1/* subst.c -- The part of the shell that does parameter, command, arithmetic, 2 and 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-2007 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#include "bashintl.h" 41 42#include "shell.h" 43#include "flags.h" 44#include "jobs.h" 45#include "execute_cmd.h" 46#include "filecntl.h" 47#include "trap.h" 48#include "pathexp.h" 49#include "mailcheck.h" 50 51#include "shmbutil.h" 52 53#include "builtins/getopt.h" 54#include "builtins/common.h" 55 56#include <tilde/tilde.h> 57#include <glob/strmatch.h> 58 59#if !defined (errno) 60extern int errno; 61#endif /* !errno */ 62 63/* The size that strings change by. */ 64#define DEFAULT_INITIAL_ARRAY_SIZE 112 65#define DEFAULT_ARRAY_SIZE 128 66 67/* Variable types. */ 68#define VT_VARIABLE 0 69#define VT_POSPARMS 1 70#define VT_ARRAYVAR 2 71#define VT_ARRAYMEMBER 3 72 73#define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */ 74 75/* Flags for quoted_strchr */ 76#define ST_BACKSL 0x01 77#define ST_CTLESC 0x02 78#define ST_SQUOTE 0x04 /* unused yet */ 79#define ST_DQUOTE 0x08 /* unused yet */ 80 81/* Flags for the string extraction functions. */ 82#define EX_NOALLOC 0x01 /* just skip; don't return substring */ 83#define EX_VARNAME 0x02 /* variable name; for string_extract () */ 84#define EX_REQMATCH 0x04 /* closing/matching delimiter required */ 85#define EX_COMMAND 0x08 /* extracting a shell script/command */ 86 87/* Flags for the `pflags' argument to param_expand() */ 88#define PF_NOCOMSUB 0x01 /* Do not perform command substitution */ 89 90/* These defs make it easier to use the editor. */ 91#define LBRACE '{' 92#define RBRACE '}' 93#define LPAREN '(' 94#define RPAREN ')' 95 96/* Evaluates to 1 if C is one of the shell's special parameters whose length 97 can be taken, but is also one of the special expansion characters. */ 98#define VALID_SPECIAL_LENGTH_PARAM(c) \ 99 ((c) == '-' || (c) == '?' || (c) == '#') 100 101/* Evaluates to 1 if C is one of the shell's special parameters for which an 102 indirect variable reference may be made. */ 103#define VALID_INDIR_PARAM(c) \ 104 ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*') 105 106/* Evaluates to 1 if C is one of the OP characters that follows the parameter 107 in ${parameter[:]OPword}. */ 108#define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP) 109 110/* Evaluates to 1 if this is one of the shell's special variables. */ 111#define SPECIAL_VAR(name, wi) \ 112 ((DIGIT (*name) && all_digits (name)) || \ 113 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \ 114 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1]))) 115 116/* An expansion function that takes a string and a quoted flag and returns 117 a WORD_LIST *. Used as the type of the third argument to 118 expand_string_if_necessary(). */ 119typedef WORD_LIST *EXPFUNC __P((char *, int)); 120 121/* Process ID of the last command executed within command substitution. */ 122pid_t last_command_subst_pid = NO_PID; 123pid_t current_command_subst_pid = NO_PID; 124 125/* Variables used to keep track of the characters in IFS. */ 126SHELL_VAR *ifs_var; 127char *ifs_value; 128unsigned char ifs_cmap[UCHAR_MAX + 1]; 129 130#if defined (HANDLE_MULTIBYTE) 131unsigned char ifs_firstc[MB_LEN_MAX]; 132size_t ifs_firstc_len; 133#else 134unsigned char ifs_firstc; 135#endif 136 137/* Extern functions and variables from different files. */ 138extern int last_command_exit_value, last_command_exit_signal; 139extern int subshell_environment; 140extern int subshell_level, parse_and_execute_level; 141extern int eof_encountered; 142extern int return_catch_flag, return_catch_value; 143extern pid_t dollar_dollar_pid; 144extern int posixly_correct; 145extern char *this_command_name; 146extern struct fd_bitmap *current_fds_to_close; 147extern int wordexp_only; 148extern int expanding_redir; 149extern int tempenv_assign_error; 150 151#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE) 152extern wchar_t *wcsdup __P((const wchar_t *)); 153#endif 154 155/* Non-zero means to allow unmatched globbed filenames to expand to 156 a null file. */ 157int allow_null_glob_expansion; 158 159/* Non-zero means to throw an error when globbing fails to match anything. */ 160int fail_glob_expansion; 161 162#if 0 163/* Variables to keep track of which words in an expanded word list (the 164 output of expand_word_list_internal) are the result of globbing 165 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c. 166 (CURRENTLY UNUSED). */ 167char *glob_argv_flags; 168static int glob_argv_flags_size; 169#endif 170 171static WORD_LIST expand_word_error, expand_word_fatal; 172static WORD_DESC expand_wdesc_error, expand_wdesc_fatal; 173static char expand_param_error, expand_param_fatal; 174static char extract_string_error, extract_string_fatal; 175 176/* Tell the expansion functions to not longjmp back to top_level on fatal 177 errors. Enabled when doing completion and prompt string expansion. */ 178static int no_longjmp_on_fatal_error = 0; 179 180/* Set by expand_word_unsplit; used to inhibit splitting and re-joining 181 $* on $IFS, primarily when doing assignment statements. */ 182static int expand_no_split_dollar_star = 0; 183 184/* Used to hold a list of variable assignments preceding a command. Global 185 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a 186 SIGCHLD trap. */ 187WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL; 188 189/* A WORD_LIST of words to be expanded by expand_word_list_internal, 190 without any leading variable assignments. */ 191static WORD_LIST *garglist = (WORD_LIST *)NULL; 192 193static char *quoted_substring __P((char *, int, int)); 194static int quoted_strlen __P((char *)); 195static char *quoted_strchr __P((char *, int, int)); 196 197static char *expand_string_if_necessary __P((char *, int, EXPFUNC *)); 198static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *)); 199static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *)); 200static WORD_LIST *expand_string_internal __P((char *, int)); 201static WORD_LIST *expand_string_leave_quoted __P((char *, int)); 202static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *)); 203 204static WORD_LIST *list_quote_escapes __P((WORD_LIST *)); 205static char *dequote_escapes __P((char *)); 206static char *make_quoted_char __P((int)); 207static WORD_LIST *quote_list __P((WORD_LIST *)); 208static char *remove_quoted_escapes __P((char *)); 209static char *remove_quoted_nulls __P((char *)); 210 211static int unquoted_substring __P((char *, char *)); 212static int unquoted_member __P((int, char *)); 213 214#if defined (ARRAY_VARS) 215static SHELL_VAR *do_compound_assignment __P((char *, char *, int)); 216#endif 217static int do_assignment_internal __P((const WORD_DESC *, int)); 218 219static char *string_extract_verbatim __P((char *, size_t, int *, char *)); 220static char *string_extract __P((char *, int *, char *, int)); 221static char *string_extract_double_quoted __P((char *, int *, int)); 222static inline char *string_extract_single_quoted __P((char *, int *)); 223static inline int skip_single_quoted __P((const char *, size_t, int)); 224static int skip_double_quoted __P((char *, size_t, int)); 225static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int)); 226static char *extract_dollar_brace_string __P((char *, int *, int, int)); 227 228static char *pos_params __P((char *, int, int, int)); 229 230static unsigned char *mb_getcharlens __P((char *, int)); 231 232static char *remove_upattern __P((char *, char *, int)); 233#if defined (HANDLE_MULTIBYTE) 234static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int)); 235#endif 236static char *remove_pattern __P((char *, char *, int)); 237 238static int match_pattern_char __P((char *, char *)); 239static int match_upattern __P((char *, char *, int, char **, char **)); 240#if defined (HANDLE_MULTIBYTE) 241static int match_pattern_wchar __P((wchar_t *, wchar_t *)); 242static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **)); 243#endif 244static int match_pattern __P((char *, char *, int, char **, char **)); 245static int getpatspec __P((int, char *)); 246static char *getpattern __P((char *, int, int)); 247static char *variable_remove_pattern __P((char *, char *, int, int)); 248static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int)); 249static char *parameter_list_remove_pattern __P((int, char *, int, int)); 250#ifdef ARRAY_VARS 251static char *array_remove_pattern __P((ARRAY *, char *, int, char *, int)); 252#endif 253static char *parameter_brace_remove_pattern __P((char *, char *, char *, int, int)); 254 255static char *process_substitute __P((char *, int)); 256 257static char *read_comsub __P((int, int)); 258 259#ifdef ARRAY_VARS 260static arrayind_t array_length_reference __P((char *)); 261#endif 262 263static int valid_brace_expansion_word __P((char *, int)); 264static int chk_atstar __P((char *, int, int *, int *)); 265static int chk_arithsub __P((const char *, int)); 266 267static WORD_DESC *parameter_brace_expand_word __P((char *, int, int)); 268static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *)); 269static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *)); 270static void parameter_brace_expand_error __P((char *, char *)); 271 272static int valid_length_expression __P((char *)); 273static intmax_t parameter_brace_expand_length __P((char *)); 274 275static char *skiparith __P((char *, int)); 276static int verify_substring_values __P((char *, char *, int, intmax_t *, intmax_t *)); 277static int get_var_and_type __P((char *, char *, int, SHELL_VAR **, char **)); 278static char *mb_substring __P((char *, int, int)); 279static char *parameter_brace_substring __P((char *, char *, char *, int)); 280 281static char *pos_params_pat_subst __P((char *, char *, char *, int)); 282 283static char *parameter_brace_patsub __P((char *, char *, char *, int)); 284 285static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int *, int *)); 286static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int)); 287 288static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *)); 289 290static WORD_LIST *word_list_split __P((WORD_LIST *)); 291 292static void exp_jump_to_top_level __P((int)); 293 294static WORD_LIST *separate_out_assignments __P((WORD_LIST *)); 295static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int)); 296#ifdef BRACE_EXPANSION 297static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int)); 298#endif 299static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int)); 300static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int)); 301 302/* **************************************************************** */ 303/* */ 304/* Utility Functions */ 305/* */ 306/* **************************************************************** */ 307 308#ifdef INCLUDE_UNUSED 309static char * 310quoted_substring (string, start, end) 311 char *string; 312 int start, end; 313{ 314 register int len, l; 315 register char *result, *s, *r; 316 317 len = end - start; 318 319 /* Move to string[start], skipping quoted characters. */ 320 for (s = string, l = 0; *s && l < start; ) 321 { 322 if (*s == CTLESC) 323 { 324 s++; 325 continue; 326 } 327 l++; 328 if (*s == 0) 329 break; 330 } 331 332 r = result = (char *)xmalloc (2*len + 1); /* save room for quotes */ 333 334 /* Copy LEN characters, including quote characters. */ 335 s = string + l; 336 for (l = 0; l < len; s++) 337 { 338 if (*s == CTLESC) 339 *r++ = *s++; 340 *r++ = *s; 341 l++; 342 if (*s == 0) 343 break; 344 } 345 *r = '\0'; 346 return result; 347} 348#endif 349 350#ifdef INCLUDE_UNUSED 351/* Return the length of S, skipping over quoted characters */ 352static int 353quoted_strlen (s) 354 char *s; 355{ 356 register char *p; 357 int i; 358 359 i = 0; 360 for (p = s; *p; p++) 361 { 362 if (*p == CTLESC) 363 { 364 p++; 365 if (*p == 0) 366 return (i + 1); 367 } 368 i++; 369 } 370 371 return i; 372} 373#endif 374 375/* Find the first occurrence of character C in string S, obeying shell 376 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped 377 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters 378 escaped with CTLESC are skipped. */ 379static char * 380quoted_strchr (s, c, flags) 381 char *s; 382 int c, flags; 383{ 384 register char *p; 385 386 for (p = s; *p; p++) 387 { 388 if (((flags & ST_BACKSL) && *p == '\\') 389 || ((flags & ST_CTLESC) && *p == CTLESC)) 390 { 391 p++; 392 if (*p == '\0') 393 return ((char *)NULL); 394 continue; 395 } 396 else if (*p == c) 397 return p; 398 } 399 return ((char *)NULL); 400} 401 402/* Return 1 if CHARACTER appears in an unquoted portion of 403 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */ 404static int 405unquoted_member (character, string) 406 int character; 407 char *string; 408{ 409 size_t slen; 410 int sindex, c; 411 DECLARE_MBSTATE; 412 413 slen = strlen (string); 414 sindex = 0; 415 while (c = string[sindex]) 416 { 417 if (c == character) 418 return (1); 419 420 switch (c) 421 { 422 default: 423 ADVANCE_CHAR (string, slen, sindex); 424 break; 425 426 case '\\': 427 sindex++; 428 if (string[sindex]) 429 ADVANCE_CHAR (string, slen, sindex); 430 break; 431 432 case '\'': 433 sindex = skip_single_quoted (string, slen, ++sindex); 434 break; 435 436 case '"': 437 sindex = skip_double_quoted (string, slen, ++sindex); 438 break; 439 } 440 } 441 return (0); 442} 443 444/* Return 1 if SUBSTR appears in an unquoted portion of STRING. */ 445static int 446unquoted_substring (substr, string) 447 char *substr, *string; 448{ 449 size_t slen; 450 int sindex, c, sublen; 451 DECLARE_MBSTATE; 452 453 if (substr == 0 || *substr == '\0') 454 return (0); 455 456 slen = strlen (string); 457 sublen = strlen (substr); 458 for (sindex = 0; c = string[sindex]; ) 459 { 460 if (STREQN (string + sindex, substr, sublen)) 461 return (1); 462 463 switch (c) 464 { 465 case '\\': 466 sindex++; 467 468 if (string[sindex]) 469 ADVANCE_CHAR (string, slen, sindex); 470 break; 471 472 case '\'': 473 sindex = skip_single_quoted (string, slen, ++sindex); 474 break; 475 476 case '"': 477 sindex = skip_double_quoted (string, slen, ++sindex); 478 break; 479 480 default: 481 ADVANCE_CHAR (string, slen, sindex); 482 break; 483 } 484 } 485 return (0); 486} 487 488/* Most of the substitutions must be done in parallel. In order 489 to avoid using tons of unclear goto's, I have some functions 490 for manipulating malloc'ed strings. They all take INDX, a 491 pointer to an integer which is the offset into the string 492 where manipulation is taking place. They also take SIZE, a 493 pointer to an integer which is the current length of the 494 character array for this string. */ 495 496/* Append SOURCE to TARGET at INDEX. SIZE is the current amount 497 of space allocated to TARGET. SOURCE can be NULL, in which 498 case nothing happens. Gets rid of SOURCE by freeing it. 499 Returns TARGET in case the location has changed. */ 500INLINE char * 501sub_append_string (source, target, indx, size) 502 char *source, *target; 503 int *indx, *size; 504{ 505 if (source) 506 { 507 int srclen, n; 508 509 srclen = STRLEN (source); 510 if (srclen >= (int)(*size - *indx)) 511 { 512 n = srclen + *indx; 513 n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE); 514 target = (char *)xrealloc (target, (*size = n)); 515 } 516 517 FASTCOPY (source, target + *indx, srclen); 518 *indx += srclen; 519 target[*indx] = '\0'; 520 521 free (source); 522 } 523 return (target); 524} 525 526#if 0 527/* UNUSED */ 528/* Append the textual representation of NUMBER to TARGET. 529 INDX and SIZE are as in SUB_APPEND_STRING. */ 530char * 531sub_append_number (number, target, indx, size) 532 intmax_t number; 533 int *indx, *size; 534 char *target; 535{ 536 char *temp; 537 538 temp = itos (number); 539 return (sub_append_string (temp, target, indx, size)); 540} 541#endif 542 543/* Extract a substring from STRING, starting at SINDEX and ending with 544 one of the characters in CHARLIST. Don't make the ending character 545 part of the string. Leave SINDEX pointing at the ending character. 546 Understand about backslashes in the string. If (flags & EX_VARNAME) 547 is non-zero, and array variables have been compiled into the shell, 548 everything between a `[' and a corresponding `]' is skipped over. 549 If (flags & EX_NOALLOC) is non-zero, don't return the substring, just 550 update SINDEX. If (flags & EX_REQMATCH) is non-zero, the string must 551 contain a closing character from CHARLIST. */ 552static char * 553string_extract (string, sindex, charlist, flags) 554 char *string; 555 int *sindex; 556 char *charlist; 557 int flags; 558{ 559 register int c, i; 560 int found; 561 size_t slen; 562 char *temp; 563 DECLARE_MBSTATE; 564 565 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0; 566 i = *sindex; 567 found = 0; 568 while (c = string[i]) 569 { 570 if (c == '\\') 571 { 572 if (string[i + 1]) 573 i++; 574 else 575 break; 576 } 577#if defined (ARRAY_VARS) 578 else if ((flags & EX_VARNAME) && c == '[') 579 { 580 int ni; 581 /* If this is an array subscript, skip over it and continue. */ 582 ni = skipsubscript (string, i); 583 if (string[ni] == ']') 584 i = ni; 585 } 586#endif 587 else if (MEMBER (c, charlist)) 588 { 589 found = 1; 590 break; 591 } 592 593 ADVANCE_CHAR (string, slen, i); 594 } 595 596 /* If we had to have a matching delimiter and didn't find one, return an 597 error and let the caller deal with it. */ 598 if ((flags & EX_REQMATCH) && found == 0) 599 { 600 *sindex = i; 601 return (&extract_string_error); 602 } 603 604 temp = (flags & EX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i); 605 *sindex = i; 606 607 return (temp); 608} 609 610/* Extract the contents of STRING as if it is enclosed in double quotes. 611 SINDEX, when passed in, is the offset of the character immediately 612 following the opening double quote; on exit, SINDEX is left pointing after 613 the closing double quote. If STRIPDQ is non-zero, unquoted double 614 quotes are stripped and the string is terminated by a null byte. 615 Backslashes between the embedded double quotes are processed. If STRIPDQ 616 is zero, an unquoted `"' terminates the string. */ 617static char * 618string_extract_double_quoted (string, sindex, stripdq) 619 char *string; 620 int *sindex, stripdq; 621{ 622 size_t slen; 623 char *send; 624 int j, i, t; 625 unsigned char c; 626 char *temp, *ret; /* The new string we return. */ 627 int pass_next, backquote, si; /* State variables for the machine. */ 628 int dquote; 629 DECLARE_MBSTATE; 630 631 slen = strlen (string + *sindex) + *sindex; 632 send = string + slen; 633 634 pass_next = backquote = dquote = 0; 635 temp = (char *)xmalloc (1 + slen - *sindex); 636 637 j = 0; 638 i = *sindex; 639 while (c = string[i]) 640 { 641 /* Process a character that was quoted by a backslash. */ 642 if (pass_next) 643 { 644 /* Posix.2 sez: 645 646 ``The backslash shall retain its special meaning as an escape 647 character only when followed by one of the characters: 648 $ ` " \ <newline>''. 649 650 If STRIPDQ is zero, we handle the double quotes here and let 651 expand_word_internal handle the rest. If STRIPDQ is non-zero, 652 we have already been through one round of backslash stripping, 653 and want to strip these backslashes only if DQUOTE is non-zero, 654 indicating that we are inside an embedded double-quoted string. */ 655 656 /* If we are in an embedded quoted string, then don't strip 657 backslashes before characters for which the backslash 658 retains its special meaning, but remove backslashes in 659 front of other characters. If we are not in an 660 embedded quoted string, don't strip backslashes at all. 661 This mess is necessary because the string was already 662 surrounded by double quotes (and sh has some really weird 663 quoting rules). 664 The returned string will be run through expansion as if 665 it were double-quoted. */ 666 if ((stripdq == 0 && c != '"') || 667 (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0))) 668 temp[j++] = '\\'; 669 pass_next = 0; 670 671add_one_character: 672 COPY_CHAR_I (temp, j, string, send, i); 673 continue; 674 } 675 676 /* A backslash protects the next character. The code just above 677 handles preserving the backslash in front of any character but 678 a double quote. */ 679 if (c == '\\') 680 { 681 pass_next++; 682 i++; 683 continue; 684 } 685 686 /* Inside backquotes, ``the portion of the quoted string from the 687 initial backquote and the characters up to the next backquote 688 that is not preceded by a backslash, having escape characters 689 removed, defines that command''. */ 690 if (backquote) 691 { 692 if (c == '`') 693 backquote = 0; 694 temp[j++] = c; 695 i++; 696 continue; 697 } 698 699 if (c == '`') 700 { 701 temp[j++] = c; 702 backquote++; 703 i++; 704 continue; 705 } 706 707 /* Pass everything between `$(' and the matching `)' or a quoted 708 ${ ... } pair through according to the Posix.2 specification. */ 709 if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE))) 710 { 711 int free_ret = 1; 712 713 si = i + 2; 714 if (string[i + 1] == LPAREN) 715 ret = extract_delimited_string (string, &si, "$(", "(", ")", EX_COMMAND); /*)*/ 716 else 717 ret = extract_dollar_brace_string (string, &si, 1, 0); 718 719 temp[j++] = '$'; 720 temp[j++] = string[i + 1]; 721 722 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error 723 is set. */ 724 if (ret == 0 && no_longjmp_on_fatal_error) 725 { 726 free_ret = 0; 727 ret = string + i + 2; 728 } 729 730 for (t = 0; ret[t]; t++, j++) 731 temp[j] = ret[t]; 732 temp[j] = string[si]; 733 734 if (string[si]) 735 { 736 j++; 737 i = si + 1; 738 } 739 else 740 i = si; 741 742 if (free_ret) 743 free (ret); 744 continue; 745 } 746 747 /* Add any character but a double quote to the quoted string we're 748 accumulating. */ 749 if (c != '"') 750 goto add_one_character; 751 752 /* c == '"' */ 753 if (stripdq) 754 { 755 dquote ^= 1; 756 i++; 757 continue; 758 } 759 760 break; 761 } 762 temp[j] = '\0'; 763 764 /* Point to after the closing quote. */ 765 if (c) 766 i++; 767 *sindex = i; 768 769 return (temp); 770} 771 772/* This should really be another option to string_extract_double_quoted. */ 773static int 774skip_double_quoted (string, slen, sind) 775 char *string; 776 size_t slen; 777 int sind; 778{ 779 int c, i; 780 char *ret; 781 int pass_next, backquote, si; 782 DECLARE_MBSTATE; 783 784 pass_next = backquote = 0; 785 i = sind; 786 while (c = string[i]) 787 { 788 if (pass_next) 789 { 790 pass_next = 0; 791 ADVANCE_CHAR (string, slen, i); 792 continue; 793 } 794 else if (c == '\\') 795 { 796 pass_next++; 797 i++; 798 continue; 799 } 800 else if (backquote) 801 { 802 if (c == '`') 803 backquote = 0; 804 ADVANCE_CHAR (string, slen, i); 805 continue; 806 } 807 else if (c == '`') 808 { 809 backquote++; 810 i++; 811 continue; 812 } 813 else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE))) 814 { 815 si = i + 2; 816 if (string[i + 1] == LPAREN) 817 ret = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC|EX_COMMAND); /* ) */ 818 else 819 ret = extract_dollar_brace_string (string, &si, 0, EX_NOALLOC); 820 821 i = si + 1; 822 continue; 823 } 824 else if (c != '"') 825 { 826 ADVANCE_CHAR (string, slen, i); 827 continue; 828 } 829 else 830 break; 831 } 832 833 if (c) 834 i++; 835 836 return (i); 837} 838 839/* Extract the contents of STRING as if it is enclosed in single quotes. 840 SINDEX, when passed in, is the offset of the character immediately 841 following the opening single quote; on exit, SINDEX is left pointing after 842 the closing single quote. */ 843static inline char * 844string_extract_single_quoted (string, sindex) 845 char *string; 846 int *sindex; 847{ 848 register int i; 849 size_t slen; 850 char *t; 851 DECLARE_MBSTATE; 852 853 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */ 854 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0; 855 i = *sindex; 856 while (string[i] && string[i] != '\'') 857 ADVANCE_CHAR (string, slen, i); 858 859 t = substring (string, *sindex, i); 860 861 if (string[i]) 862 i++; 863 *sindex = i; 864 865 return (t); 866} 867 868static inline int 869skip_single_quoted (string, slen, sind) 870 const char *string; 871 size_t slen; 872 int sind; 873{ 874 register int c; 875 DECLARE_MBSTATE; 876 877 c = sind; 878 while (string[c] && string[c] != '\'') 879 ADVANCE_CHAR (string, slen, c); 880 881 if (string[c]) 882 c++; 883 return c; 884} 885 886/* Just like string_extract, but doesn't hack backslashes or any of 887 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */ 888static char * 889string_extract_verbatim (string, slen, sindex, charlist) 890 char *string; 891 size_t slen; 892 int *sindex; 893 char *charlist; 894{ 895 register int i = *sindex; 896#if defined (HANDLE_MULTIBYTE) 897 size_t clen; 898 wchar_t *wcharlist; 899#endif 900 int c; 901 char *temp; 902 DECLARE_MBSTATE; 903 904 if (charlist[0] == '\'' && charlist[1] == '\0') 905 { 906 temp = string_extract_single_quoted (string, sindex); 907 --*sindex; /* leave *sindex at separator character */ 908 return temp; 909 } 910 911 i = *sindex; 912#if 0 913 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need 914 this only if MB_CUR_MAX > 1. */ 915 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1; 916#endif 917#if defined (HANDLE_MULTIBYTE) 918 clen = strlen (charlist); 919 wcharlist = 0; 920#endif 921 while (c = string[i]) 922 { 923#if defined (HANDLE_MULTIBYTE) 924 size_t mblength; 925#endif 926 if (c == CTLESC) 927 { 928 i += 2; 929 continue; 930 } 931 932#if defined (HANDLE_MULTIBYTE) 933 mblength = MBLEN (string + i, slen - i); 934 if (mblength > 1) 935 { 936 wchar_t wc; 937 mblength = mbtowc (&wc, string + i, slen - i); 938 if (MB_INVALIDCH (mblength)) 939 { 940 if (MEMBER (c, charlist)) 941 break; 942 } 943 else 944 { 945 if (wcharlist == 0) 946 { 947 size_t len; 948 len = mbstowcs (wcharlist, charlist, 0); 949 if (len == -1) 950 len = 0; 951 wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1)); 952 mbstowcs (wcharlist, charlist, len + 1); 953 } 954 955 if (wcschr (wcharlist, wc)) 956 break; 957 } 958 } 959 else 960#endif 961 if (MEMBER (c, charlist)) 962 break; 963 964 ADVANCE_CHAR (string, slen, i); 965 } 966 967#if defined (HANDLE_MULTIBYTE) 968 FREE (wcharlist); 969#endif 970 971 temp = substring (string, *sindex, i); 972 *sindex = i; 973 974 return (temp); 975} 976 977/* Extract the $( construct in STRING, and return a new string. 978 Start extracting at (SINDEX) as if we had just seen "$(". 979 Make (SINDEX) get the position of the matching ")". ) */ 980char * 981extract_command_subst (string, sindex) 982 char *string; 983 int *sindex; 984{ 985 return (extract_delimited_string (string, sindex, "$(", "(", ")", EX_COMMAND)); /*)*/ 986} 987 988/* Extract the $[ construct in STRING, and return a new string. (]) 989 Start extracting at (SINDEX) as if we had just seen "$[". 990 Make (SINDEX) get the position of the matching "]". */ 991char * 992extract_arithmetic_subst (string, sindex) 993 char *string; 994 int *sindex; 995{ 996 return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/ 997} 998 999#if defined (PROCESS_SUBSTITUTION) 1000/* Extract the <( or >( construct in STRING, and return a new string. 1001 Start extracting at (SINDEX) as if we had just seen "<(". 1002 Make (SINDEX) get the position of the matching ")". */ /*))*/ 1003char * 1004extract_process_subst (string, starter, sindex) 1005 char *string; 1006 char *starter; 1007 int *sindex; 1008{ 1009 return (extract_delimited_string (string, sindex, starter, "(", ")", 0)); 1010} 1011#endif /* PROCESS_SUBSTITUTION */ 1012 1013#if defined (ARRAY_VARS) 1014/* This can be fooled by unquoted right parens in the passed string. If 1015 each caller verifies that the last character in STRING is a right paren, 1016 we don't even need to call extract_delimited_string. */ 1017char * 1018extract_array_assignment_list (string, sindex) 1019 char *string; 1020 int *sindex; 1021{ 1022 int slen; 1023 char *ret; 1024 1025 slen = strlen (string); /* ( */ 1026 if (string[slen - 1] == ')') 1027 { 1028 ret = substring (string, *sindex, slen - 1); 1029 *sindex = slen - 1; 1030 return ret; 1031 } 1032 return 0; 1033} 1034#endif 1035 1036/* Extract and create a new string from the contents of STRING, a 1037 character string delimited with OPENER and CLOSER. SINDEX is 1038 the address of an int describing the current offset in STRING; 1039 it should point to just after the first OPENER found. On exit, 1040 SINDEX gets the position of the last character of the matching CLOSER. 1041 If OPENER is more than a single character, ALT_OPENER, if non-null, 1042 contains a character string that can also match CLOSER and thus 1043 needs to be skipped. */ 1044static char * 1045extract_delimited_string (string, sindex, opener, alt_opener, closer, flags) 1046 char *string; 1047 int *sindex; 1048 char *opener, *alt_opener, *closer; 1049 int flags; 1050{ 1051 int i, c, si; 1052 size_t slen; 1053 char *t, *result; 1054 int pass_character, nesting_level, in_comment; 1055 int len_closer, len_opener, len_alt_opener; 1056 DECLARE_MBSTATE; 1057 1058 slen = strlen (string + *sindex) + *sindex; 1059 len_opener = STRLEN (opener); 1060 len_alt_opener = STRLEN (alt_opener); 1061 len_closer = STRLEN (closer); 1062 1063 pass_character = in_comment = 0; 1064 1065 nesting_level = 1; 1066 i = *sindex; 1067 1068 while (nesting_level) 1069 { 1070 c = string[i]; 1071 1072 if (c == 0) 1073 break; 1074 1075 if (in_comment) 1076 { 1077 if (c == '\n') 1078 in_comment = 0; 1079 ADVANCE_CHAR (string, slen, i); 1080 continue; 1081 } 1082 1083 if (pass_character) /* previous char was backslash */ 1084 { 1085 pass_character = 0; 1086 ADVANCE_CHAR (string, slen, i); 1087 continue; 1088 } 1089 1090 /* Not exactly right yet; should handle shell metacharacters and 1091 multibyte characters, too. */ 1092 if ((flags & EX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || whitespace (string[i - 1]))) 1093 { 1094 in_comment = 1; 1095 ADVANCE_CHAR (string, slen, i); 1096 continue; 1097 } 1098 1099 if (c == CTLESC || c == '\\') 1100 { 1101 pass_character++; 1102 i++; 1103 continue; 1104 } 1105 1106 /* Process a nested OPENER. */ 1107 if (STREQN (string + i, opener, len_opener)) 1108 { 1109 si = i + len_opener; 1110 t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|EX_NOALLOC); 1111 i = si + 1; 1112 continue; 1113 } 1114 1115 /* Process a nested ALT_OPENER */ 1116 if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener)) 1117 { 1118 si = i + len_alt_opener; 1119 t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|EX_NOALLOC); 1120 i = si + 1; 1121 continue; 1122 } 1123 1124 /* If the current substring terminates the delimited string, decrement 1125 the nesting level. */ 1126 if (STREQN (string + i, closer, len_closer)) 1127 { 1128 i += len_closer - 1; /* move to last byte of the closer */ 1129 nesting_level--; 1130 if (nesting_level == 0) 1131 break; 1132 } 1133 1134 /* Pass old-style command substitution through verbatim. */ 1135 if (c == '`') 1136 { 1137 si = i + 1; 1138 t = string_extract (string, &si, "`", flags|EX_NOALLOC); 1139 i = si + 1; 1140 continue; 1141 } 1142 1143 /* Pass single-quoted and double-quoted strings through verbatim. */ 1144 if (c == '\'' || c == '"') 1145 { 1146 si = i + 1; 1147 i = (c == '\'') ? skip_single_quoted (string, slen, si) 1148 : skip_double_quoted (string, slen, si); 1149 continue; 1150 } 1151 1152 /* move past this character, which was not special. */ 1153 ADVANCE_CHAR (string, slen, i); 1154 } 1155 1156 if (c == 0 && nesting_level) 1157 { 1158 if (no_longjmp_on_fatal_error == 0) 1159 { 1160 report_error (_("bad substitution: no closing `%s' in %s"), closer, string); 1161 last_command_exit_value = EXECUTION_FAILURE; 1162 exp_jump_to_top_level (DISCARD); 1163 } 1164 else 1165 { 1166 *sindex = i; 1167 return (char *)NULL; 1168 } 1169 } 1170 1171 si = i - *sindex - len_closer + 1; 1172 if (flags & EX_NOALLOC) 1173 result = (char *)NULL; 1174 else 1175 { 1176 result = (char *)xmalloc (1 + si); 1177 strncpy (result, string + *sindex, si); 1178 result[si] = '\0'; 1179 } 1180 *sindex = i; 1181 1182 return (result); 1183} 1184 1185/* Extract a parameter expansion expression within ${ and } from STRING. 1186 Obey the Posix.2 rules for finding the ending `}': count braces while 1187 skipping over enclosed quoted strings and command substitutions. 1188 SINDEX is the address of an int describing the current offset in STRING; 1189 it should point to just after the first `{' found. On exit, SINDEX 1190 gets the position of the matching `}'. QUOTED is non-zero if this 1191 occurs inside double quotes. */ 1192/* XXX -- this is very similar to extract_delimited_string -- XXX */ 1193static char * 1194extract_dollar_brace_string (string, sindex, quoted, flags) 1195 char *string; 1196 int *sindex, quoted, flags; 1197{ 1198 register int i, c; 1199 size_t slen; 1200 int pass_character, nesting_level, si; 1201 char *result, *t; 1202 DECLARE_MBSTATE; 1203 1204 pass_character = 0; 1205 nesting_level = 1; 1206 slen = strlen (string + *sindex) + *sindex; 1207 1208 i = *sindex; 1209 while (c = string[i]) 1210 { 1211 if (pass_character) 1212 { 1213 pass_character = 0; 1214 ADVANCE_CHAR (string, slen, i); 1215 continue; 1216 } 1217 1218 /* CTLESCs and backslashes quote the next character. */ 1219 if (c == CTLESC || c == '\\') 1220 { 1221 pass_character++; 1222 i++; 1223 continue; 1224 } 1225 1226 if (string[i] == '$' && string[i+1] == LBRACE) 1227 { 1228 nesting_level++; 1229 i += 2; 1230 continue; 1231 } 1232 1233 if (c == RBRACE) 1234 { 1235 nesting_level--; 1236 if (nesting_level == 0) 1237 break; 1238 i++; 1239 continue; 1240 } 1241 1242 /* Pass the contents of old-style command substitutions through 1243 verbatim. */ 1244 if (c == '`') 1245 { 1246 si = i + 1; 1247 t = string_extract (string, &si, "`", flags|EX_NOALLOC); 1248 i = si + 1; 1249 continue; 1250 } 1251 1252 /* Pass the contents of new-style command substitutions and 1253 arithmetic substitutions through verbatim. */ 1254 if (string[i] == '$' && string[i+1] == LPAREN) 1255 { 1256 si = i + 2; 1257 t = extract_delimited_string (string, &si, "$(", "(", ")", flags|EX_NOALLOC|EX_COMMAND); /*)*/ 1258 i = si + 1; 1259 continue; 1260 } 1261 1262 /* Pass the contents of single-quoted and double-quoted strings 1263 through verbatim. */ 1264 if (c == '\'' || c == '"') 1265 { 1266 si = i + 1; 1267 i = (c == '\'') ? skip_single_quoted (string, slen, si) 1268 : skip_double_quoted (string, slen, si); 1269 /* skip_XXX_quoted leaves index one past close quote */ 1270 continue; 1271 } 1272 1273 /* move past this character, which was not special. */ 1274 ADVANCE_CHAR (string, slen, i); 1275 } 1276 1277 if (c == 0 && nesting_level) 1278 { 1279 if (no_longjmp_on_fatal_error == 0) 1280 { /* { */ 1281 report_error (_("bad substitution: no closing `%s' in %s"), "}", string); 1282 last_command_exit_value = EXECUTION_FAILURE; 1283 exp_jump_to_top_level (DISCARD); 1284 } 1285 else 1286 { 1287 *sindex = i; 1288 return ((char *)NULL); 1289 } 1290 } 1291 1292 result = (flags & EX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i); 1293 *sindex = i; 1294 1295 return (result); 1296} 1297 1298/* Remove backslashes which are quoting backquotes from STRING. Modifies 1299 STRING, and returns a pointer to it. */ 1300char * 1301de_backslash (string) 1302 char *string; 1303{ 1304 register size_t slen; 1305 register int i, j, prev_i; 1306 DECLARE_MBSTATE; 1307 1308 slen = strlen (string); 1309 i = j = 0; 1310 1311 /* Loop copying string[i] to string[j], i >= j. */ 1312 while (i < slen) 1313 { 1314 if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' || 1315 string[i + 1] == '$')) 1316 i++; 1317 prev_i = i; 1318 ADVANCE_CHAR (string, slen, i); 1319 if (j < prev_i) 1320 do string[j++] = string[prev_i++]; while (prev_i < i); 1321 else 1322 j = i; 1323 } 1324 string[j] = '\0'; 1325 1326 return (string); 1327} 1328 1329#if 0 1330/*UNUSED*/ 1331/* Replace instances of \! in a string with !. */ 1332void 1333unquote_bang (string) 1334 char *string; 1335{ 1336 register int i, j; 1337 register char *temp; 1338 1339 temp = (char *)xmalloc (1 + strlen (string)); 1340 1341 for (i = 0, j = 0; (temp[j] = string[i]); i++, j++) 1342 { 1343 if (string[i] == '\\' && string[i + 1] == '!') 1344 { 1345 temp[j] = '!'; 1346 i++; 1347 } 1348 } 1349 strcpy (string, temp); 1350 free (temp); 1351} 1352#endif 1353 1354#if defined (READLINE) 1355/* Return 1 if the portion of STRING ending at EINDEX is quoted (there is 1356 an unclosed quoted string), or if the character at EINDEX is quoted 1357 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various 1358 single and double-quoted string parsing functions should not return an 1359 error if there are unclosed quotes or braces. The characters that this 1360 recognizes need to be the same as the contents of 1361 rl_completer_quote_characters. */ 1362 1363#define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0) 1364 1365int 1366char_is_quoted (string, eindex) 1367 char *string; 1368 int eindex; 1369{ 1370 int i, pass_next, c; 1371 size_t slen; 1372 DECLARE_MBSTATE; 1373 1374 slen = strlen (string); 1375 no_longjmp_on_fatal_error = 1; 1376 i = pass_next = 0; 1377 while (i <= eindex) 1378 { 1379 c = string[i]; 1380 1381 if (pass_next) 1382 { 1383 pass_next = 0; 1384 if (i >= eindex) /* XXX was if (i >= eindex - 1) */ 1385 CQ_RETURN(1); 1386 ADVANCE_CHAR (string, slen, i); 1387 continue; 1388 } 1389 else if (c == '\\') 1390 { 1391 pass_next = 1; 1392 i++; 1393 continue; 1394 } 1395 else if (c == '\'' || c == '"') 1396 { 1397 i = (c == '\'') ? skip_single_quoted (string, slen, ++i) 1398 : skip_double_quoted (string, slen, ++i); 1399 if (i > eindex) 1400 CQ_RETURN(1); 1401 /* no increment, the skip_xxx functions go one past end */ 1402 } 1403 else 1404 ADVANCE_CHAR (string, slen, i); 1405 } 1406 1407 CQ_RETURN(0); 1408} 1409 1410int 1411unclosed_pair (string, eindex, openstr) 1412 char *string; 1413 int eindex; 1414 char *openstr; 1415{ 1416 int i, pass_next, openc, olen; 1417 size_t slen; 1418 DECLARE_MBSTATE; 1419 1420 slen = strlen (string); 1421 olen = strlen (openstr); 1422 i = pass_next = openc = 0; 1423 while (i <= eindex) 1424 { 1425 if (pass_next) 1426 { 1427 pass_next = 0; 1428 if (i >= eindex) /* XXX was if (i >= eindex - 1) */ 1429 return 0; 1430 ADVANCE_CHAR (string, slen, i); 1431 continue; 1432 } 1433 else if (string[i] == '\\') 1434 { 1435 pass_next = 1; 1436 i++; 1437 continue; 1438 } 1439 else if (STREQN (string + i, openstr, olen)) 1440 { 1441 openc = 1 - openc; 1442 i += olen; 1443 } 1444 else if (string[i] == '\'' || string[i] == '"') 1445 { 1446 i = (string[i] == '\'') ? skip_single_quoted (string, slen, i) 1447 : skip_double_quoted (string, slen, i); 1448 if (i > eindex) 1449 return 0; 1450 } 1451 else 1452 ADVANCE_CHAR (string, slen, i); 1453 } 1454 return (openc); 1455} 1456 1457/* Skip characters in STRING until we find a character in DELIMS, and return 1458 the index of that character. START is the index into string at which we 1459 begin. This is similar in spirit to strpbrk, but it returns an index into 1460 STRING and takes a starting index. This little piece of code knows quite 1461 a lot of shell syntax. It's very similar to skip_double_quoted and other 1462 functions of that ilk. */ 1463int 1464skip_to_delim (string, start, delims) 1465 char *string; 1466 int start; 1467 char *delims; 1468{ 1469 int i, pass_next, backq, si, c; 1470 size_t slen; 1471 char *temp; 1472 DECLARE_MBSTATE; 1473 1474 slen = strlen (string + start) + start; 1475 no_longjmp_on_fatal_error = 1; 1476 i = start; 1477 pass_next = backq = 0; 1478 while (c = string[i]) 1479 { 1480 if (pass_next) 1481 { 1482 pass_next = 0; 1483 if (c == 0) 1484 CQ_RETURN(i); 1485 ADVANCE_CHAR (string, slen, i); 1486 continue; 1487 } 1488 else if (c == '\\') 1489 { 1490 pass_next = 1; 1491 i++; 1492 continue; 1493 } 1494 else if (backq) 1495 { 1496 if (c == '`') 1497 backq = 0; 1498 ADVANCE_CHAR (string, slen, i); 1499 continue; 1500 } 1501 else if (c == '`') 1502 { 1503 backq = 1; 1504 i++; 1505 continue; 1506 } 1507 else if (c == '\'' || c == '"') 1508 { 1509 i = (c == '\'') ? skip_single_quoted (string, slen, ++i) 1510 : skip_double_quoted (string, slen, ++i); 1511 /* no increment, the skip functions increment past the closing quote. */ 1512 } 1513 else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE)) 1514 { 1515 si = i + 2; 1516 if (string[si] == '\0') 1517 CQ_RETURN(si); 1518 1519 if (string[i+1] == LPAREN) 1520 temp = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC|EX_COMMAND); /* ) */ 1521 else 1522 temp = extract_dollar_brace_string (string, &si, 0, EX_NOALLOC); 1523 i = si; 1524 if (string[i] == '\0') /* don't increment i past EOS in loop */ 1525 break; 1526 i++; 1527 continue; 1528 } 1529 else if (member (c, delims)) 1530 break; 1531 else 1532 ADVANCE_CHAR (string, slen, i); 1533 } 1534 1535 CQ_RETURN(i); 1536} 1537 1538/* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the 1539 individual words. If DELIMS is NULL, the current value of $IFS is used 1540 to split the string, and the function follows the shell field splitting 1541 rules. SENTINEL is an index to look for. NWP, if non-NULL, 1542 gets the number of words in the returned list. CWP, if non-NULL, gets 1543 the index of the word containing SENTINEL. Non-whitespace chars in 1544 DELIMS delimit separate fields. */ 1545WORD_LIST * 1546split_at_delims (string, slen, delims, sentinel, nwp, cwp) 1547 char *string; 1548 int slen; 1549 char *delims; 1550 int sentinel; 1551 int *nwp, *cwp; 1552{ 1553 int ts, te, i, nw, cw, ifs_split; 1554 char *token, *d, *d2; 1555 WORD_LIST *ret, *tl; 1556 1557 if (string == 0 || *string == '\0') 1558 { 1559 if (nwp) 1560 *nwp = 0; 1561 if (cwp) 1562 *cwp = 0; 1563 return ((WORD_LIST *)NULL); 1564 } 1565 1566 d = (delims == 0) ? ifs_value : delims; 1567 ifs_split = delims == 0; 1568 1569 /* Make d2 the non-whitespace characters in delims */ 1570 d2 = 0; 1571 if (delims) 1572 { 1573 size_t slength; 1574#if defined (HANDLE_MULTIBYTE) 1575 size_t mblength = 1; 1576#endif 1577 DECLARE_MBSTATE; 1578 1579 slength = strlen (delims); 1580 d2 = (char *)xmalloc (slength + 1); 1581 i = ts = 0; 1582 while (delims[i]) 1583 { 1584#if defined (HANDLE_MULTIBYTE) 1585 mbstate_t state_bak; 1586 state_bak = state; 1587 mblength = MBRLEN (delims + i, slength, &state); 1588 if (MB_INVALIDCH (mblength)) 1589 state = state_bak; 1590 else if (mblength > 1) 1591 { 1592 memcpy (d2 + ts, delims + i, mblength); 1593 ts += mblength; 1594 i += mblength; 1595 slength -= mblength; 1596 continue; 1597 } 1598#endif 1599 if (whitespace (delims[i]) == 0) 1600 d2[ts++] = delims[i]; 1601 1602 i++; 1603 slength--; 1604 } 1605 d2[ts] = '\0'; 1606 } 1607 1608 ret = (WORD_LIST *)NULL; 1609 1610 /* Remove sequences of whitspace characters at the start of the string, as 1611 long as those characters are delimiters. */ 1612 for (i = 0; member (string[i], d) && spctabnl (string[i]); i++) 1613 ; 1614 if (string[i] == '\0') 1615 return (ret); 1616 1617 ts = i; 1618 nw = 0; 1619 cw = -1; 1620 while (1) 1621 { 1622 te = skip_to_delim (string, ts, d); 1623 1624 /* If we have a non-whitespace delimiter character, use it to make a 1625 separate field. This is just about what $IFS splitting does and 1626 is closer to the behavior of the shell parser. */ 1627 if (ts == te && d2 && member (string[ts], d2)) 1628 { 1629 te = ts + 1; 1630 /* If we're using IFS splitting, the non-whitespace delimiter char 1631 and any additional IFS whitespace delimits a field. */ 1632 if (ifs_split) 1633 while (member (string[te], d) && spctabnl (string[te])) 1634 te++; 1635 else 1636 while (member (string[te], d2)) 1637 te++; 1638 } 1639 1640 token = substring (string, ts, te); 1641 1642 ret = add_string_to_list (token, ret); 1643 free (token); 1644 nw++; 1645 1646 if (sentinel >= ts && sentinel <= te) 1647 cw = nw; 1648 1649 /* If the cursor is at whitespace just before word start, set the 1650 sentinel word to the current word. */ 1651 if (cwp && cw == -1 && sentinel == ts-1) 1652 cw = nw; 1653 1654 /* If the cursor is at whitespace between two words, make a new, empty 1655 word, add it before (well, after, since the list is in reverse order) 1656 the word we just added, and set the current word to that one. */ 1657 if (cwp && cw == -1 && sentinel < ts) 1658 { 1659 tl = make_word_list (make_word (""), ret->next); 1660 ret->next = tl; 1661 cw = nw; 1662 nw++; 1663 } 1664 1665 if (string[te] == 0) 1666 break; 1667 1668 i = te; 1669 while (member (string[i], d) && (ifs_split || spctabnl(string[i]))) 1670 i++; 1671 1672 if (string[i]) 1673 ts = i; 1674 else 1675 break; 1676 } 1677 1678 /* Special case for SENTINEL at the end of STRING. If we haven't found 1679 the word containing SENTINEL yet, and the index we're looking for is at 1680 the end of STRING, add an additional null argument and set the current 1681 word pointer to that. */ 1682 if (cwp && cw == -1 && sentinel >= slen) 1683 { 1684 if (whitespace (string[sentinel - 1])) 1685 { 1686 token = ""; 1687 ret = add_string_to_list (token, ret); 1688 nw++; 1689 } 1690 cw = nw; 1691 } 1692 1693 if (nwp) 1694 *nwp = nw; 1695 if (cwp) 1696 *cwp = cw; 1697 1698 return (REVERSE_LIST (ret, WORD_LIST *)); 1699} 1700#endif /* READLINE */ 1701 1702#if 0 1703/* UNUSED */ 1704/* Extract the name of the variable to bind to from the assignment string. */ 1705char * 1706assignment_name (string) 1707 char *string; 1708{ 1709 int offset; 1710 char *temp; 1711 1712 offset = assignment (string, 0); 1713 if (offset == 0) 1714 return (char *)NULL; 1715 temp = substring (string, 0, offset); 1716 return (temp); 1717} 1718#endif 1719 1720/* **************************************************************** */ 1721/* */ 1722/* Functions to convert strings to WORD_LISTs and vice versa */ 1723/* */ 1724/* **************************************************************** */ 1725 1726/* Return a single string of all the words in LIST. SEP is the separator 1727 to put between individual elements of LIST in the output string. */ 1728char * 1729string_list_internal (list, sep) 1730 WORD_LIST *list; 1731 char *sep; 1732{ 1733 register WORD_LIST *t; 1734 char *result, *r; 1735 int word_len, sep_len, result_size; 1736 1737 if (list == 0) 1738 return ((char *)NULL); 1739 1740 /* Short-circuit quickly if we don't need to separate anything. */ 1741 if (list->next == 0) 1742 return (savestring (list->word->word)); 1743 1744 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */ 1745 sep_len = STRLEN (sep); 1746 result_size = 0; 1747 1748 for (t = list; t; t = t->next) 1749 { 1750 if (t != list) 1751 result_size += sep_len; 1752 result_size += strlen (t->word->word); 1753 } 1754 1755 r = result = (char *)xmalloc (result_size + 1); 1756 1757 for (t = list; t; t = t->next) 1758 { 1759 if (t != list && sep_len) 1760 { 1761 if (sep_len > 1) 1762 { 1763 FASTCOPY (sep, r, sep_len); 1764 r += sep_len; 1765 } 1766 else 1767 *r++ = sep[0]; 1768 } 1769 1770 word_len = strlen (t->word->word); 1771 FASTCOPY (t->word->word, r, word_len); 1772 r += word_len; 1773 } 1774 1775 *r = '\0'; 1776 return (result); 1777} 1778 1779/* Return a single string of all the words present in LIST, separating 1780 each word with a space. */ 1781char * 1782string_list (list) 1783 WORD_LIST *list; 1784{ 1785 return (string_list_internal (list, " ")); 1786} 1787 1788/* Return a single string of all the words present in LIST, obeying the 1789 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the 1790 expansion [of $*] appears within a double quoted string, it expands 1791 to a single field with the value of each parameter separated by the 1792 first character of the IFS variable, or by a <space> if IFS is unset." */ 1793char * 1794string_list_dollar_star (list) 1795 WORD_LIST *list; 1796{ 1797 char *ret; 1798#if defined (HANDLE_MULTIBYTE) 1799# if defined (__GNUC__) 1800 char sep[MB_CUR_MAX + 1]; 1801# else 1802 char *sep = 0; 1803# endif 1804#else 1805 char sep[2]; 1806#endif 1807 1808#if defined (HANDLE_MULTIBYTE) 1809# if !defined (__GNUC__) 1810 sep = (char *)xmalloc (MB_CUR_MAX + 1); 1811# endif /* !__GNUC__ */ 1812 if (ifs_firstc_len == 1) 1813 { 1814 sep[0] = ifs_firstc[0]; 1815 sep[1] = '\0'; 1816 } 1817 else 1818 { 1819 memcpy (sep, ifs_firstc, ifs_firstc_len); 1820 sep[ifs_firstc_len] = '\0'; 1821 } 1822#else 1823 sep[0] = ifs_firstc; 1824 sep[1] = '\0'; 1825#endif 1826 1827 ret = string_list_internal (list, sep); 1828#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__) 1829 free (sep); 1830#endif 1831 return ret; 1832} 1833 1834/* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) 1835 is non-zero, the $@ appears within double quotes, and we should quote 1836 the list before converting it into a string. If IFS is unset, and the 1837 word is not quoted, we just need to quote CTLESC and CTLNUL characters 1838 in the words in the list, because the default value of $IFS is 1839 <space><tab><newline>, IFS characters in the words in the list should 1840 also be split. If IFS is null, and the word is not quoted, we need 1841 to quote the words in the list to preserve the positional parameters 1842 exactly. */ 1843char * 1844string_list_dollar_at (list, quoted) 1845 WORD_LIST *list; 1846 int quoted; 1847{ 1848 char *ifs, *ret; 1849#if defined (HANDLE_MULTIBYTE) 1850# if defined (__GNUC__) 1851 char sep[MB_CUR_MAX + 1]; 1852# else 1853 char *sep = 0; 1854# endif /* !__GNUC__ */ 1855#else 1856 char sep[2]; 1857#endif 1858 WORD_LIST *tlist; 1859 1860 /* XXX this could just be ifs = ifs_value; */ 1861 ifs = ifs_var ? value_cell (ifs_var) : (char *)0; 1862 1863#if defined (HANDLE_MULTIBYTE) 1864# if !defined (__GNUC__) 1865 sep = (char *)xmalloc (MB_CUR_MAX + 1); 1866# endif /* !__GNUC__ */ 1867 if (ifs && *ifs) 1868 { 1869 if (ifs_firstc_len == 1) 1870 { 1871 sep[0] = ifs_firstc[0]; 1872 sep[1] = '\0'; 1873 } 1874 else 1875 { 1876 memcpy (sep, ifs_firstc, ifs_firstc_len); 1877 sep[ifs_firstc_len] = '\0'; 1878 } 1879 } 1880 else 1881 { 1882 sep[0] = ' '; 1883 sep[1] = '\0'; 1884 } 1885#else 1886 sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs; 1887 sep[1] = '\0'; 1888#endif 1889 1890 /* XXX -- why call quote_list if ifs == 0? we can get away without doing 1891 it now that quote_escapes quotes spaces */ 1892#if 0 1893 tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0)) 1894#else 1895 tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) 1896#endif 1897 ? quote_list (list) 1898 : list_quote_escapes (list); 1899 1900 ret = string_list_internal (tlist, sep); 1901#if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__) 1902 free (sep); 1903#endif 1904 return ret; 1905} 1906 1907/* Return the list of words present in STRING. Separate the string into 1908 words at any of the characters found in SEPARATORS. If QUOTED is 1909 non-zero then word in the list will have its quoted flag set, otherwise 1910 the quoted flag is left as make_word () deemed fit. 1911 1912 This obeys the P1003.2 word splitting semantics. If `separators' is 1913 exactly <space><tab><newline>, then the splitting algorithm is that of 1914 the Bourne shell, which treats any sequence of characters from `separators' 1915 as a delimiter. If IFS is unset, which results in `separators' being set 1916 to "", no splitting occurs. If separators has some other value, the 1917 following rules are applied (`IFS white space' means zero or more 1918 occurrences of <space>, <tab>, or <newline>, as long as those characters 1919 are in `separators'): 1920 1921 1) IFS white space is ignored at the start and the end of the 1922 string. 1923 2) Each occurrence of a character in `separators' that is not 1924 IFS white space, along with any adjacent occurrences of 1925 IFS white space delimits a field. 1926 3) Any nonzero-length sequence of IFS white space delimits a field. 1927 */ 1928 1929/* BEWARE! list_string strips null arguments. Don't call it twice and 1930 expect to have "" preserved! */ 1931 1932/* This performs word splitting and quoted null character removal on 1933 STRING. */ 1934#define issep(c) \ 1935 (((separators)[0]) ? ((separators)[1] ? isifs(c) \ 1936 : (c) == (separators)[0]) \ 1937 : 0) 1938 1939WORD_LIST * 1940list_string (string, separators, quoted) 1941 register char *string, *separators; 1942 int quoted; 1943{ 1944 WORD_LIST *result; 1945 WORD_DESC *t; 1946 char *current_word, *s; 1947 int sindex, sh_style_split, whitesep; 1948 size_t slen; 1949 1950 if (!string || !*string) 1951 return ((WORD_LIST *)NULL); 1952 1953 sh_style_split = separators && separators[0] == ' ' && 1954 separators[1] == '\t' && 1955 separators[2] == '\n' && 1956 separators[3] == '\0'; 1957 1958 slen = 0; 1959 /* Remove sequences of whitespace at the beginning of STRING, as 1960 long as those characters appear in IFS. Do not do this if 1961 STRING is quoted or if there are no separator characters. */ 1962 if (!quoted || !separators || !*separators) 1963 { 1964 for (s = string; *s && spctabnl (*s) && issep (*s); s++); 1965 1966 if (!*s) 1967 return ((WORD_LIST *)NULL); 1968 1969 string = s; 1970 } 1971 1972 /* OK, now STRING points to a word that does not begin with white space. 1973 The splitting algorithm is: 1974 extract a word, stopping at a separator 1975 skip sequences of spc, tab, or nl as long as they are separators 1976 This obeys the field splitting rules in Posix.2. */ 1977 slen = (MB_CUR_MAX > 1) ? strlen (string) : 1; 1978 for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; ) 1979 { 1980 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim 1981 unless multibyte chars are possible. */ 1982 current_word = string_extract_verbatim (string, slen, &sindex, separators); 1983 if (current_word == 0) 1984 break; 1985 1986 /* If we have a quoted empty string, add a quoted null argument. We 1987 want to preserve the quoted null character iff this is a quoted 1988 empty string; otherwise the quoted null characters are removed 1989 below. */ 1990 if (QUOTED_NULL (current_word)) 1991 { 1992 t = alloc_word_desc (); 1993 t->word = make_quoted_char ('\0'); 1994 t->flags |= W_QUOTED|W_HASQUOTEDNULL; 1995 result = make_word_list (t, result); 1996 } 1997 else if (current_word[0] != '\0') 1998 { 1999 /* If we have something, then add it regardless. However, 2000 perform quoted null character removal on the current word. */ 2001 remove_quoted_nulls (current_word); 2002 result = add_string_to_list (current_word, result); 2003 result->word->flags &= ~W_HASQUOTEDNULL; /* just to be sure */ 2004 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) 2005 result->word->flags |= W_QUOTED; 2006 } 2007 2008 /* If we're not doing sequences of separators in the traditional 2009 Bourne shell style, then add a quoted null argument. */ 2010 else if (!sh_style_split && !spctabnl (string[sindex])) 2011 { 2012 t = alloc_word_desc (); 2013 t->word = make_quoted_char ('\0'); 2014 t->flags |= W_QUOTED|W_HASQUOTEDNULL; 2015 result = make_word_list (t, result); 2016 } 2017 2018 free (current_word); 2019 2020 /* Note whether or not the separator is IFS whitespace, used later. */ 2021 whitesep = string[sindex] && spctabnl (string[sindex]); 2022 2023 /* Move past the current separator character. */ 2024 if (string[sindex]) 2025 { 2026 DECLARE_MBSTATE; 2027 ADVANCE_CHAR (string, slen, sindex); 2028 } 2029 2030 /* Now skip sequences of space, tab, or newline characters if they are 2031 in the list of separators. */ 2032 while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex])) 2033 sindex++; 2034 2035 /* If the first separator was IFS whitespace and the current character 2036 is a non-whitespace IFS character, it should be part of the current 2037 field delimiter, not a separate delimiter that would result in an 2038 empty field. Look at POSIX.2, 3.6.5, (3)(b). */ 2039 if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex])) 2040 { 2041 sindex++; 2042 /* An IFS character that is not IFS white space, along with any 2043 adjacent IFS white space, shall delimit a field. (SUSv3) */ 2044 while (string[sindex] && spctabnl (string[sindex]) && isifs (string[sindex])) 2045 sindex++; 2046 } 2047 } 2048 return (REVERSE_LIST (result, WORD_LIST *)); 2049} 2050 2051 2052#define iswhitespace(c) (posixly_correct ? posix_whitespace(c) : spctabnl(c)) 2053 2054/* Parse a single word from STRING, using SEPARATORS to separate fields. 2055 ENDPTR is set to the first character after the word. This is used by 2056 the `read' builtin. This is never called with SEPARATORS != $IFS; 2057 it should be simplified. 2058 2059 XXX - this function is very similar to list_string; they should be 2060 combined - XXX */ 2061char * 2062get_word_from_string (stringp, separators, endptr) 2063 char **stringp, *separators, **endptr; 2064{ 2065 register char *s; 2066 char *current_word; 2067 int sindex, sh_style_split, whitesep; 2068 size_t slen; 2069 2070 if (!stringp || !*stringp || !**stringp) 2071 return ((char *)NULL); 2072 2073 s = *stringp; 2074 2075 sh_style_split = separators && separators[0] == ' ' && 2076 separators[1] == '\t' && 2077 separators[2] == '\n' && 2078 separators[3] == '\0'; 2079 2080 /* Remove sequences of whitespace at the beginning of STRING, as 2081 long as those characters appear in IFS. */ 2082 2083 if (posixly_correct || sh_style_split || !separators || !*separators) 2084 { 2085 for (; *s && iswhitespace (*s) && isifs (*s); s++); 2086 2087 /* If the string is nothing but whitespace, update it and return. */ 2088 if (!*s) 2089 { 2090 *stringp = s; 2091 if (endptr) 2092 *endptr = s; 2093 return ((char *)NULL); 2094 } 2095 } 2096 2097 /* OK, S points to a word that does not begin with white space. 2098 Now extract a word, stopping at a separator, save a pointer to 2099 the first character after the word, then skip sequences of spc, 2100 tab, or nl as long as they are separators. 2101 2102 This obeys the field splitting rules in Posix.2. */ 2103 sindex = 0; 2104 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim 2105 unless multibyte chars are possible. */ 2106 slen = (MB_CUR_MAX > 1) ? strlen (s) : 1; 2107 current_word = string_extract_verbatim (s, slen, &sindex, separators); 2108 2109 /* Set ENDPTR to the first character after the end of the word. */ 2110 if (endptr) 2111 *endptr = s + sindex; 2112 2113 /* Note whether or not the separator is IFS whitespace, used later. */ 2114 whitesep = s[sindex] && iswhitespace (s[sindex]); 2115 2116 /* Move past the current separator character. */ 2117 if (s[sindex]) 2118 { 2119 DECLARE_MBSTATE; 2120 ADVANCE_CHAR (s, slen, sindex); 2121 } 2122 2123 /* Now skip sequences of space, tab, or newline characters if they are 2124 in the list of separators. */ 2125 while (s[sindex] && iswhitespace (s[sindex]) && isifs (s[sindex])) 2126 sindex++; 2127 2128 /* If the first separator was IFS whitespace and the current character is 2129 a non-whitespace IFS character, it should be part of the current field 2130 delimiter, not a separate delimiter that would result in an empty field. 2131 Look at POSIX.2, 3.6.5, (3)(b). */ 2132 if (s[sindex] && whitesep && isifs (s[sindex]) && !iswhitespace (s[sindex])) 2133 { 2134 sindex++; 2135 /* An IFS character that is not IFS white space, along with any adjacent 2136 IFS white space, shall delimit a field. */ 2137 while (s[sindex] && iswhitespace (s[sindex]) && isifs (s[sindex])) 2138 sindex++; 2139 } 2140 2141 /* Update STRING to point to the next field. */ 2142 *stringp = s + sindex; 2143 return (current_word); 2144} 2145 2146/* Remove IFS white space at the end of STRING. Start at the end 2147 of the string and walk backwards until the beginning of the string 2148 or we find a character that's not IFS white space and not CTLESC. 2149 Only let CTLESC escape a white space character if SAW_ESCAPE is 2150 non-zero. */ 2151char * 2152strip_trailing_ifs_whitespace (string, separators, saw_escape) 2153 char *string, *separators; 2154 int saw_escape; 2155{ 2156 char *s; 2157 2158 s = string + STRLEN (string) - 1; 2159 while (s > string && ((iswhitespace (*s) && isifs (*s)) || 2160 (saw_escape && *s == CTLESC && iswhitespace (s[1])))) 2161 s--; 2162 *++s = '\0'; 2163 return string; 2164} 2165 2166#if 0 2167/* UNUSED */ 2168/* Split STRING into words at whitespace. Obeys shell-style quoting with 2169 backslashes, single and double quotes. */ 2170WORD_LIST * 2171list_string_with_quotes (string) 2172 char *string; 2173{ 2174 WORD_LIST *list; 2175 char *token, *s; 2176 size_t s_len; 2177 int c, i, tokstart, len; 2178 2179 for (s = string; s && *s && spctabnl (*s); s++) 2180 ; 2181 if (s == 0 || *s == 0) 2182 return ((WORD_LIST *)NULL); 2183 2184 s_len = strlen (s); 2185 tokstart = i = 0; 2186 list = (WORD_LIST *)NULL; 2187 while (1) 2188 { 2189 c = s[i]; 2190 if (c == '\\') 2191 { 2192 i++; 2193 if (s[i]) 2194 i++; 2195 } 2196 else if (c == '\'') 2197 i = skip_single_quoted (s, s_len, ++i); 2198 else if (c == '"') 2199 i = skip_double_quoted (s, s_len, ++i); 2200 else if (c == 0 || spctabnl (c)) 2201 { 2202 /* We have found the end of a token. Make a word out of it and 2203 add it to the word list. */ 2204 token = substring (s, tokstart, i); 2205 list = add_string_to_list (token, list); 2206 free (token); 2207 while (spctabnl (s[i])) 2208 i++; 2209 if (s[i]) 2210 tokstart = i; 2211 else 2212 break; 2213 } 2214 else 2215 i++; /* normal character */ 2216 } 2217 return (REVERSE_LIST (list, WORD_LIST *)); 2218} 2219#endif 2220 2221/********************************************************/ 2222/* */ 2223/* Functions to perform assignment statements */ 2224/* */ 2225/********************************************************/ 2226 2227#if defined (ARRAY_VARS) 2228static SHELL_VAR * 2229do_compound_assignment (name, value, flags) 2230 char *name, *value; 2231 int flags; 2232{ 2233 SHELL_VAR *v; 2234 int mklocal; 2235 WORD_LIST *list; 2236 2237 mklocal = flags & ASS_MKLOCAL; 2238 2239 if (mklocal && variable_context) 2240 { 2241 list = expand_compound_array_assignment (value, flags); 2242 v = find_variable (name); 2243 if (v == 0 || array_p (v) == 0 || v->context != variable_context) 2244 v = make_local_array_variable (name); 2245 assign_compound_array_list (v, list, flags); 2246 } 2247 else 2248 v = assign_array_from_string (name, value, flags); 2249 2250 return (v); 2251} 2252#endif 2253 2254/* Given STRING, an assignment string, get the value of the right side 2255 of the `=', and bind it to the left side. If EXPAND is true, then 2256 perform parameter expansion, command substitution, and arithmetic 2257 expansion on the right-hand side. Perform tilde expansion in any 2258 case. Do not perform word splitting on the result of expansion. */ 2259static int 2260do_assignment_internal (word, expand) 2261 const WORD_DESC *word; 2262 int expand; 2263{ 2264 int offset, tlen, appendop, assign_list, aflags; 2265 char *name, *value; 2266 SHELL_VAR *entry; 2267#if defined (ARRAY_VARS) 2268 char *t; 2269 int ni; 2270#endif 2271 const char *string; 2272 2273 if (word == 0 || word->word == 0) 2274 return 0; 2275 2276 appendop = assign_list = aflags = 0; 2277 string = word->word; 2278 offset = assignment (string, 0); 2279 name = savestring (string); 2280 value = (char *)NULL; 2281 2282 if (name[offset] == '=') 2283 { 2284 char *temp; 2285 2286 if (name[offset - 1] == '+') 2287 { 2288 appendop = 1; 2289 name[offset - 1] = '\0'; 2290 } 2291 2292 name[offset] = 0; /* might need this set later */ 2293 temp = name + offset + 1; 2294 tlen = STRLEN (temp); 2295 2296#if defined (ARRAY_VARS) 2297 if (expand && (word->flags & W_COMPASSIGN)) 2298 { 2299 assign_list = ni = 1; 2300 value = extract_array_assignment_list (temp, &ni); 2301 } 2302 else 2303#endif 2304 2305 if (expand && temp[0]) 2306 value = expand_string_if_necessary (temp, 0, expand_string_assignment); 2307 else 2308 value = savestring (temp); 2309 } 2310 2311 if (value == 0) 2312 { 2313 value = (char *)xmalloc (1); 2314 value[0] = '\0'; 2315 } 2316 2317 if (echo_command_at_execute) 2318 { 2319 if (appendop) 2320 name[offset - 1] = '+'; 2321 xtrace_print_assignment (name, value, assign_list, 1); 2322 if (appendop) 2323 name[offset - 1] = '\0'; 2324 } 2325 2326#define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0) 2327 2328 if (appendop) 2329 aflags |= ASS_APPEND; 2330 2331#if defined (ARRAY_VARS) 2332 if (t = xstrchr (name, '[')) /*]*/ 2333 { 2334 if (assign_list) 2335 { 2336 report_error (_("%s: cannot assign list to array member"), name); 2337 ASSIGN_RETURN (0); 2338 } 2339 entry = assign_array_element (name, value, aflags); 2340 if (entry == 0) 2341 ASSIGN_RETURN (0); 2342 } 2343 else if (assign_list) 2344 { 2345 if (word->flags & W_ASSIGNARG) 2346 aflags |= ASS_MKLOCAL; 2347 entry = do_compound_assignment (name, value, aflags); 2348 } 2349 else 2350#endif /* ARRAY_VARS */ 2351 entry = bind_variable (name, value, aflags); 2352 2353 stupidly_hack_special_variables (name); 2354 2355 if (entry) 2356 VUNSETATTR (entry, att_invisible); 2357 2358 /* Return 1 if the assignment seems to have been performed correctly. */ 2359 ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0); 2360} 2361 2362/* Perform the assignment statement in STRING, and expand the 2363 right side by doing tilde, command and parameter expansion. */ 2364int 2365do_assignment (string) 2366 char *string; 2367{ 2368 WORD_DESC td; 2369 2370 td.flags = W_ASSIGNMENT; 2371 td.word = string; 2372 2373 return do_assignment_internal (&td, 1); 2374} 2375 2376int 2377do_word_assignment (word) 2378 WORD_DESC *word; 2379{ 2380 return do_assignment_internal (word, 1); 2381} 2382 2383/* Given STRING, an assignment string, get the value of the right side 2384 of the `=', and bind it to the left side. Do not perform any word 2385 expansions on the right hand side. */ 2386int 2387do_assignment_no_expand (string) 2388 char *string; 2389{ 2390 WORD_DESC td; 2391 2392 td.flags = W_ASSIGNMENT; 2393 td.word = string; 2394 2395 return (do_assignment_internal (&td, 0)); 2396} 2397 2398/*************************************************** 2399 * * 2400 * Functions to manage the positional parameters * 2401 * * 2402 ***************************************************/ 2403 2404/* Return the word list that corresponds to `$*'. */ 2405WORD_LIST * 2406list_rest_of_args () 2407{ 2408 register WORD_LIST *list, *args; 2409 int i; 2410 2411 /* Break out of the loop as soon as one of the dollar variables is null. */ 2412 for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++) 2413 list = make_word_list (make_bare_word (dollar_vars[i]), list); 2414 2415 for (args = rest_of_args; args; args = args->next) 2416 list = make_word_list (make_bare_word (args->word->word), list); 2417 2418 return (REVERSE_LIST (list, WORD_LIST *)); 2419} 2420 2421int 2422number_of_args () 2423{ 2424 register WORD_LIST *list; 2425 int n; 2426 2427 for (n = 0; n < 9 && dollar_vars[n+1]; n++) 2428 ; 2429 for (list = rest_of_args; list; list = list->next) 2430 n++; 2431 return n; 2432} 2433 2434/* Return the value of a positional parameter. This handles values > 10. */ 2435char * 2436get_dollar_var_value (ind) 2437 intmax_t ind; 2438{ 2439 char *temp; 2440 WORD_LIST *p; 2441 2442 if (ind < 10) 2443 temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL; 2444 else /* We want something like ${11} */ 2445 { 2446 ind -= 10; 2447 for (p = rest_of_args; p && ind--; p = p->next) 2448 ; 2449 temp = p ? savestring (p->word->word) : (char *)NULL; 2450 } 2451 return (temp); 2452} 2453 2454/* Make a single large string out of the dollar digit variables, 2455 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special 2456 case of "$*" with respect to IFS. */ 2457char * 2458string_rest_of_args (dollar_star) 2459 int dollar_star; 2460{ 2461 register WORD_LIST *list; 2462 char *string; 2463 2464 list = list_rest_of_args (); 2465 string = dollar_star ? string_list_dollar_star (list) : string_list (list); 2466 dispose_words (list); 2467 return (string); 2468} 2469 2470/* Return a string containing the positional parameters from START to 2471 END, inclusive. If STRING[0] == '*', we obey the rules for $*, 2472 which only makes a difference if QUOTED is non-zero. If QUOTED includes 2473 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise 2474 no quoting chars are added. */ 2475static char * 2476pos_params (string, start, end, quoted) 2477 char *string; 2478 int start, end, quoted; 2479{ 2480 WORD_LIST *save, *params, *h, *t; 2481 char *ret; 2482 int i; 2483 2484 /* see if we can short-circuit. if start == end, we want 0 parameters. */ 2485 if (start == end) 2486 return ((char *)NULL); 2487 2488 save = params = list_rest_of_args (); 2489 if (save == 0) 2490 return ((char *)NULL); 2491 2492 for (i = 1; params && i < start; i++) 2493 params = params->next; 2494 if (params == 0) 2495 return ((char *)NULL); 2496 for (h = t = params; params && i < end; i++) 2497 { 2498 t = params; 2499 params = params->next; 2500 } 2501 2502 t->next = (WORD_LIST *)NULL; 2503 if (string[0] == '*') 2504 { 2505 if (quoted & Q_DOUBLE_QUOTES) 2506 ret = string_list_dollar_star (quote_list (h)); 2507 else if (quoted & Q_HERE_DOCUMENT) 2508 ret = string_list (quote_list (h)); 2509 else 2510 ret = string_list (h); 2511 } 2512 else 2513 ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (h) : h); 2514 if (t != params) 2515 t->next = params; 2516 2517 dispose_words (save); 2518 return (ret); 2519} 2520 2521/******************************************************************/ 2522/* */ 2523/* Functions to expand strings to strings or WORD_LISTs */ 2524/* */ 2525/******************************************************************/ 2526 2527#if defined (PROCESS_SUBSTITUTION) 2528#define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~') 2529#else 2530#define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~') 2531#endif 2532 2533/* If there are any characters in STRING that require full expansion, 2534 then call FUNC to expand STRING; otherwise just perform quote 2535 removal if necessary. This returns a new string. */ 2536static char * 2537expand_string_if_necessary (string, quoted, func) 2538 char *string; 2539 int quoted; 2540 EXPFUNC *func; 2541{ 2542 WORD_LIST *list; 2543 size_t slen; 2544 int i, saw_quote; 2545 char *ret; 2546 DECLARE_MBSTATE; 2547 2548 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */ 2549 slen = (MB_CUR_MAX > 1) ? strlen (string) : 0; 2550 i = saw_quote = 0; 2551 while (string[i]) 2552 { 2553 if (EXP_CHAR (string[i])) 2554 break; 2555 else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"') 2556 saw_quote = 1; 2557 ADVANCE_CHAR (string, slen, i); 2558 } 2559 2560 if (string[i]) 2561 { 2562 list = (*func) (string, quoted); 2563 if (list) 2564 { 2565 ret = string_list (list); 2566 dispose_words (list); 2567 } 2568 else 2569 ret = (char *)NULL; 2570 } 2571 else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0)) 2572 ret = string_quote_removal (string, quoted); 2573 else 2574 ret = savestring (string); 2575 2576 return ret; 2577} 2578 2579static inline char * 2580expand_string_to_string_internal (string, quoted, func) 2581 char *string; 2582 int quoted; 2583 EXPFUNC *func; 2584{ 2585 WORD_LIST *list; 2586 char *ret; 2587 2588 if (string == 0 || *string == '\0') 2589 return ((char *)NULL); 2590 2591 list = (*func) (string, quoted); 2592 if (list) 2593 { 2594 ret = string_list (list); 2595 dispose_words (list); 2596 } 2597 else 2598 ret = (char *)NULL; 2599 2600 return (ret); 2601} 2602 2603char * 2604expand_string_to_string (string, quoted) 2605 char *string; 2606 int quoted; 2607{ 2608 return (expand_string_to_string_internal (string, quoted, expand_string)); 2609} 2610 2611char * 2612expand_string_unsplit_to_string (string, quoted) 2613 char *string; 2614 int quoted; 2615{ 2616 return (expand_string_to_string_internal (string, quoted, expand_string_unsplit)); 2617} 2618 2619char * 2620expand_assignment_string_to_string (string, quoted) 2621 char *string; 2622 int quoted; 2623{ 2624 return (expand_string_to_string_internal (string, quoted, expand_string_assignment)); 2625} 2626 2627char * 2628expand_arith_string (string, quoted) 2629 char *string; 2630 int quoted; 2631{ 2632 return (expand_string_if_necessary (string, quoted, expand_string)); 2633} 2634 2635#if defined (COND_COMMAND) 2636/* Just remove backslashes in STRING. Returns a new string. */ 2637char * 2638remove_backslashes (string) 2639 char *string; 2640{ 2641 char *r, *ret, *s; 2642 2643 r = ret = (char *)xmalloc (strlen (string) + 1); 2644 for (s = string; s && *s; ) 2645 { 2646 if (*s == '\\') 2647 s++; 2648 if (*s == 0) 2649 break; 2650 *r++ = *s++; 2651 } 2652 *r = '\0'; 2653 return ret; 2654} 2655 2656/* This needs better error handling. */ 2657/* Expand W for use as an argument to a unary or binary operator in a 2658 [[...]] expression. If SPECIAL is 1, this is the rhs argument 2659 to the != or == operator, and should be treated as a pattern. In 2660 this case, we quote the string specially for the globbing code. If 2661 SPECIAL is 2, this is an rhs argument for the =~ operator, and should 2662 be quoted appropriately for regcomp/regexec. The caller is responsible 2663 for removing the backslashes if the unquoted word is needed later. */ 2664char * 2665cond_expand_word (w, special) 2666 WORD_DESC *w; 2667 int special; 2668{ 2669 char *r, *p; 2670 WORD_LIST *l; 2671 int qflags; 2672 2673 if (w->word == 0 || w->word[0] == '\0') 2674 return ((char *)NULL); 2675 2676 l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0); 2677 if (l) 2678 { 2679 if (special == 0) 2680 { 2681 dequote_list (l); 2682 r = string_list (l); 2683 } 2684 else 2685 { 2686 qflags = QGLOB_CVTNULL; 2687 if (special == 2) 2688 qflags |= QGLOB_REGEXP; 2689 p = string_list (l); 2690 r = quote_string_for_globbing (p, qflags); 2691 free (p); 2692 } 2693 dispose_words (l); 2694 } 2695 else 2696 r = (char *)NULL; 2697 2698 return r; 2699} 2700#endif 2701 2702/* Call expand_word_internal to expand W and handle error returns. 2703 A convenience function for functions that don't want to handle 2704 any errors or free any memory before aborting. */ 2705static WORD_LIST * 2706call_expand_word_internal (w, q, i, c, e) 2707 WORD_DESC *w; 2708 int q, i, *c, *e; 2709{ 2710 WORD_LIST *result; 2711 2712 result = expand_word_internal (w, q, i, c, e); 2713 if (result == &expand_word_error || result == &expand_word_fatal) 2714 { 2715 /* By convention, each time this error is returned, w->word has 2716 already been freed (it sometimes may not be in the fatal case, 2717 but that doesn't result in a memory leak because we're going 2718 to exit in most cases). */ 2719 w->word = (char *)NULL; 2720 last_command_exit_value = EXECUTION_FAILURE; 2721 exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF); 2722 /* NOTREACHED */ 2723 } 2724 else 2725 return (result); 2726} 2727 2728/* Perform parameter expansion, command substitution, and arithmetic 2729 expansion on STRING, as if it were a word. Leave the result quoted. */ 2730static WORD_LIST * 2731expand_string_internal (string, quoted) 2732 char *string; 2733 int quoted; 2734{ 2735 WORD_DESC td; 2736 WORD_LIST *tresult; 2737 2738 if (string == 0 || *string == 0) 2739 return ((WORD_LIST *)NULL); 2740 2741 td.flags = 0; 2742 td.word = savestring (string); 2743 2744 tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL); 2745 2746 FREE (td.word); 2747 return (tresult); 2748} 2749 2750/* Expand STRING by performing parameter expansion, command substitution, 2751 and arithmetic expansion. Dequote the resulting WORD_LIST before 2752 returning it, but do not perform word splitting. The call to 2753 remove_quoted_nulls () is in here because word splitting normally 2754 takes care of quote removal. */ 2755WORD_LIST * 2756expand_string_unsplit (string, quoted) 2757 char *string; 2758 int quoted; 2759{ 2760 WORD_LIST *value; 2761 2762 if (string == 0 || *string == '\0') 2763 return ((WORD_LIST *)NULL); 2764 2765 expand_no_split_dollar_star = 1; 2766 value = expand_string_internal (string, quoted); 2767 expand_no_split_dollar_star = 0; 2768 2769 if (value) 2770 { 2771 if (value->word) 2772 { 2773 remove_quoted_nulls (value->word->word); 2774 value->word->flags &= ~W_HASQUOTEDNULL; 2775 } 2776 dequote_list (value); 2777 } 2778 return (value); 2779} 2780 2781/* Expand the rhs of an assignment statement */ 2782WORD_LIST * 2783expand_string_assignment (string, quoted) 2784 char *string; 2785 int quoted; 2786{ 2787 WORD_DESC td; 2788 WORD_LIST *value; 2789 2790 if (string == 0 || *string == '\0') 2791 return ((WORD_LIST *)NULL); 2792 2793 expand_no_split_dollar_star = 1; 2794 2795 td.flags = W_ASSIGNRHS; 2796 td.word = savestring (string); 2797 value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL); 2798 FREE (td.word); 2799 2800 expand_no_split_dollar_star = 0; 2801 2802 if (value) 2803 { 2804 if (value->word) 2805 { 2806 remove_quoted_nulls (value->word->word); 2807 value->word->flags &= ~W_HASQUOTEDNULL; 2808 } 2809 dequote_list (value); 2810 } 2811 return (value); 2812} 2813 2814 2815/* Expand one of the PS? prompt strings. This is a sort of combination of 2816 expand_string_unsplit and expand_string_internal, but returns the 2817 passed string when an error occurs. Might want to trap other calls 2818 to jump_to_top_level here so we don't endlessly loop. */ 2819WORD_LIST * 2820expand_prompt_string (string, quoted, wflags) 2821 char *string; 2822 int quoted; 2823 int wflags; 2824{ 2825 WORD_LIST *value; 2826 WORD_DESC td; 2827 2828 if (string == 0 || *string == 0) 2829 return ((WORD_LIST *)NULL); 2830 2831 td.flags = wflags; 2832 td.word = savestring (string); 2833 2834 no_longjmp_on_fatal_error = 1; 2835 value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL); 2836 no_longjmp_on_fatal_error = 0; 2837 2838 if (value == &expand_word_error || value == &expand_word_fatal) 2839 { 2840 value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL); 2841 return value; 2842 } 2843 FREE (td.word); 2844 if (value) 2845 { 2846 if (value->word) 2847 { 2848 remove_quoted_nulls (value->word->word); 2849 value->word->flags &= ~W_HASQUOTEDNULL; 2850 } 2851 dequote_list (value); 2852 } 2853 return (value); 2854} 2855 2856/* Expand STRING just as if you were expanding a word, but do not dequote 2857 the resultant WORD_LIST. This is called only from within this file, 2858 and is used to correctly preserve quoted characters when expanding 2859 things like ${1+"$@"}. This does parameter expansion, command 2860 substitution, arithmetic expansion, and word splitting. */ 2861static WORD_LIST * 2862expand_string_leave_quoted (string, quoted) 2863 char *string; 2864 int quoted; 2865{ 2866 WORD_LIST *tlist; 2867 WORD_LIST *tresult; 2868 2869 if (string == 0 || *string == '\0') 2870 return ((WORD_LIST *)NULL); 2871 2872 tlist = expand_string_internal (string, quoted); 2873 2874 if (tlist) 2875 { 2876 tresult = word_list_split (tlist); 2877 dispose_words (tlist); 2878 return (tresult); 2879 } 2880 return ((WORD_LIST *)NULL); 2881} 2882 2883/* This does not perform word splitting or dequote the WORD_LIST 2884 it returns. */ 2885static WORD_LIST * 2886expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at) 2887 char *string; 2888 int quoted, *dollar_at_p, *has_dollar_at; 2889{ 2890 WORD_DESC td; 2891 WORD_LIST *tresult; 2892 2893 if (string == 0 || *string == '\0') 2894 return (WORD_LIST *)NULL; 2895 2896 td.flags = 0; 2897 td.word = string; 2898 tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at); 2899 return (tresult); 2900} 2901 2902/* Expand STRING just as if you were expanding a word. This also returns 2903 a list of words. Note that filename globbing is *NOT* done for word 2904 or string expansion, just when the shell is expanding a command. This 2905 does parameter expansion, command substitution, arithmetic expansion, 2906 and word splitting. Dequote the resultant WORD_LIST before returning. */ 2907WORD_LIST * 2908expand_string (string, quoted) 2909 char *string; 2910 int quoted; 2911{ 2912 WORD_LIST *result; 2913 2914 if (string == 0 || *string == '\0') 2915 return ((WORD_LIST *)NULL); 2916 2917 result = expand_string_leave_quoted (string, quoted); 2918 return (result ? dequote_list (result) : result); 2919} 2920 2921/*************************************************** 2922 * * 2923 * Functions to handle quoting chars * 2924 * * 2925 ***************************************************/ 2926 2927/* Conventions: 2928 2929 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string. 2930 The parser passes CTLNUL as CTLESC CTLNUL. */ 2931 2932/* Quote escape characters in string s, but no other characters. This is 2933 used to protect CTLESC and CTLNUL in variable values from the rest of 2934 the word expansion process after the variable is expanded. If IFS is 2935 null, we quote spaces as well, just in case we split on spaces later 2936 (in the case of unquoted $@, we will eventually attempt to split the 2937 entire word on spaces). Corresponding code exists in dequote_escapes. 2938 Even if we don't end up splitting on spaces, quoting spaces is not a 2939 problem. */ 2940char * 2941quote_escapes (string) 2942 char *string; 2943{ 2944 register char *s, *t; 2945 size_t slen; 2946 char *result, *send; 2947 int quote_spaces; 2948 DECLARE_MBSTATE; 2949 2950 slen = strlen (string); 2951 send = string + slen; 2952 2953 quote_spaces = (ifs_value && *ifs_value == 0); 2954 t = result = (char *)xmalloc ((slen * 2) + 1); 2955 s = string; 2956 2957 while (*s) 2958 { 2959 if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' ')) 2960 *t++ = CTLESC; 2961 COPY_CHAR_P (t, s, send); 2962 } 2963 *t = '\0'; 2964 return (result); 2965} 2966 2967static WORD_LIST * 2968list_quote_escapes (list) 2969 WORD_LIST *list; 2970{ 2971 register WORD_LIST *w; 2972 char *t; 2973 2974 for (w = list; w; w = w->next) 2975 { 2976 t = w->word->word; 2977 w->word->word = quote_escapes (t); 2978 free (t); 2979 } 2980 return list; 2981} 2982 2983/* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL. 2984 2985 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL. 2986 This is necessary to make unquoted CTLESC and CTLNUL characters in the 2987 data stream pass through properly. 2988 2989 We need to remove doubled CTLESC characters inside quoted strings before 2990 quoting the entire string, so we do not double the number of CTLESC 2991 characters. 2992 2993 Also used by parts of the pattern substitution code. */ 2994static char * 2995dequote_escapes (string) 2996 char *string; 2997{ 2998 register char *s, *t; 2999 size_t slen; 3000 char *result, *send; 3001 int quote_spaces; 3002 DECLARE_MBSTATE; 3003 3004 if (string == 0) 3005 return string; 3006 3007 slen = strlen (string); 3008 send = string + slen; 3009 3010 t = result = (char *)xmalloc (slen + 1); 3011 s = string; 3012 3013 if (strchr (string, CTLESC) == 0) 3014 return (strcpy (result, s)); 3015 3016 quote_spaces = (ifs_value && *ifs_value == 0); 3017 while (*s) 3018 { 3019 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' '))) 3020 { 3021 s++; 3022 if (*s == '\0') 3023 break; 3024 } 3025 COPY_CHAR_P (t, s, send); 3026 } 3027 *t = '\0'; 3028 return result; 3029} 3030 3031/* Return a new string with the quoted representation of character C. 3032 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be 3033 set in any resultant WORD_DESC where this value is the word. */ 3034static char * 3035make_quoted_char (c) 3036 int c; 3037{ 3038 char *temp; 3039 3040 temp = (char *)xmalloc (3); 3041 if (c == 0) 3042 { 3043 temp[0] = CTLNUL; 3044 temp[1] = '\0'; 3045 } 3046 else 3047 { 3048 temp[0] = CTLESC; 3049 temp[1] = c; 3050 temp[2] = '\0'; 3051 } 3052 return (temp); 3053} 3054 3055/* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so 3056 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where 3057 this value is the word. */ 3058char * 3059quote_string (string) 3060 char *string; 3061{ 3062 register char *t; 3063 size_t slen; 3064 char *result, *send; 3065 3066 if (*string == 0) 3067 { 3068 result = (char *)xmalloc (2); 3069 result[0] = CTLNUL; 3070 result[1] = '\0'; 3071 } 3072 else 3073 { 3074 DECLARE_MBSTATE; 3075 3076 slen = strlen (string); 3077 send = string + slen; 3078 3079 result = (char *)xmalloc ((slen * 2) + 1); 3080 3081 for (t = result; string < send; ) 3082 { 3083 *t++ = CTLESC; 3084 COPY_CHAR_P (t, string, send); 3085 } 3086 *t = '\0'; 3087 } 3088 return (result); 3089} 3090 3091/* De-quote quoted characters in STRING. */ 3092char * 3093dequote_string (string) 3094 char *string; 3095{ 3096 register char *s, *t; 3097 size_t slen; 3098 char *result, *send; 3099 DECLARE_MBSTATE; 3100 3101 slen = strlen (string); 3102 3103 t = result = (char *)xmalloc (slen + 1); 3104 3105 if (QUOTED_NULL (string)) 3106 { 3107 result[0] = '\0'; 3108 return (result); 3109 } 3110 3111 /* If no character in the string can be quoted, don't bother examining 3112 each character. Just return a copy of the string passed to us. */ 3113 if (strchr (string, CTLESC) == NULL) 3114 return (strcpy (result, string)); 3115 3116 send = string + slen; 3117 s = string; 3118 while (*s) 3119 { 3120 if (*s == CTLESC) 3121 { 3122 s++; 3123 if (*s == '\0') 3124 break; 3125 } 3126 COPY_CHAR_P (t, s, send); 3127 } 3128 3129 *t = '\0'; 3130 return (result); 3131} 3132 3133/* Quote the entire WORD_LIST list. */ 3134static WORD_LIST * 3135quote_list (list) 3136 WORD_LIST *list; 3137{ 3138 register WORD_LIST *w; 3139 char *t; 3140 3141 for (w = list; w; w = w->next) 3142 { 3143 t = w->word->word; 3144 w->word->word = quote_string (t); 3145 free (t); 3146 w->word->flags |= W_QUOTED; 3147 /* XXX - turn on W_HAVEQUOTEDNULL here? */ 3148 } 3149 return list; 3150} 3151 3152/* De-quote quoted characters in each word in LIST. */ 3153WORD_LIST * 3154dequote_list (list) 3155 WORD_LIST *list; 3156{ 3157 register char *s; 3158 register WORD_LIST *tlist; 3159 3160 for (tlist = list; tlist; tlist = tlist->next) 3161 { 3162 s = dequote_string (tlist->word->word); 3163 free (tlist->word->word); 3164 tlist->word->word = s; 3165 /* XXX - turn off W_HAVEQUOTEDNULL here? */ 3166 } 3167 return list; 3168} 3169 3170/* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed 3171 string. */ 3172static char * 3173remove_quoted_escapes (string) 3174 char *string; 3175{ 3176 char *t; 3177 3178 if (string) 3179 { 3180 t = dequote_escapes (string); 3181 strcpy (string, t); 3182 free (t); 3183 } 3184 3185 return (string); 3186} 3187 3188/* Perform quoted null character removal on STRING. We don't allow any 3189 quoted null characters in the middle or at the ends of strings because 3190 of how expand_word_internal works. remove_quoted_nulls () turns 3191 STRING into an empty string iff it only consists of a quoted null, 3192 and removes all unquoted CTLNUL characters. */ 3193static char * 3194remove_quoted_nulls (string) 3195 char *string; 3196{ 3197 register size_t slen; 3198 register int i, j, prev_i; 3199 DECLARE_MBSTATE; 3200 3201 if (strchr (string, CTLNUL) == 0) /* XXX */ 3202 return string; /* XXX */ 3203 3204 slen = strlen (string); 3205 i = j = 0; 3206 3207 while (i < slen) 3208 { 3209 if (string[i] == CTLESC) 3210 { 3211 /* Old code had j++, but we cannot assume that i == j at this 3212 point -- what if a CTLNUL has already been removed from the 3213 string? We don't want to drop the CTLESC or recopy characters 3214 that we've already copied down. */ 3215 i++; string[j++] = CTLESC; 3216 if (i == slen) 3217 break; 3218 } 3219 else if (string[i] == CTLNUL) 3220 i++; 3221 3222 prev_i = i; 3223 ADVANCE_CHAR (string, slen, i); 3224 if (j < prev_i) 3225 { 3226 do string[j++] = string[prev_i++]; while (prev_i < i); 3227 } 3228 else 3229 j = i; 3230 } 3231 string[j] = '\0'; 3232 3233 return (string); 3234} 3235 3236/* Perform quoted null character removal on each element of LIST. 3237 This modifies LIST. */ 3238void 3239word_list_remove_quoted_nulls (list) 3240 WORD_LIST *list; 3241{ 3242 register WORD_LIST *t; 3243 3244 for (t = list; t; t = t->next) 3245 { 3246 remove_quoted_nulls (t->word->word); 3247 t->word->flags &= ~W_HASQUOTEDNULL; 3248 } 3249} 3250 3251/* **************************************************************** */ 3252/* */ 3253/* Functions for Matching and Removing Patterns */ 3254/* */ 3255/* **************************************************************** */ 3256 3257#if defined (HANDLE_MULTIBYTE) 3258#if 0 /* Currently unused */ 3259static unsigned char * 3260mb_getcharlens (string, len) 3261 char *string; 3262 int len; 3263{ 3264 int i, offset, last; 3265 unsigned char *ret; 3266 char *p; 3267 DECLARE_MBSTATE; 3268 3269 i = offset = 0; 3270 last = 0; 3271 ret = (unsigned char *)xmalloc (len); 3272 memset (ret, 0, len); 3273 while (string[last]) 3274 { 3275 ADVANCE_CHAR (string, len, offset); 3276 ret[last] = offset - last; 3277 last = offset; 3278 } 3279 return ret; 3280} 3281#endif 3282#endif 3283 3284/* Remove the portion of PARAM matched by PATTERN according to OP, where OP 3285 can have one of 4 values: 3286 RP_LONG_LEFT remove longest matching portion at start of PARAM 3287 RP_SHORT_LEFT remove shortest matching portion at start of PARAM 3288 RP_LONG_RIGHT remove longest matching portion at end of PARAM 3289 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM 3290*/ 3291 3292#define RP_LONG_LEFT 1 3293#define RP_SHORT_LEFT 2 3294#define RP_LONG_RIGHT 3 3295#define RP_SHORT_RIGHT 4 3296 3297static char * 3298remove_upattern (param, pattern, op) 3299 char *param, *pattern; 3300 int op; 3301{ 3302 register int len; 3303 register char *end; 3304 register char *p, *ret, c; 3305 3306 len = STRLEN (param); 3307 end = param + len; 3308 3309 switch (op) 3310 { 3311 case RP_LONG_LEFT: /* remove longest match at start */ 3312 for (p = end; p >= param; p--) 3313 { 3314 c = *p; *p = '\0'; 3315 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH) 3316 { 3317 *p = c; 3318 return (savestring (p)); 3319 } 3320 *p = c; 3321 3322 } 3323 break; 3324 3325 case RP_SHORT_LEFT: /* remove shortest match at start */ 3326 for (p = param; p <= end; p++) 3327 { 3328 c = *p; *p = '\0'; 3329 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH) 3330 { 3331 *p = c; 3332 return (savestring (p)); 3333 } 3334 *p = c; 3335 } 3336 break; 3337 3338 case RP_LONG_RIGHT: /* remove longest match at end */ 3339 for (p = param; p <= end; p++) 3340 { 3341 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH) 3342 { 3343 c = *p; *p = '\0'; 3344 ret = savestring (param); 3345 *p = c; 3346 return (ret); 3347 } 3348 } 3349 break; 3350 3351 case RP_SHORT_RIGHT: /* remove shortest match at end */ 3352 for (p = end; p >= param; p--) 3353 { 3354 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH) 3355 { 3356 c = *p; *p = '\0'; 3357 ret = savestring (param); 3358 *p = c; 3359 return (ret); 3360 } 3361 } 3362 break; 3363 } 3364 3365 return (savestring (param)); /* no match, return original string */ 3366} 3367 3368#if defined (HANDLE_MULTIBYTE) 3369static wchar_t * 3370remove_wpattern (wparam, wstrlen, wpattern, op) 3371 wchar_t *wparam; 3372 size_t wstrlen; 3373 wchar_t *wpattern; 3374 int op; 3375{ 3376 wchar_t wc, *ret; 3377 int n; 3378 3379 switch (op) 3380 { 3381 case RP_LONG_LEFT: /* remove longest match at start */ 3382 for (n = wstrlen; n >= 0; n--) 3383 { 3384 wc = wparam[n]; wparam[n] = L'\0'; 3385 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH) 3386 { 3387 wparam[n] = wc; 3388 return (wcsdup (wparam + n)); 3389 } 3390 wparam[n] = wc; 3391 } 3392 break; 3393 3394 case RP_SHORT_LEFT: /* remove shortest match at start */ 3395 for (n = 0; n <= wstrlen; n++) 3396 { 3397 wc = wparam[n]; wparam[n] = L'\0'; 3398 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH) 3399 { 3400 wparam[n] = wc; 3401 return (wcsdup (wparam + n)); 3402 } 3403 wparam[n] = wc; 3404 } 3405 break; 3406 3407 case RP_LONG_RIGHT: /* remove longest match at end */ 3408 for (n = 0; n <= wstrlen; n++) 3409 { 3410 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH) 3411 { 3412 wc = wparam[n]; wparam[n] = L'\0'; 3413 ret = wcsdup (wparam); 3414 wparam[n] = wc; 3415 return (ret); 3416 } 3417 } 3418 break; 3419 3420 case RP_SHORT_RIGHT: /* remove shortest match at end */ 3421 for (n = wstrlen; n >= 0; n--) 3422 { 3423 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH) 3424 { 3425 wc = wparam[n]; wparam[n] = L'\0'; 3426 ret = wcsdup (wparam); 3427 wparam[n] = wc; 3428 return (ret); 3429 } 3430 } 3431 break; 3432 } 3433 3434 return (wcsdup (wparam)); /* no match, return original string */ 3435} 3436#endif /* HANDLE_MULTIBYTE */ 3437 3438static char * 3439remove_pattern (param, pattern, op) 3440 char *param, *pattern; 3441 int op; 3442{ 3443 if (param == NULL) 3444 return (param); 3445 if (*param == '\0' || pattern == NULL || *pattern == '\0') /* minor optimization */ 3446 return (savestring (param)); 3447 3448#if defined (HANDLE_MULTIBYTE) 3449 if (MB_CUR_MAX > 1) 3450 { 3451 wchar_t *ret, *oret; 3452 size_t n; 3453 wchar_t *wparam, *wpattern; 3454 mbstate_t ps; 3455 char *xret; 3456 3457 n = xdupmbstowcs (&wpattern, NULL, pattern); 3458 if (n == (size_t)-1) 3459 return (remove_upattern (param, pattern, op)); 3460 n = xdupmbstowcs (&wparam, NULL, param); 3461 if (n == (size_t)-1) 3462 { 3463 free (wpattern); 3464 return (remove_upattern (param, pattern, op)); 3465 } 3466 oret = ret = remove_wpattern (wparam, n, wpattern, op); 3467 3468 free (wparam); 3469 free (wpattern); 3470 3471 n = strlen (param); 3472 xret = (char *)xmalloc (n + 1); 3473 memset (&ps, '\0', sizeof (mbstate_t)); 3474 n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps); 3475 xret[n] = '\0'; /* just to make sure */ 3476 free (oret); 3477 return xret; 3478 } 3479 else 3480#endif 3481 return (remove_upattern (param, pattern, op)); 3482} 3483 3484/* Return 1 of the first character of STRING could match the first 3485 character of pattern PAT. Used to avoid n2 calls to strmatch(). */ 3486static int 3487match_pattern_char (pat, string) 3488 char *pat, *string; 3489{ 3490 char c; 3491 3492 if (*string == 0) 3493 return (0); 3494 3495 switch (c = *pat++) 3496 { 3497 default: 3498 return (*string == c); 3499 case '\\': 3500 return (*string == *pat); 3501 case '?': 3502 return (*pat == LPAREN ? 1 : (*string != '\0')); 3503 case '*': 3504 return (1); 3505 case '+': 3506 case '!': 3507 case '@': 3508 return (*pat == LPAREN ? 1 : (*string == c)); 3509 case '[': 3510 return (*string != '\0'); 3511 } 3512} 3513 3514/* Match PAT anywhere in STRING and return the match boundaries. 3515 This returns 1 in case of a successful match, 0 otherwise. SP 3516 and EP are pointers into the string where the match begins and 3517 ends, respectively. MTYPE controls what kind of match is attempted. 3518 MATCH_BEG and MATCH_END anchor the match at the beginning and end 3519 of the string, respectively. The longest match is returned. */ 3520static int 3521match_upattern (string, pat, mtype, sp, ep) 3522 char *string, *pat; 3523 int mtype; 3524 char **sp, **ep; 3525{ 3526 int c, len; 3527 register char *p, *p1, *npat; 3528 char *end; 3529 3530 /* If the pattern doesn't match anywhere in the string, go ahead and 3531 short-circuit right away. A minor optimization, saves a bunch of 3532 unnecessary calls to strmatch (up to N calls for a string of N 3533 characters) if the match is unsuccessful. To preserve the semantics 3534 of the substring matches below, we make sure that the pattern has 3535 `*' as first and last character, making a new pattern if necessary. */ 3536 /* XXX - check this later if I ever implement `**' with special meaning, 3537 since this will potentially result in `**' at the beginning or end */ 3538 len = STRLEN (pat); 3539 if (pat[0] != '*' || pat[len - 1] != '*') 3540 { 3541 p = npat = (char *)xmalloc (len + 3); 3542 p1 = pat; 3543 if (*p1 != '*') 3544 *p++ = '*'; 3545 while (*p1) 3546 *p++ = *p1++; 3547 if (p1[-1] != '*' || p[-2] == '\\') 3548 *p++ = '*'; 3549 *p = '\0'; 3550 } 3551 else 3552 npat = pat; 3553 c = strmatch (npat, string, FNMATCH_EXTFLAG); 3554 if (npat != pat) 3555 free (npat); 3556 if (c == FNM_NOMATCH) 3557 return (0); 3558 3559 len = STRLEN (string); 3560 end = string + len; 3561 3562 switch (mtype) 3563 { 3564 case MATCH_ANY: 3565 for (p = string; p <= end; p++) 3566 { 3567 if (match_pattern_char (pat, p)) 3568 { 3569 for (p1 = end; p1 >= p; p1--) 3570 { 3571 c = *p1; *p1 = '\0'; 3572 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0) 3573 { 3574 *p1 = c; 3575 *sp = p; 3576 *ep = p1; 3577 return 1; 3578 } 3579 *p1 = c; 3580 } 3581 } 3582 } 3583 3584 return (0); 3585 3586 case MATCH_BEG: 3587 if (match_pattern_char (pat, string) == 0) 3588 return (0); 3589 3590 for (p = end; p >= string; p--) 3591 { 3592 c = *p; *p = '\0'; 3593 if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0) 3594 { 3595 *p = c; 3596 *sp = string; 3597 *ep = p; 3598 return 1; 3599 } 3600 *p = c; 3601 } 3602 3603 return (0); 3604 3605 case MATCH_END: 3606 for (p = string; p <= end; p++) 3607 { 3608 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0) 3609 { 3610 *sp = p; 3611 *ep = end; 3612 return 1; 3613 } 3614 3615 } 3616 3617 return (0); 3618 } 3619 3620 return (0); 3621} 3622 3623#if defined (HANDLE_MULTIBYTE) 3624/* Return 1 of the first character of WSTRING could match the first 3625 character of pattern WPAT. Wide character version. */ 3626static int 3627match_pattern_wchar (wpat, wstring) 3628 wchar_t *wpat, *wstring; 3629{ 3630 wchar_t wc; 3631 3632 if (*wstring == 0) 3633 return (0); 3634 3635 switch (wc = *wpat++) 3636 { 3637 default: 3638 return (*wstring == wc); 3639 case L'\\': 3640 return (*wstring == *wpat); 3641 case L'?': 3642 return (*wpat == LPAREN ? 1 : (*wstring != L'\0')); 3643 case L'*': 3644 return (1); 3645 case L'+': 3646 case L'!': 3647 case L'@': 3648 return (*wpat == LPAREN ? 1 : (*wstring == wc)); 3649 case L'[': 3650 return (*wstring != L'\0'); 3651 } 3652} 3653 3654/* Match WPAT anywhere in WSTRING and return the match boundaries. 3655 This returns 1 in case of a successful match, 0 otherwise. Wide 3656 character version. */ 3657static int 3658match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep) 3659 wchar_t *wstring; 3660 char **indices; 3661 size_t wstrlen; 3662 wchar_t *wpat; 3663 int mtype; 3664 char **sp, **ep; 3665{ 3666 wchar_t wc, *wp, *nwpat, *wp1; 3667 int len; 3668#if 0 3669 size_t n, n1; /* Apple's gcc seems to miscompile this badly */ 3670#else 3671 int n, n1; 3672#endif 3673 3674 /* If the pattern doesn't match anywhere in the string, go ahead and 3675 short-circuit right away. A minor optimization, saves a bunch of 3676 unnecessary calls to strmatch (up to N calls for a string of N 3677 characters) if the match is unsuccessful. To preserve the semantics 3678 of the substring matches below, we make sure that the pattern has 3679 `*' as first and last character, making a new pattern if necessary. */ 3680 /* XXX - check this later if I ever implement `**' with special meaning, 3681 since this will potentially result in `**' at the beginning or end */ 3682 len = wcslen (wpat); 3683 if (wpat[0] != L'*' || wpat[len - 1] != L'*') 3684 { 3685 wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t)); 3686 wp1 = wpat; 3687 if (*wp1 != L'*') 3688 *wp++ = L'*'; 3689 while (*wp1 != L'\0') 3690 *wp++ = *wp1++; 3691 if (wp1[-1] != L'*' || wp1[-2] == L'\\') 3692 *wp++ = L'*'; 3693 *wp = '\0'; 3694 } 3695 else 3696 nwpat = wpat; 3697 len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG); 3698 if (nwpat != wpat) 3699 free (nwpat); 3700 if (len == FNM_NOMATCH) 3701 return (0); 3702 3703 switch (mtype) 3704 { 3705 case MATCH_ANY: 3706 for (n = 0; n <= wstrlen; n++) 3707 { 3708 if (match_pattern_wchar (wpat, wstring + n)) 3709 { 3710 for (n1 = wstrlen; n1 >= n; n1--) 3711 { 3712 wc = wstring[n1]; wstring[n1] = L'\0'; 3713 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0) 3714 { 3715 wstring[n1] = wc; 3716 *sp = indices[n]; 3717 *ep = indices[n1]; 3718 return 1; 3719 } 3720 wstring[n1] = wc; 3721 } 3722 } 3723 } 3724 3725 return (0); 3726 3727 case MATCH_BEG: 3728 if (match_pattern_wchar (wpat, wstring) == 0) 3729 return (0); 3730 3731 for (n = wstrlen; n >= 0; n--) 3732 { 3733 wc = wstring[n]; wstring[n] = L'\0'; 3734 if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG) == 0) 3735 { 3736 wstring[n] = wc; 3737 *sp = indices[0]; 3738 *ep = indices[n]; 3739 return 1; 3740 } 3741 wstring[n] = wc; 3742 } 3743 3744 return (0); 3745 3746 case MATCH_END: 3747 for (n = 0; n <= wstrlen; n++) 3748 { 3749 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0) 3750 { 3751 *sp = indices[n]; 3752 *ep = indices[wstrlen]; 3753 return 1; 3754 } 3755 } 3756 3757 return (0); 3758 } 3759 3760 return (0); 3761} 3762#endif /* HANDLE_MULTIBYTE */ 3763 3764static int 3765match_pattern (string, pat, mtype, sp, ep) 3766 char *string, *pat; 3767 int mtype; 3768 char **sp, **ep; 3769{ 3770#if defined (HANDLE_MULTIBYTE) 3771 int ret; 3772 size_t n; 3773 wchar_t *wstring, *wpat; 3774 char **indices; 3775#endif 3776 3777 if (string == 0 || *string == 0 || pat == 0 || *pat == 0) 3778 return (0); 3779 3780#if defined (HANDLE_MULTIBYTE) 3781 if (MB_CUR_MAX > 1) 3782 { 3783 n = xdupmbstowcs (&wpat, NULL, pat); 3784 if (n == (size_t)-1) 3785 return (match_upattern (string, pat, mtype, sp, ep)); 3786 n = xdupmbstowcs (&wstring, &indices, string); 3787 if (n == (size_t)-1) 3788 { 3789 free (wpat); 3790 return (match_upattern (string, pat, mtype, sp, ep)); 3791 } 3792 ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep); 3793 3794 free (wpat); 3795 free (wstring); 3796 free (indices); 3797 3798 return (ret); 3799 } 3800 else 3801#endif 3802 return (match_upattern (string, pat, mtype, sp, ep)); 3803} 3804 3805static int 3806getpatspec (c, value) 3807 int c; 3808 char *value; 3809{ 3810 if (c == '#') 3811 return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT); 3812 else /* c == '%' */ 3813 return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT); 3814} 3815 3816/* Posix.2 says that the WORD should be run through tilde expansion, 3817 parameter expansion, command substitution and arithmetic expansion. 3818 This leaves the result quoted, so quote_string_for_globbing () has 3819 to be called to fix it up for strmatch (). If QUOTED is non-zero, 3820 it means that the entire expression was enclosed in double quotes. 3821 This means that quoting characters in the pattern do not make any 3822 special pattern characters quoted. For example, the `*' in the 3823 following retains its special meaning: "${foo#'*'}". */ 3824static char * 3825getpattern (value, quoted, expandpat) 3826 char *value; 3827 int quoted, expandpat; 3828{ 3829 char *pat, *tword; 3830 WORD_LIST *l; 3831#if 0 3832 int i; 3833#endif 3834 3835 /* There is a problem here: how to handle single or double quotes in the 3836 pattern string when the whole expression is between double quotes? 3837 POSIX.2 says that enclosing double quotes do not cause the pattern to 3838 be quoted, but does that leave us a problem with @ and array[@] and their 3839 expansions inside a pattern? */ 3840#if 0 3841 if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword) 3842 { 3843 i = 0; 3844 pat = string_extract_double_quoted (tword, &i, 1); 3845 free (tword); 3846 tword = pat; 3847 } 3848#endif 3849 3850 /* expand_string_for_rhs () leaves WORD quoted and does not perform 3851 word splitting. */ 3852 l = *value ? expand_string_for_rhs (value, 3853 (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted, 3854 (int *)NULL, (int *)NULL) 3855 : (WORD_LIST *)0; 3856 pat = string_list (l); 3857 dispose_words (l); 3858 if (pat) 3859 { 3860 tword = quote_string_for_globbing (pat, QGLOB_CVTNULL); 3861 free (pat); 3862 pat = tword; 3863 } 3864 return (pat); 3865} 3866 3867#if 0 3868/* Handle removing a pattern from a string as a result of ${name%[%]value} 3869 or ${name#[#]value}. */ 3870static char * 3871variable_remove_pattern (value, pattern, patspec, quoted) 3872 char *value, *pattern; 3873 int patspec, quoted; 3874{ 3875 char *tword; 3876 3877 tword = remove_pattern (value, pattern, patspec); 3878 3879 return (tword); 3880} 3881#endif 3882 3883static char * 3884list_remove_pattern (list, pattern, patspec, itype, quoted) 3885 WORD_LIST *list; 3886 char *pattern; 3887 int patspec, itype, quoted; 3888{ 3889 WORD_LIST *new, *l; 3890 WORD_DESC *w; 3891 char *tword; 3892 3893 for (new = (WORD_LIST *)NULL, l = list; l; l = l->next) 3894 { 3895 tword = remove_pattern (l->word->word, pattern, patspec); 3896 w = alloc_word_desc (); 3897 w->word = tword ? tword : savestring (""); 3898 new = make_word_list (w, new); 3899 } 3900 3901 l = REVERSE_LIST (new, WORD_LIST *); 3902 if (itype == '*') 3903 tword = (quoted & Q_DOUBLE_QUOTES) ? string_list_dollar_star (l) : string_list (l); 3904 else 3905 tword = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (l) : l); 3906 3907 dispose_words (l); 3908 return (tword); 3909} 3910 3911static char * 3912parameter_list_remove_pattern (itype, pattern, patspec, quoted) 3913 int itype; 3914 char *pattern; 3915 int patspec, quoted; 3916{ 3917 char *ret; 3918 WORD_LIST *list; 3919 3920 list = list_rest_of_args (); 3921 if (list == 0) 3922 return ((char *)NULL); 3923 ret = list_remove_pattern (list, pattern, patspec, itype, quoted); 3924 dispose_words (list); 3925 return (ret); 3926} 3927 3928#if defined (ARRAY_VARS) 3929static char * 3930array_remove_pattern (a, pattern, patspec, varname, quoted) 3931 ARRAY *a; 3932 char *pattern; 3933 int patspec; 3934 char *varname; /* so we can figure out how it's indexed */ 3935 int quoted; 3936{ 3937 int itype; 3938 char *ret; 3939 WORD_LIST *list; 3940 SHELL_VAR *v; 3941 3942 /* compute itype from varname here */ 3943 v = array_variable_part (varname, &ret, 0); 3944 itype = ret[0]; 3945 3946 list = array_to_word_list (a); 3947 if (list == 0) 3948 return ((char *)NULL); 3949 ret = list_remove_pattern (list, pattern, patspec, itype, quoted); 3950 dispose_words (list); 3951 3952 return ret; 3953} 3954#endif /* ARRAY_VARS */ 3955 3956static char * 3957parameter_brace_remove_pattern (varname, value, patstr, rtype, quoted) 3958 char *varname, *value, *patstr; 3959 int rtype, quoted; 3960{ 3961 int vtype, patspec, starsub; 3962 char *temp1, *val, *pattern; 3963 SHELL_VAR *v; 3964 3965 if (value == 0) 3966 return ((char *)NULL); 3967 3968 this_command_name = varname; 3969 3970 vtype = get_var_and_type (varname, value, quoted, &v, &val); 3971 if (vtype == -1) 3972 return ((char *)NULL); 3973 3974 starsub = vtype & VT_STARSUB; 3975 vtype &= ~VT_STARSUB; 3976 3977 patspec = getpatspec (rtype, patstr); 3978 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT) 3979 patstr++; 3980 3981 /* Need to pass getpattern newly-allocated memory in case of expansion -- 3982 the expansion code will free the passed string on an error. */ 3983 temp1 = savestring (patstr); 3984 pattern = getpattern (temp1, quoted, 1); 3985 free (temp1); 3986 3987 temp1 = (char *)NULL; /* shut up gcc */ 3988 switch (vtype) 3989 { 3990 case VT_VARIABLE: 3991 case VT_ARRAYMEMBER: 3992 temp1 = remove_pattern (val, pattern, patspec); 3993 if (vtype == VT_VARIABLE) 3994 FREE (val); 3995 if (temp1) 3996 { 3997 val = quote_escapes (temp1); 3998 free (temp1); 3999 temp1 = val; 4000 } 4001 break; 4002#if defined (ARRAY_VARS) 4003 case VT_ARRAYVAR: 4004 temp1 = array_remove_pattern (array_cell (v), pattern, patspec, varname, quoted); 4005 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0)) 4006 { 4007 val = quote_escapes (temp1); 4008 free (temp1); 4009 temp1 = val; 4010 } 4011 break; 4012#endif 4013 case VT_POSPARMS: 4014 temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted); 4015 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0)) 4016 { 4017 val = quote_escapes (temp1); 4018 free (temp1); 4019 temp1 = val; 4020 } 4021 break; 4022 } 4023 4024 FREE (pattern); 4025 return temp1; 4026} 4027 4028/******************************************* 4029 * * 4030 * Functions to expand WORD_DESCs * 4031 * * 4032 *******************************************/ 4033 4034/* Expand WORD, performing word splitting on the result. This does 4035 parameter expansion, command substitution, arithmetic expansion, 4036 word splitting, and quote removal. */ 4037 4038WORD_LIST * 4039expand_word (word, quoted) 4040 WORD_DESC *word; 4041 int quoted; 4042{ 4043 WORD_LIST *result, *tresult; 4044 4045 tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL); 4046 result = word_list_split (tresult); 4047 dispose_words (tresult); 4048 return (result ? dequote_list (result) : result); 4049} 4050 4051/* Expand WORD, but do not perform word splitting on the result. This 4052 does parameter expansion, command substitution, arithmetic expansion, 4053 and quote removal. */ 4054WORD_LIST * 4055expand_word_unsplit (word, quoted) 4056 WORD_DESC *word; 4057 int quoted; 4058{ 4059 WORD_LIST *result; 4060 4061 expand_no_split_dollar_star = 1; 4062 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL); 4063 expand_no_split_dollar_star = 0; 4064 4065 return (result ? dequote_list (result) : result); 4066} 4067 4068/* Perform shell expansions on WORD, but do not perform word splitting or 4069 quote removal on the result. */ 4070WORD_LIST * 4071expand_word_leave_quoted (word, quoted) 4072 WORD_DESC *word; 4073 int quoted; 4074{ 4075 return (call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL)); 4076} 4077 4078#if defined (PROCESS_SUBSTITUTION) 4079 4080/*****************************************************************/ 4081/* */ 4082/* Hacking Process Substitution */ 4083/* */ 4084/*****************************************************************/ 4085 4086#if !defined (HAVE_DEV_FD) 4087/* Named pipes must be removed explicitly with `unlink'. This keeps a list 4088 of FIFOs the shell has open. unlink_fifo_list will walk the list and 4089 unlink all of them. add_fifo_list adds the name of an open FIFO to the 4090 list. NFIFO is a count of the number of FIFOs in the list. */ 4091#define FIFO_INCR 20 4092 4093struct temp_fifo { 4094 char *file; 4095 pid_t proc; 4096}; 4097 4098static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL; 4099static int nfifo; 4100static int fifo_list_size; 4101 4102static void 4103add_fifo_list (pathname) 4104 char *pathname; 4105{ 4106 if (nfifo >= fifo_list_size - 1) 4107 { 4108 fifo_list_size += FIFO_INCR; 4109 fifo_list = (struct temp_fifo *)xrealloc (fifo_list, 4110 fifo_list_size * sizeof (struct temp_fifo)); 4111 } 4112 4113 fifo_list[nfifo].file = savestring (pathname); 4114 nfifo++; 4115} 4116 4117void 4118unlink_fifo_list () 4119{ 4120 int saved, i, j; 4121 4122 if (nfifo == 0) 4123 return; 4124 4125 for (i = saved = 0; i < nfifo; i++) 4126 { 4127 if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1)) 4128 { 4129 unlink (fifo_list[i].file); 4130 free (fifo_list[i].file); 4131 fifo_list[i].file = (char *)NULL; 4132 fifo_list[i].proc = -1; 4133 } 4134 else 4135 saved++; 4136 } 4137 4138 /* If we didn't remove some of the FIFOs, compact the list. */ 4139 if (saved) 4140 { 4141 for (i = j = 0; i < nfifo; i++) 4142 if (fifo_list[i].file) 4143 { 4144 fifo_list[j].file = fifo_list[i].file; 4145 fifo_list[j].proc = fifo_list[i].proc; 4146 j++; 4147 } 4148 nfifo = j; 4149 } 4150 else 4151 nfifo = 0; 4152} 4153 4154int 4155fifos_pending () 4156{ 4157 return nfifo; 4158} 4159 4160static char * 4161make_named_pipe () 4162{ 4163 char *tname; 4164 4165 tname = sh_mktmpname ("sh-np", MT_USERANDOM); 4166 if (mkfifo (tname, 0600) < 0) 4167 { 4168 free (tname); 4169 return ((char *)NULL); 4170 } 4171 4172 add_fifo_list (tname); 4173 return (tname); 4174} 4175 4176#else /* HAVE_DEV_FD */ 4177 4178/* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell 4179 has open to children. NFDS is a count of the number of bits currently 4180 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number 4181 of open files. */ 4182static char *dev_fd_list = (char *)NULL; 4183static int nfds; 4184static int totfds; /* The highest possible number of open files. */ 4185 4186static void 4187add_fifo_list (fd) 4188 int fd; 4189{ 4190 if (!dev_fd_list || fd >= totfds) 4191 { 4192 int ofds; 4193 4194 ofds = totfds; 4195 totfds = getdtablesize (); 4196 if (totfds < 0 || totfds > 256) 4197 totfds = 256; 4198 if (fd > totfds) 4199 totfds = fd + 2; 4200 4201 dev_fd_list = (char *)xrealloc (dev_fd_list, totfds); 4202 memset (dev_fd_list + ofds, '\0', totfds - ofds); 4203 } 4204 4205 dev_fd_list[fd] = 1; 4206 nfds++; 4207} 4208 4209int 4210fifos_pending () 4211{ 4212 return 0; /* used for cleanup; not needed with /dev/fd */ 4213} 4214 4215void 4216unlink_fifo_list () 4217{ 4218 register int i; 4219 4220 if (nfds == 0) 4221 return; 4222 4223 for (i = 0; nfds && i < totfds; i++) 4224 if (dev_fd_list[i]) 4225 { 4226 close (i); 4227 dev_fd_list[i] = 0; 4228 nfds--; 4229 } 4230 4231 nfds = 0; 4232} 4233 4234#if defined (NOTDEF) 4235print_dev_fd_list () 4236{ 4237 register int i; 4238 4239 fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ()); 4240 fflush (stderr); 4241 4242 for (i = 0; i < totfds; i++) 4243 { 4244 if (dev_fd_list[i]) 4245 fprintf (stderr, " %d", i); 4246 } 4247 fprintf (stderr, "\n"); 4248} 4249#endif /* NOTDEF */ 4250 4251static char * 4252make_dev_fd_filename (fd) 4253 int fd; 4254{ 4255 char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p; 4256 4257 ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 4); 4258 4259 strcpy (ret, DEV_FD_PREFIX); 4260 p = inttostr (fd, intbuf, sizeof (intbuf)); 4261 strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p); 4262 4263 add_fifo_list (fd); 4264 return (ret); 4265} 4266 4267#endif /* HAVE_DEV_FD */ 4268 4269/* Return a filename that will open a connection to the process defined by 4270 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return 4271 a filename in /dev/fd corresponding to a descriptor that is one of the 4272 ends of the pipe. If not defined, we use named pipes on systems that have 4273 them. Systems without /dev/fd and named pipes are out of luck. 4274 4275 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or 4276 use the read end of the pipe and dup that file descriptor to fd 0 in 4277 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for 4278 writing or use the write end of the pipe in the child, and dup that 4279 file descriptor to fd 1 in the child. The parent does the opposite. */ 4280 4281static char * 4282process_substitute (string, open_for_read_in_child) 4283 char *string; 4284 int open_for_read_in_child; 4285{ 4286 char *pathname; 4287 int fd, result; 4288 pid_t old_pid, pid; 4289#if defined (HAVE_DEV_FD) 4290 int parent_pipe_fd, child_pipe_fd; 4291 int fildes[2]; 4292#endif /* HAVE_DEV_FD */ 4293#if defined (JOB_CONTROL) 4294 pid_t old_pipeline_pgrp; 4295#endif 4296 4297 if (!string || !*string || wordexp_only) 4298 return ((char *)NULL); 4299 4300#if !defined (HAVE_DEV_FD) 4301 pathname = make_named_pipe (); 4302#else /* HAVE_DEV_FD */ 4303 if (pipe (fildes) < 0) 4304 { 4305 sys_error (_("cannot make pipe for process substitution")); 4306 return ((char *)NULL); 4307 } 4308 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of 4309 the pipe in the parent, otherwise the read end. */ 4310 parent_pipe_fd = fildes[open_for_read_in_child]; 4311 child_pipe_fd = fildes[1 - open_for_read_in_child]; 4312 /* Move the parent end of the pipe to some high file descriptor, to 4313 avoid clashes with FDs used by the script. */ 4314 parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64); 4315 4316 pathname = make_dev_fd_filename (parent_pipe_fd); 4317#endif /* HAVE_DEV_FD */ 4318 4319 if (!pathname) 4320 { 4321 sys_error (_("cannot make pipe for process substitution")); 4322 return ((char *)NULL); 4323 } 4324 4325 old_pid = last_made_pid; 4326 4327#if defined (JOB_CONTROL) 4328 old_pipeline_pgrp = pipeline_pgrp; 4329 pipeline_pgrp = shell_pgrp; 4330 save_pipeline (1); 4331#endif /* JOB_CONTROL */ 4332 4333 pid = make_child ((char *)NULL, 1); 4334 if (pid == 0) 4335 { 4336 reset_terminating_signals (); /* XXX */ 4337 free_pushed_string_input (); 4338 /* Cancel traps, in trap.c. */ 4339 restore_original_signals (); 4340 setup_async_signals (); 4341 subshell_environment |= SUBSHELL_COMSUB; 4342 } 4343 4344#if defined (JOB_CONTROL) 4345 set_sigchld_handler (); 4346 stop_making_children (); 4347 pipeline_pgrp = old_pipeline_pgrp; 4348#endif /* JOB_CONTROL */ 4349 4350 if (pid < 0) 4351 { 4352 sys_error (_("cannot make child for process substitution")); 4353 free (pathname); 4354#if defined (HAVE_DEV_FD) 4355 close (parent_pipe_fd); 4356 close (child_pipe_fd); 4357#endif /* HAVE_DEV_FD */ 4358 return ((char *)NULL); 4359 } 4360 4361 if (pid > 0) 4362 { 4363#if defined (JOB_CONTROL) 4364 restore_pipeline (1); 4365#endif 4366 4367#if !defined (HAVE_DEV_FD) 4368 fifo_list[nfifo-1].proc = pid; 4369#endif 4370 4371 last_made_pid = old_pid; 4372 4373#if defined (JOB_CONTROL) && defined (PGRP_PIPE) 4374 close_pgrp_pipe (); 4375#endif /* JOB_CONTROL && PGRP_PIPE */ 4376 4377#if defined (HAVE_DEV_FD) 4378 close (child_pipe_fd); 4379#endif /* HAVE_DEV_FD */ 4380 4381 return (pathname); 4382 } 4383 4384 set_sigint_handler (); 4385 4386#if defined (JOB_CONTROL) 4387 set_job_control (0); 4388#endif /* JOB_CONTROL */ 4389 4390#if !defined (HAVE_DEV_FD) 4391 /* Open the named pipe in the child. */ 4392 fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY); 4393 if (fd < 0) 4394 { 4395 /* Two separate strings for ease of translation. */ 4396 if (open_for_read_in_child) 4397 sys_error (_("cannot open named pipe %s for reading"), pathname); 4398 else 4399 sys_error (_("cannot open named pipe %s for writing"), pathname); 4400 4401 exit (127); 4402 } 4403 if (open_for_read_in_child) 4404 { 4405 if (sh_unset_nodelay_mode (fd) < 0) 4406 { 4407 sys_error (_("cannout reset nodelay mode for fd %d"), fd); 4408 exit (127); 4409 } 4410 } 4411#else /* HAVE_DEV_FD */ 4412 fd = child_pipe_fd; 4413#endif /* HAVE_DEV_FD */ 4414 4415 if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0) 4416 { 4417 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname, 4418 open_for_read_in_child ? 0 : 1); 4419 exit (127); 4420 } 4421 4422 if (fd != (open_for_read_in_child ? 0 : 1)) 4423 close (fd); 4424 4425 /* Need to close any files that this process has open to pipes inherited 4426 from its parent. */ 4427 if (current_fds_to_close) 4428 { 4429 close_fd_bitmap (current_fds_to_close); 4430 current_fds_to_close = (struct fd_bitmap *)NULL; 4431 } 4432 4433#if defined (HAVE_DEV_FD) 4434 /* Make sure we close the parent's end of the pipe and clear the slot 4435 in the fd list so it is not closed later, if reallocated by, for 4436 instance, pipe(2). */ 4437 close (parent_pipe_fd); 4438 dev_fd_list[parent_pipe_fd] = 0; 4439#endif /* HAVE_DEV_FD */ 4440 4441 result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST)); 4442 4443#if !defined (HAVE_DEV_FD) 4444 /* Make sure we close the named pipe in the child before we exit. */ 4445 close (open_for_read_in_child ? 0 : 1); 4446#endif /* !HAVE_DEV_FD */ 4447 4448 exit (result); 4449 /*NOTREACHED*/ 4450} 4451#endif /* PROCESS_SUBSTITUTION */ 4452 4453/***********************************/ 4454/* */ 4455/* Command Substitution */ 4456/* */ 4457/***********************************/ 4458 4459static char * 4460read_comsub (fd, quoted) 4461 int fd, quoted; 4462{ 4463 char *istring, buf[128], *bufp; 4464 int istring_index, istring_size, c; 4465 ssize_t bufn; 4466 4467 istring = (char *)NULL; 4468 istring_index = istring_size = bufn = 0; 4469 4470#ifdef __CYGWIN__ 4471 setmode (fd, O_TEXT); /* we don't want CR/LF, we want Unix-style */ 4472#endif 4473 4474 /* Read the output of the command through the pipe. */ 4475 while (1) 4476 { 4477 if (fd < 0) 4478 break; 4479 if (--bufn <= 0) 4480 { 4481 bufn = zread (fd, buf, sizeof (buf)); 4482 if (bufn <= 0) 4483 break; 4484 bufp = buf; 4485 } 4486 c = *bufp++; 4487 4488 if (c == 0) 4489 { 4490#if 0 4491 internal_warning ("read_comsub: ignored null byte in input"); 4492#endif 4493 continue; 4494 } 4495 4496 /* Add the character to ISTRING, possibly after resizing it. */ 4497 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE); 4498 4499 /* This is essentially quote_string inline */ 4500 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */) 4501 istring[istring_index++] = CTLESC; 4502 /* Escape CTLESC and CTLNUL in the output to protect those characters 4503 from the rest of the word expansions (word splitting and globbing.) 4504 This is essentially quote_escapes inline. */ 4505 else if (c == CTLESC) 4506 istring[istring_index++] = CTLESC; 4507 else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0))) 4508 istring[istring_index++] = CTLESC; 4509 4510 istring[istring_index++] = c; 4511 4512#if 0 4513#if defined (__CYGWIN__) 4514 if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r') 4515 { 4516 istring_index--; 4517 istring[istring_index - 1] = '\n'; 4518 } 4519#endif 4520#endif 4521 } 4522 4523 if (istring) 4524 istring[istring_index] = '\0'; 4525 4526 /* If we read no output, just return now and save ourselves some 4527 trouble. */ 4528 if (istring_index == 0) 4529 { 4530 FREE (istring); 4531 return (char *)NULL; 4532 } 4533 4534 /* Strip trailing newlines from the output of the command. */ 4535 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) 4536 { 4537 while (istring_index > 0) 4538 { 4539 if (istring[istring_index - 1] == '\n') 4540 { 4541 --istring_index; 4542 4543 /* If the newline was quoted, remove the quoting char. */ 4544 if (istring[istring_index - 1] == CTLESC) 4545 --istring_index; 4546 } 4547 else 4548 break; 4549 } 4550 istring[istring_index] = '\0'; 4551 } 4552 else 4553 strip_trailing (istring, istring_index - 1, 1); 4554 4555 return istring; 4556} 4557 4558/* Perform command substitution on STRING. This returns a string, 4559 possibly quoted. */ 4560char * 4561command_substitute (string, quoted) 4562 char *string; 4563 int quoted; 4564{ 4565 pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid; 4566 char *istring; 4567 int result, fildes[2], function_value, pflags, rc; 4568 4569 istring = (char *)NULL; 4570 4571 /* Don't fork () if there is no need to. In the case of no command to 4572 run, just return NULL. */ 4573 if (!string || !*string || (string[0] == '\n' && !string[1])) 4574 return ((char *)NULL); 4575 4576 if (wordexp_only && read_but_dont_execute) 4577 { 4578 last_command_exit_value = 125; 4579 jump_to_top_level (EXITPROG); 4580 } 4581 4582 /* We're making the assumption here that the command substitution will 4583 eventually run a command from the file system. Since we'll run 4584 maybe_make_export_env in this subshell before executing that command, 4585 the parent shell and any other shells it starts will have to remake 4586 the environment. If we make it before we fork, other shells won't 4587 have to. Don't bother if we have any temporary variable assignments, 4588 though, because the export environment will be remade after this 4589 command completes anyway, but do it if all the words to be expanded 4590 are variable assignments. */ 4591 if (subst_assign_varlist == 0 || garglist == 0) 4592 maybe_make_export_env (); /* XXX */ 4593 4594 /* Flags to pass to parse_and_execute() */ 4595 pflags = interactive ? SEVAL_RESETLINE : 0; 4596 4597 /* Pipe the output of executing STRING into the current shell. */ 4598 if (pipe (fildes) < 0) 4599 { 4600 sys_error (_("cannot make pipe for command substitution")); 4601 goto error_exit; 4602 } 4603 4604 old_pid = last_made_pid; 4605#if defined (JOB_CONTROL) 4606 old_pipeline_pgrp = pipeline_pgrp; 4607 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */ 4608 if ((subshell_environment & SUBSHELL_PIPE) == 0) 4609 pipeline_pgrp = shell_pgrp; 4610 cleanup_the_pipeline (); 4611#endif /* JOB_CONTROL */ 4612 4613 old_async_pid = last_asynchronous_pid; 4614#if 0 4615 pid = make_child ((char *)NULL, 0); 4616#else 4617 pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC); 4618#endif 4619 last_asynchronous_pid = old_async_pid; 4620 4621 if (pid == 0) 4622 /* Reset the signal handlers in the child, but don't free the 4623 trap strings. */ 4624 reset_signal_handlers (); 4625 4626#if defined (JOB_CONTROL) 4627 set_sigchld_handler (); 4628 stop_making_children (); 4629 if (pid != 0) 4630 pipeline_pgrp = old_pipeline_pgrp; 4631#else 4632 stop_making_children (); 4633#endif /* JOB_CONTROL */ 4634 4635 if (pid < 0) 4636 { 4637 sys_error (_("cannot make child for command substitution")); 4638 error_exit: 4639 4640 FREE (istring); 4641 close (fildes[0]); 4642 close (fildes[1]); 4643 return ((char *)NULL); 4644 } 4645 4646 if (pid == 0) 4647 { 4648 set_sigint_handler (); /* XXX */ 4649 4650 free_pushed_string_input (); 4651 4652 if (dup2 (fildes[1], 1) < 0) 4653 { 4654 sys_error (_("command_substitute: cannot duplicate pipe as fd 1")); 4655 exit (EXECUTION_FAILURE); 4656 } 4657 4658 /* If standard output is closed in the parent shell 4659 (such as after `exec >&-'), file descriptor 1 will be 4660 the lowest available file descriptor, and end up in 4661 fildes[0]. This can happen for stdin and stderr as well, 4662 but stdout is more important -- it will cause no output 4663 to be generated from this command. */ 4664 if ((fildes[1] != fileno (stdin)) && 4665 (fildes[1] != fileno (stdout)) && 4666 (fildes[1] != fileno (stderr))) 4667 close (fildes[1]); 4668 4669 if ((fildes[0] != fileno (stdin)) && 4670 (fildes[0] != fileno (stdout)) && 4671 (fildes[0] != fileno (stderr))) 4672 close (fildes[0]); 4673 4674 /* The currently executing shell is not interactive. */ 4675 interactive = 0; 4676 4677 /* This is a subshell environment. */ 4678 subshell_environment |= SUBSHELL_COMSUB; 4679 4680 /* When not in POSIX mode, command substitution does not inherit 4681 the -e flag. */ 4682 if (posixly_correct == 0) 4683 exit_immediately_on_error = 0; 4684 4685 remove_quoted_escapes (string); 4686 4687 startup_state = 2; /* see if we can avoid a fork */ 4688 /* Give command substitution a place to jump back to on failure, 4689 so we don't go back up to main (). */ 4690 result = setjmp (top_level); 4691 4692 /* If we're running a command substitution inside a shell function, 4693 trap `return' so we don't return from the function in the subshell 4694 and go off to never-never land. */ 4695 if (result == 0 && return_catch_flag) 4696 function_value = setjmp (return_catch); 4697 else 4698 function_value = 0; 4699 4700 if (result == ERREXIT) 4701 rc = last_command_exit_value; 4702 else if (result == EXITPROG) 4703 rc = last_command_exit_value; 4704 else if (result) 4705 rc = EXECUTION_FAILURE; 4706 else if (function_value) 4707 rc = return_catch_value; 4708 else 4709 { 4710 subshell_level++; 4711 rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST); 4712 subshell_level--; 4713 } 4714 4715 last_command_exit_value = rc; 4716 rc = run_exit_trap (); 4717#if defined (PROCESS_SUBSTITUTION) 4718 unlink_fifo_list (); 4719#endif 4720 exit (rc); 4721 } 4722 else 4723 { 4724#if defined (JOB_CONTROL) && defined (PGRP_PIPE) 4725 close_pgrp_pipe (); 4726#endif /* JOB_CONTROL && PGRP_PIPE */ 4727 4728 close (fildes[1]); 4729 4730 istring = read_comsub (fildes[0], quoted); 4731 4732 close (fildes[0]); 4733 4734 current_command_subst_pid = pid; 4735 last_command_exit_value = wait_for (pid); 4736 last_command_subst_pid = pid; 4737 last_made_pid = old_pid; 4738 4739#if defined (JOB_CONTROL) 4740 /* If last_command_exit_value > 128, then the substituted command 4741 was terminated by a signal. If that signal was SIGINT, then send 4742 SIGINT to ourselves. This will break out of loops, for instance. */ 4743 if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT) 4744 kill (getpid (), SIGINT); 4745 4746 /* wait_for gives the terminal back to shell_pgrp. If some other 4747 process group should have it, give it away to that group here. 4748 pipeline_pgrp is non-zero only while we are constructing a 4749 pipline, so what we are concerned about is whether or not that 4750 pipeline was started in the background. A pipeline started in 4751 the background should never get the tty back here. */ 4752#if 0 4753 if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid) 4754#else 4755 if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0) 4756#endif 4757 give_terminal_to (pipeline_pgrp, 0); 4758#endif /* JOB_CONTROL */ 4759 4760 return (istring); 4761 } 4762} 4763 4764/******************************************************** 4765 * * 4766 * Utility functions for parameter expansion * 4767 * * 4768 ********************************************************/ 4769 4770#if defined (ARRAY_VARS) 4771 4772static arrayind_t 4773array_length_reference (s) 4774 char *s; 4775{ 4776 int len; 4777 arrayind_t ind; 4778 char *t, c; 4779 ARRAY *array; 4780 SHELL_VAR *var; 4781 4782 var = array_variable_part (s, &t, &len); 4783 4784 /* If unbound variables should generate an error, report one and return 4785 failure. */ 4786 if ((var == 0 || array_p (var) == 0) && unbound_vars_is_error) 4787 { 4788 c = *--t; 4789 *t = '\0'; 4790 err_unboundvar (s); 4791 *t = c; 4792 return (-1); 4793 } 4794 else if (var == 0) 4795 return 0; 4796 4797 /* We support a couple of expansions for variables that are not arrays. 4798 We'll return the length of the value for v[0], and 1 for v[@] or 4799 v[*]. Return 0 for everything else. */ 4800 4801 array = array_p (var) ? array_cell (var) : (ARRAY *)NULL; 4802 4803 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']') 4804 return (array_p (var) ? array_num_elements (array) : 1); 4805 4806 ind = array_expand_index (t, len); 4807 if (ind < 0) 4808 { 4809 err_badarraysub (t); 4810 return (-1); 4811 } 4812 4813 if (array_p (var)) 4814 t = array_reference (array, ind); 4815 else 4816 t = (ind == 0) ? value_cell (var) : (char *)NULL; 4817 4818 len = MB_STRLEN (t); 4819 return (len); 4820} 4821#endif /* ARRAY_VARS */ 4822 4823static int 4824valid_brace_expansion_word (name, var_is_special) 4825 char *name; 4826 int var_is_special; 4827{ 4828 if (DIGIT (*name) && all_digits (name)) 4829 return 1; 4830 else if (var_is_special) 4831 return 1; 4832#if defined (ARRAY_VARS) 4833 else if (valid_array_reference (name)) 4834 return 1; 4835#endif /* ARRAY_VARS */ 4836 else if (legal_identifier (name)) 4837 return 1; 4838 else 4839 return 0; 4840} 4841 4842static int 4843chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at) 4844 char *name; 4845 int quoted; 4846 int *quoted_dollar_atp, *contains_dollar_at; 4847{ 4848 char *temp1; 4849 4850 if (name == 0) 4851 { 4852 if (quoted_dollar_atp) 4853 *quoted_dollar_atp = 0; 4854 if (contains_dollar_at) 4855 *contains_dollar_at = 0; 4856 return 0; 4857 } 4858 4859 /* check for $@ and $* */ 4860 if (name[0] == '@' && name[1] == 0) 4861 { 4862 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) 4863 *quoted_dollar_atp = 1; 4864 if (contains_dollar_at) 4865 *contains_dollar_at = 1; 4866 return 1; 4867 } 4868 else if (name[0] == '*' && name[1] == '\0' && quoted == 0) 4869 { 4870 if (contains_dollar_at) 4871 *contains_dollar_at = 1; 4872 return 1; 4873 } 4874 4875 /* Now check for ${array[@]} and ${array[*]} */ 4876#if defined (ARRAY_VARS) 4877 else if (valid_array_reference (name)) 4878 { 4879 temp1 = xstrchr (name, '['); 4880 if (temp1 && temp1[1] == '@' && temp1[2] == ']') 4881 { 4882 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) 4883 *quoted_dollar_atp = 1; 4884 if (contains_dollar_at) 4885 *contains_dollar_at = 1; 4886 return 1; 4887 } /* [ */ 4888 /* ${array[*]}, when unquoted, should be treated like ${array[@]}, 4889 which should result in separate words even when IFS is unset. */ 4890 if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0) 4891 { 4892 if (contains_dollar_at) 4893 *contains_dollar_at = 1; 4894 return 1; 4895 } 4896 } 4897#endif 4898 return 0; 4899} 4900 4901/* Parameter expand NAME, and return a new string which is the expansion, 4902 or NULL if there was no expansion. 4903 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in 4904 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that 4905 NAME was found inside of a double-quoted expression. */ 4906static WORD_DESC * 4907parameter_brace_expand_word (name, var_is_special, quoted) 4908 char *name; 4909 int var_is_special, quoted; 4910{ 4911 WORD_DESC *ret; 4912 char *temp, *tt; 4913 intmax_t arg_index; 4914 SHELL_VAR *var; 4915 int atype, rflags; 4916 4917 ret = 0; 4918 temp = 0; 4919 rflags = 0; 4920 4921 /* Handle multiple digit arguments, as in ${11}. */ 4922 if (legal_number (name, &arg_index)) 4923 { 4924 tt = get_dollar_var_value (arg_index); 4925 if (tt) 4926 temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) 4927 ? quote_string (tt) 4928 : quote_escapes (tt); 4929 else 4930 temp = (char *)NULL; 4931 FREE (tt); 4932 } 4933 else if (var_is_special) /* ${@} */ 4934 { 4935 int sindex; 4936 tt = (char *)xmalloc (2 + strlen (name)); 4937 tt[sindex = 0] = '$'; 4938 strcpy (tt + 1, name); 4939 4940 ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL, 4941 (int *)NULL, (int *)NULL, 0); 4942 free (tt); 4943 } 4944#if defined (ARRAY_VARS) 4945 else if (valid_array_reference (name)) 4946 { 4947 temp = array_value (name, quoted, &atype); 4948 if (atype == 0 && temp) 4949 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) 4950 ? quote_string (temp) 4951 : quote_escapes (temp); 4952 else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) 4953 rflags |= W_HASQUOTEDNULL; 4954 } 4955#endif 4956 else if (var = find_variable (name)) 4957 { 4958 if (var_isset (var) && invisible_p (var) == 0) 4959 { 4960#if defined (ARRAY_VARS) 4961 temp = array_p (var) ? array_reference (array_cell (var), 0) : value_cell (var); 4962#else 4963 temp = value_cell (var); 4964#endif 4965 4966 if (temp) 4967 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) 4968 ? quote_string (temp) 4969 : quote_escapes (temp); 4970 } 4971 else 4972 temp = (char *)NULL; 4973 } 4974 else 4975 temp = (char *)NULL; 4976 4977 if (ret == 0) 4978 { 4979 ret = alloc_word_desc (); 4980 ret->word = temp; 4981 ret->flags |= rflags; 4982 } 4983 return ret; 4984} 4985 4986/* Expand an indirect reference to a variable: ${!NAME} expands to the 4987 value of the variable whose name is the value of NAME. */ 4988static WORD_DESC * 4989parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at) 4990 char *name; 4991 int var_is_special, quoted; 4992 int *quoted_dollar_atp, *contains_dollar_at; 4993{ 4994 char *temp, *t; 4995 WORD_DESC *w; 4996 4997 w = parameter_brace_expand_word (name, var_is_special, quoted); 4998 t = w->word; 4999 /* Have to dequote here if necessary */ 5000 if (t) 5001 { 5002 temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) 5003 ? dequote_string (t) 5004 : dequote_escapes (t); 5005 free (t); 5006 t = temp; 5007 } 5008 dispose_word_desc (w); 5009 5010 chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at); 5011 if (t == 0) 5012 return (WORD_DESC *)NULL; 5013 5014 w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted); 5015 free (t); 5016 5017 return w; 5018} 5019 5020/* Expand the right side of a parameter expansion of the form ${NAMEcVALUE}, 5021 depending on the value of C, the separating character. C can be one of 5022 "-", "+", or "=". QUOTED is true if the entire brace expression occurs 5023 between double quotes. */ 5024static WORD_DESC * 5025parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat) 5026 char *name, *value; 5027 int c, quoted, *qdollaratp, *hasdollarat; 5028{ 5029 WORD_DESC *w; 5030 WORD_LIST *l; 5031 char *t, *t1, *temp; 5032 int hasdol; 5033 5034 /* If the entire expression is between double quotes, we want to treat 5035 the value as a double-quoted string, with the exception that we strip 5036 embedded unescaped double quotes. */ 5037 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value) 5038 { 5039 hasdol = 0; 5040 temp = string_extract_double_quoted (value, &hasdol, 1); 5041 } 5042 else 5043 temp = value; 5044 5045 w = alloc_word_desc (); 5046 hasdol = 0; 5047 /* XXX was 0 not quoted */ 5048 l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL) 5049 : (WORD_LIST *)0; 5050 if (hasdollarat) 5051 *hasdollarat = hasdol || (l && l->next); 5052 if (temp != value) 5053 free (temp); 5054 if (l) 5055 { 5056 /* The expansion of TEMP returned something. We need to treat things 5057 slightly differently if HASDOL is non-zero. If we have "$@", the 5058 individual words have already been quoted. We need to turn them 5059 into a string with the words separated by the first character of 5060 $IFS without any additional quoting, so string_list_dollar_at won't 5061 do the right thing. We use string_list_dollar_star instead. */ 5062 temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l); 5063 5064 /* If l->next is not null, we know that TEMP contained "$@", since that 5065 is the only expansion that creates more than one word. */ 5066 if (qdollaratp && ((hasdol && quoted) || l->next)) 5067 *qdollaratp = 1; 5068 dispose_words (l); 5069 } 5070 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol) 5071 { 5072 /* The brace expansion occurred between double quotes and there was 5073 a $@ in TEMP. It does not matter if the $@ is quoted, as long as 5074 it does not expand to anything. In this case, we want to return 5075 a quoted empty string. */ 5076 temp = make_quoted_char ('\0'); 5077 w->flags |= W_HASQUOTEDNULL; 5078 } 5079 else 5080 temp = (char *)NULL; 5081 5082 if (c == '-' || c == '+') 5083 { 5084 w->word = temp; 5085 return w; 5086 } 5087 5088 /* c == '=' */ 5089 t = temp ? savestring (temp) : savestring (""); 5090 t1 = dequote_string (t); 5091 free (t); 5092#if defined (ARRAY_VARS) 5093 if (valid_array_reference (name)) 5094 assign_array_element (name, t1, 0); 5095 else 5096#endif /* ARRAY_VARS */ 5097 bind_variable (name, t1, 0); 5098 free (t1); 5099 5100 w->word = temp; 5101 return w; 5102} 5103 5104/* Deal with the right hand side of a ${name:?value} expansion in the case 5105 that NAME is null or not set. If VALUE is non-null it is expanded and 5106 used as the error message to print, otherwise a standard message is 5107 printed. */ 5108static void 5109parameter_brace_expand_error (name, value) 5110 char *name, *value; 5111{ 5112 WORD_LIST *l; 5113 char *temp; 5114 5115 if (value && *value) 5116 { 5117 l = expand_string (value, 0); 5118 temp = string_list (l); 5119 report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */ 5120 FREE (temp); 5121 dispose_words (l); 5122 } 5123 else 5124 report_error (_("%s: parameter null or not set"), name); 5125 5126 /* Free the data we have allocated during this expansion, since we 5127 are about to longjmp out. */ 5128 free (name); 5129 FREE (value); 5130} 5131 5132/* Return 1 if NAME is something for which parameter_brace_expand_length is 5133 OK to do. */ 5134static int 5135valid_length_expression (name) 5136 char *name; 5137{ 5138 return (name[1] == '\0' || /* ${#} */ 5139 ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') || /* special param */ 5140 (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */ 5141#if defined (ARRAY_VARS) 5142 valid_array_reference (name + 1) || /* ${#a[7]} */ 5143#endif 5144 legal_identifier (name + 1)); /* ${#PS1} */ 5145} 5146 5147#if defined (HANDLE_MULTIBYTE) 5148size_t 5149mbstrlen (s) 5150 const char *s; 5151{ 5152 size_t clen, nc; 5153 mbstate_t mbs, mbsbak; 5154 5155 nc = 0; 5156 memset (&mbs, 0, sizeof (mbs)); 5157 mbsbak = mbs; 5158 while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0) 5159 { 5160 if (MB_INVALIDCH(clen)) 5161 { 5162 clen = 1; /* assume single byte */ 5163 mbs = mbsbak; 5164 } 5165 5166 s += clen; 5167 nc++; 5168 mbsbak = mbs; 5169 } 5170 return nc; 5171} 5172#endif 5173 5174 5175/* Handle the parameter brace expansion that requires us to return the 5176 length of a parameter. */ 5177static intmax_t 5178parameter_brace_expand_length (name) 5179 char *name; 5180{ 5181 char *t, *newname; 5182 intmax_t number, arg_index; 5183 WORD_LIST *list; 5184#if defined (ARRAY_VARS) 5185 SHELL_VAR *var; 5186#endif 5187 5188 if (name[1] == '\0') /* ${#} */ 5189 number = number_of_args (); 5190 else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0') /* ${#@}, ${#*} */ 5191 number = number_of_args (); 5192 else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') 5193 { 5194 /* Take the lengths of some of the shell's special parameters. */ 5195 switch (name[1]) 5196 { 5197 case '-': 5198 t = which_set_flags (); 5199 break; 5200 case '?': 5201 t = itos (last_command_exit_value); 5202 break; 5203 case '$': 5204 t = itos (dollar_dollar_pid); 5205 break; 5206 case '!': 5207 if (last_asynchronous_pid == NO_PID) 5208 t = (char *)NULL; 5209 else 5210 t = itos (last_asynchronous_pid); 5211 break; 5212 case '#': 5213 t = itos (number_of_args ()); 5214 break; 5215 } 5216 number = STRLEN (t); 5217 FREE (t); 5218 } 5219#if defined (ARRAY_VARS) 5220 else if (valid_array_reference (name + 1)) 5221 number = array_length_reference (name + 1); 5222#endif /* ARRAY_VARS */ 5223 else 5224 { 5225 number = 0; 5226 5227 if (legal_number (name + 1, &arg_index)) /* ${#1} */ 5228 { 5229 t = get_dollar_var_value (arg_index); 5230 number = MB_STRLEN (t); 5231 FREE (t); 5232 } 5233#if defined (ARRAY_VARS) 5234 else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && array_p (var)) 5235 { 5236 t = array_reference (array_cell (var), 0); 5237 number = MB_STRLEN (t); 5238 } 5239#endif 5240 else /* ${#PS1} */ 5241 { 5242 newname = savestring (name); 5243 newname[0] = '$'; 5244 list = expand_string (newname, Q_DOUBLE_QUOTES); 5245 t = list ? string_list (list) : (char *)NULL; 5246 free (newname); 5247 if (list) 5248 dispose_words (list); 5249 5250 number = MB_STRLEN (t); 5251 FREE (t); 5252 } 5253 } 5254 5255 return (number); 5256} 5257 5258/* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression, 5259 so we do some ad-hoc parsing of an arithmetic expression to find 5260 the first DELIM, instead of using strchr(3). Two rules: 5261 1. If the substring contains a `(', read until closing `)'. 5262 2. If the substring contains a `?', read past one `:' for each `?'. 5263*/ 5264 5265static char * 5266skiparith (substr, delim) 5267 char *substr; 5268 int delim; 5269{ 5270 size_t sublen; 5271 int skipcol, pcount, i; 5272 DECLARE_MBSTATE; 5273 5274 sublen = strlen (substr); 5275 i = skipcol = pcount = 0; 5276 while (substr[i]) 5277 { 5278 /* Balance parens */ 5279 if (substr[i] == LPAREN) 5280 { 5281 pcount++; 5282 i++; 5283 continue; 5284 } 5285 if (substr[i] == RPAREN && pcount) 5286 { 5287 pcount--; 5288 i++; 5289 continue; 5290 } 5291 if (pcount) 5292 { 5293 ADVANCE_CHAR (substr, sublen, i); 5294 continue; 5295 } 5296 5297 /* Skip one `:' for each `?' */ 5298 if (substr[i] == ':' && skipcol) 5299 { 5300 skipcol--; 5301 i++; 5302 continue; 5303 } 5304 if (substr[i] == delim) 5305 break; 5306 if (substr[i] == '?') 5307 { 5308 skipcol++; 5309 i++; 5310 continue; 5311 } 5312 ADVANCE_CHAR (substr, sublen, i); 5313 } 5314 5315 return (substr + i); 5316} 5317 5318/* Verify and limit the start and end of the desired substring. If 5319 VTYPE == 0, a regular shell variable is being used; if it is 1, 5320 then the positional parameters are being used; if it is 2, then 5321 VALUE is really a pointer to an array variable that should be used. 5322 Return value is 1 if both values were OK, 0 if there was a problem 5323 with an invalid expression, or -1 if the values were out of range. */ 5324static int 5325verify_substring_values (value, substr, vtype, e1p, e2p) 5326 char *value, *substr; 5327 int vtype; 5328 intmax_t *e1p, *e2p; 5329{ 5330 char *t, *temp1, *temp2; 5331 arrayind_t len; 5332 int expok; 5333#if defined (ARRAY_VARS) 5334 ARRAY *a; 5335#endif 5336 5337 /* duplicate behavior of strchr(3) */ 5338 t = skiparith (substr, ':'); 5339 if (*t && *t == ':') 5340 *t = '\0'; 5341 else 5342 t = (char *)0; 5343 5344 temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES); 5345 *e1p = evalexp (temp1, &expok); 5346 free (temp1); 5347 if (expok == 0) 5348 return (0); 5349 5350 len = -1; /* paranoia */ 5351 switch (vtype) 5352 { 5353 case VT_VARIABLE: 5354 case VT_ARRAYMEMBER: 5355 len = MB_STRLEN (value); 5356 break; 5357 case VT_POSPARMS: 5358 len = number_of_args () + 1; 5359 break; 5360#if defined (ARRAY_VARS) 5361 case VT_ARRAYVAR: 5362 a = (ARRAY *)value; 5363 /* For arrays, the first value deals with array indices. Negative 5364 offsets count from one past the array's maximum index. */ 5365 len = array_max_index (a) + (*e1p < 0); /* arrays index from 0 to n - 1 */ 5366 break; 5367#endif 5368 } 5369 5370 if (len == -1) /* paranoia */ 5371 return -1; 5372 5373 if (*e1p < 0) /* negative offsets count from end */ 5374 *e1p += len; 5375 5376 if (*e1p > len || *e1p < 0) 5377 return (-1); 5378 5379#if defined (ARRAY_VARS) 5380 /* For arrays, the second offset deals with the number of elements. */ 5381 if (vtype == VT_ARRAYVAR) 5382 len = array_num_elements (a); 5383#endif 5384 5385 if (t) 5386 { 5387 t++; 5388 temp2 = savestring (t); 5389 temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES); 5390 free (temp2); 5391 t[-1] = ':'; 5392 *e2p = evalexp (temp1, &expok); 5393 free (temp1); 5394 if (expok == 0) 5395 return (0); 5396 if (*e2p < 0) 5397 { 5398 internal_error (_("%s: substring expression < 0"), t); 5399 return (0); 5400 } 5401#if defined (ARRAY_VARS) 5402 /* In order to deal with sparse arrays, push the intelligence about how 5403 to deal with the number of elements desired down to the array- 5404 specific functions. */ 5405 if (vtype != VT_ARRAYVAR) 5406#endif 5407 { 5408 *e2p += *e1p; /* want E2 chars starting at E1 */ 5409 if (*e2p > len) 5410 *e2p = len; 5411 } 5412 } 5413 else 5414 *e2p = len; 5415 5416 return (1); 5417} 5418 5419/* Return the type of variable specified by VARNAME (simple variable, 5420 positional param, or array variable). Also return the value specified 5421 by VARNAME (value of a variable or a reference to an array element). 5422 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL 5423 characters in the value are quoted with CTLESC and takes appropriate 5424 steps. For convenience, *VALP is set to the dequoted VALUE. */ 5425static int 5426get_var_and_type (varname, value, quoted, varp, valp) 5427 char *varname, *value; 5428 int quoted; 5429 SHELL_VAR **varp; 5430 char **valp; 5431{ 5432 int vtype; 5433 char *temp; 5434#if defined (ARRAY_VARS) 5435 SHELL_VAR *v; 5436#endif 5437 5438 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */ 5439 vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0'; 5440 if (vtype == VT_POSPARMS && varname[0] == '*') 5441 vtype |= VT_STARSUB; 5442 *varp = (SHELL_VAR *)NULL; 5443 5444#if defined (ARRAY_VARS) 5445 if (valid_array_reference (varname)) 5446 { 5447 v = array_variable_part (varname, &temp, (int *)0); 5448 if (v && array_p (v)) 5449 { /* [ */ 5450 if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']') 5451 { 5452 vtype = VT_ARRAYVAR; 5453 if (temp[0] == '*') 5454 vtype |= VT_STARSUB; 5455 *valp = (char *)array_cell (v); 5456 } 5457 else 5458 { 5459 vtype = VT_ARRAYMEMBER; 5460 *valp = array_value (varname, 1, (int *)NULL); 5461 } 5462 *varp = v; 5463 } 5464 else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')) 5465 { 5466 vtype = VT_VARIABLE; 5467 *varp = v; 5468 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) 5469 *valp = dequote_string (value); 5470 else 5471 *valp = dequote_escapes (value); 5472 } 5473 else 5474 return -1; 5475 } 5476 else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && array_p (v)) 5477 { 5478 vtype = VT_ARRAYMEMBER; 5479 *varp = v; 5480 *valp = array_reference (array_cell (v), 0); 5481 } 5482 else 5483#endif 5484 { 5485 if (value && vtype == VT_VARIABLE) 5486 { 5487 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) 5488 *valp = dequote_string (value); 5489 else 5490 *valp = dequote_escapes (value); 5491 } 5492 else 5493 *valp = value; 5494 } 5495 5496 return vtype; 5497} 5498 5499/******************************************************/ 5500/* */ 5501/* Functions to extract substrings of variable values */ 5502/* */ 5503/******************************************************/ 5504 5505#if defined (HANDLE_MULTIBYTE) 5506/* Character-oriented rather than strictly byte-oriented substrings. S and 5507 E, rather being strict indices into STRING, indicate character (possibly 5508 multibyte character) positions that require calculation. 5509 Used by the ${param:offset[:length]} expansion. */ 5510static char * 5511mb_substring (string, s, e) 5512 char *string; 5513 int s, e; 5514{ 5515 char *tt; 5516 int start, stop, i, slen; 5517 DECLARE_MBSTATE; 5518 5519 start = 0; 5520 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */ 5521 slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0; 5522 5523 i = s; 5524 while (string[start] && i--) 5525 ADVANCE_CHAR (string, slen, start); 5526 stop = start; 5527 i = e - s; 5528 while (string[stop] && i--) 5529 ADVANCE_CHAR (string, slen, stop); 5530 tt = substring (string, start, stop); 5531 return tt; 5532} 5533#endif 5534 5535/* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME 5536 is `@', use the positional parameters; otherwise, use the value of 5537 VARNAME. If VARNAME is an array variable, use the array elements. */ 5538 5539static char * 5540parameter_brace_substring (varname, value, substr, quoted) 5541 char *varname, *value, *substr; 5542 int quoted; 5543{ 5544 intmax_t e1, e2; 5545 int vtype, r, starsub; 5546 char *temp, *val, *tt, *oname; 5547 SHELL_VAR *v; 5548 5549 if (value == 0) 5550 return ((char *)NULL); 5551 5552 oname = this_command_name; 5553 this_command_name = varname; 5554 5555 vtype = get_var_and_type (varname, value, quoted, &v, &val); 5556 if (vtype == -1) 5557 { 5558 this_command_name = oname; 5559 return ((char *)NULL); 5560 } 5561 5562 starsub = vtype & VT_STARSUB; 5563 vtype &= ~VT_STARSUB; 5564 5565 r = verify_substring_values (val, substr, vtype, &e1, &e2); 5566 this_command_name = oname; 5567 if (r <= 0) 5568 return ((r == 0) ? &expand_param_error : (char *)NULL); 5569 5570 switch (vtype) 5571 { 5572 case VT_VARIABLE: 5573 case VT_ARRAYMEMBER: 5574#if defined (HANDLE_MULTIBYTE) 5575 if (MB_CUR_MAX > 1) 5576 tt = mb_substring (val, e1, e2); 5577 else 5578#endif 5579 tt = substring (val, e1, e2); 5580 5581 if (vtype == VT_VARIABLE) 5582 FREE (val); 5583 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) 5584 temp = quote_string (tt); 5585 else 5586 temp = tt ? quote_escapes (tt) : (char *)NULL; 5587 FREE (tt); 5588 break; 5589 case VT_POSPARMS: 5590 tt = pos_params (varname, e1, e2, quoted); 5591 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0) 5592 { 5593 temp = tt ? quote_escapes (tt) : (char *)NULL; 5594 FREE (tt); 5595 } 5596 else 5597 temp = tt; 5598 break; 5599#if defined (ARRAY_VARS) 5600 case VT_ARRAYVAR: 5601 /* We want E2 to be the number of elements desired (arrays can be sparse, 5602 so verify_substring_values just returns the numbers specified and we 5603 rely on array_subrange to understand how to deal with them). */ 5604 tt = array_subrange (array_cell (v), e1, e2, starsub, quoted); 5605#if 0 5606 /* array_subrange now calls array_quote_escapes as appropriate, so the 5607 caller no longer needs to. */ 5608 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0) 5609 { 5610 temp = tt ? quote_escapes (tt) : (char *)NULL; 5611 FREE (tt); 5612 } 5613 else 5614#endif 5615 temp = tt; 5616 break; 5617#endif 5618 default: 5619 temp = (char *)NULL; 5620 } 5621 5622 return temp; 5623} 5624 5625/****************************************************************/ 5626/* */ 5627/* Functions to perform pattern substitution on variable values */ 5628/* */ 5629/****************************************************************/ 5630 5631char * 5632pat_subst (string, pat, rep, mflags) 5633 char *string, *pat, *rep; 5634 int mflags; 5635{ 5636 char *ret, *s, *e, *str; 5637 int rsize, rptr, l, replen, mtype; 5638 5639 mtype = mflags & MATCH_TYPEMASK; 5640 5641 /* Special cases: 5642 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING 5643 * with REP and return the result. 5644 * 2. A null pattern with mtype == MATCH_END means to append REP to 5645 * STRING and return the result. 5646 */ 5647 if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END)) 5648 { 5649 replen = STRLEN (rep); 5650 l = strlen (string); 5651 ret = (char *)xmalloc (replen + l + 2); 5652 if (replen == 0) 5653 strcpy (ret, string); 5654 else if (mtype == MATCH_BEG) 5655 { 5656 strcpy (ret, rep); 5657 strcpy (ret + replen, string); 5658 } 5659 else 5660 { 5661 strcpy (ret, string); 5662 strcpy (ret + l, rep); 5663 } 5664 return (ret); 5665 } 5666 5667 ret = (char *)xmalloc (rsize = 64); 5668 ret[0] = '\0'; 5669 5670 for (replen = STRLEN (rep), rptr = 0, str = string;;) 5671 { 5672 if (match_pattern (str, pat, mtype, &s, &e) == 0) 5673 break; 5674 l = s - str; 5675 RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64); 5676 5677 /* OK, now copy the leading unmatched portion of the string (from 5678 str to s) to ret starting at rptr (the current offset). Then copy 5679 the replacement string at ret + rptr + (s - str). Increment 5680 rptr (if necessary) and str and go on. */ 5681 if (l) 5682 { 5683 strncpy (ret + rptr, str, l); 5684 rptr += l; 5685 } 5686 if (replen) 5687 { 5688 strncpy (ret + rptr, rep, replen); 5689 rptr += replen; 5690 } 5691 str = e; /* e == end of match */ 5692 5693 if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY) 5694 break; 5695 5696 if (s == e) 5697 e++, str++; /* avoid infinite recursion on zero-length match */ 5698 } 5699 5700 /* Now copy the unmatched portion of the input string */ 5701 if (*str) 5702 { 5703 RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64); 5704 strcpy (ret + rptr, str); 5705 } 5706 else 5707 ret[rptr] = '\0'; 5708 5709 return ret; 5710} 5711 5712/* Do pattern match and replacement on the positional parameters. */ 5713static char * 5714pos_params_pat_subst (string, pat, rep, mflags) 5715 char *string, *pat, *rep; 5716 int mflags; 5717{ 5718 WORD_LIST *save, *params; 5719 WORD_DESC *w; 5720 char *ret; 5721 5722 save = params = list_rest_of_args (); 5723 if (save == 0) 5724 return ((char *)NULL); 5725 5726 for ( ; params; params = params->next) 5727 { 5728 ret = pat_subst (params->word->word, pat, rep, mflags); 5729 w = alloc_word_desc (); 5730 w->word = ret ? ret : savestring (""); 5731 dispose_word (params->word); 5732 params->word = w; 5733 } 5734 5735 if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB)) 5736 ret = string_list_dollar_star (quote_list (save)); 5737 else 5738 ret = string_list ((mflags & MATCH_QUOTED) ? quote_list (save) : save); 5739 dispose_words (save); 5740 5741 return (ret); 5742} 5743 5744/* Perform pattern substitution on VALUE, which is the expansion of 5745 VARNAME. PATSUB is an expression supplying the pattern to match 5746 and the string to substitute. QUOTED is a flags word containing 5747 the type of quoting currently in effect. */ 5748static char * 5749parameter_brace_patsub (varname, value, patsub, quoted) 5750 char *varname, *value, *patsub; 5751 int quoted; 5752{ 5753 int vtype, mflags, starsub; 5754 char *val, *temp, *pat, *rep, *p, *lpatsub, *tt; 5755 SHELL_VAR *v; 5756 5757 if (value == 0) 5758 return ((char *)NULL); 5759 5760 this_command_name = varname; 5761 5762 vtype = get_var_and_type (varname, value, quoted, &v, &val); 5763 if (vtype == -1) 5764 return ((char *)NULL); 5765 5766 starsub = vtype & VT_STARSUB; 5767 vtype &= ~VT_STARSUB; 5768 5769 mflags = 0; 5770 if (patsub && *patsub == '/') 5771 { 5772 mflags |= MATCH_GLOBREP; 5773 patsub++; 5774 } 5775 5776 /* Malloc this because expand_string_if_necessary or one of the expansion 5777 functions in its call chain may free it on a substitution error. */ 5778 lpatsub = savestring (patsub); 5779 5780 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) 5781 mflags |= MATCH_QUOTED; 5782 5783 if (starsub) 5784 mflags |= MATCH_STARSUB; 5785 5786 /* If the pattern starts with a `/', make sure we skip over it when looking 5787 for the replacement delimiter. */ 5788 if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL)) 5789 *rep++ = '\0'; 5790 else 5791 rep = (char *)NULL; 5792 5793 if (rep && *rep == '\0') 5794 rep = (char *)NULL; 5795 5796 /* Perform the same expansions on the pattern as performed by the 5797 pattern removal expansions. */ 5798 pat = getpattern (lpatsub, quoted, 1); 5799 5800 if (rep) 5801 { 5802 if ((mflags & MATCH_QUOTED) == 0) 5803 rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit); 5804 else 5805 rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit); 5806 } 5807 5808 /* ksh93 doesn't allow the match specifier to be a part of the expanded 5809 pattern. This is an extension. Make sure we don't anchor the pattern 5810 at the beginning or end of the string if we're doing global replacement, 5811 though. */ 5812 p = pat; 5813 if (mflags & MATCH_GLOBREP) 5814 mflags |= MATCH_ANY; 5815 else if (pat && pat[0] == '#') 5816 { 5817 mflags |= MATCH_BEG; 5818 p++; 5819 } 5820 else if (pat && pat[0] == '%') 5821 { 5822 mflags |= MATCH_END; 5823 p++; 5824 } 5825 else 5826 mflags |= MATCH_ANY; 5827 5828 /* OK, we now want to substitute REP for PAT in VAL. If 5829 flags & MATCH_GLOBREP is non-zero, the substitution is done 5830 everywhere, otherwise only the first occurrence of PAT is 5831 replaced. The pattern matching code doesn't understand 5832 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable 5833 values passed in (VT_VARIABLE) so the pattern substitution 5834 code works right. We need to requote special chars after 5835 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the 5836 other cases if QUOTED == 0, since the posparams and arrays 5837 indexed by * or @ do special things when QUOTED != 0. */ 5838 5839 switch (vtype) 5840 { 5841 case VT_VARIABLE: 5842 case VT_ARRAYMEMBER: 5843 temp = pat_subst (val, p, rep, mflags); 5844 if (vtype == VT_VARIABLE) 5845 FREE (val); 5846 if (temp) 5847 { 5848 tt = quote_escapes (temp); 5849 free (temp); 5850 temp = tt; 5851 } 5852 break; 5853 case VT_POSPARMS: 5854 temp = pos_params_pat_subst (val, p, rep, mflags); 5855 if (temp && (mflags & MATCH_QUOTED) == 0) 5856 { 5857 tt = quote_escapes (temp); 5858 free (temp); 5859 temp = tt; 5860 } 5861 break; 5862#if defined (ARRAY_VARS) 5863 case VT_ARRAYVAR: 5864 temp = array_patsub (array_cell (v), p, rep, mflags); 5865#if 0 5866 /* Don't need to do this anymore; array_patsub calls array_quote_escapes 5867 as appropriate before adding the space separators. */ 5868 if (temp && (mflags & MATCH_QUOTED) == 0) 5869 { 5870 tt = quote_escapes (temp); 5871 free (temp); 5872 temp = tt; 5873 } 5874#endif 5875 break; 5876#endif 5877 } 5878 5879 FREE (pat); 5880 FREE (rep); 5881 free (lpatsub); 5882 5883 return temp; 5884} 5885 5886/* Check for unbalanced parens in S, which is the contents of $(( ... )). If 5887 any occur, this must be a nested command substitution, so return 0. 5888 Otherwise, return 1. A valid arithmetic expression must always have a 5889 ( before a matching ), so any cases where there are more right parens 5890 means that this must not be an arithmetic expression, though the parser 5891 will not accept it without a balanced total number of parens. */ 5892static int 5893chk_arithsub (s, len) 5894 const char *s; 5895 int len; 5896{ 5897 int i, count; 5898 DECLARE_MBSTATE; 5899 5900 i = count = 0; 5901 while (i < len) 5902 { 5903 if (s[i] == '(') 5904 count++; 5905 else if (s[i] == ')') 5906 { 5907 count--; 5908 if (count < 0) 5909 return 0; 5910 } 5911 5912 switch (s[i]) 5913 { 5914 default: 5915 ADVANCE_CHAR (s, len, i); 5916 break; 5917 5918 case '\\': 5919 i++; 5920 if (s[i]) 5921 ADVANCE_CHAR (s, len, i); 5922 break; 5923 5924 case '\'': 5925 i = skip_single_quoted (s, len, ++i); 5926 break; 5927 5928 case '"': 5929 i = skip_double_quoted ((char *)s, len, ++i); 5930 break; 5931 } 5932 } 5933 5934 return (count == 0); 5935} 5936 5937/****************************************************************/ 5938/* */ 5939/* Functions to perform parameter expansion on a string */ 5940/* */ 5941/****************************************************************/ 5942 5943/* ${[#][!]name[[:]#[#]%[%]-=?+[word][:e1[:e2]]]} */ 5944static WORD_DESC * 5945parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_dollar_at) 5946 char *string; 5947 int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at; 5948{ 5949 int check_nullness, var_is_set, var_is_null, var_is_special; 5950 int want_substring, want_indir, want_patsub; 5951 char *name, *value, *temp, *temp1; 5952 WORD_DESC *tdesc, *ret; 5953 int t_index, sindex, c, tflag; 5954 intmax_t number; 5955 5956 value = (char *)NULL; 5957 var_is_set = var_is_null = var_is_special = check_nullness = 0; 5958 want_substring = want_indir = want_patsub = 0; 5959 5960 sindex = *indexp; 5961 t_index = ++sindex; 5962 /* ${#var} doesn't have any of the other parameter expansions on it. */ 5963 if (string[t_index] == '#' && legal_variable_starter (string[t_index+1])) /* {{ */ 5964 name = string_extract (string, &t_index, "}", EX_VARNAME); 5965 else 5966 name = string_extract (string, &t_index, "#%:-=?+/}", EX_VARNAME); 5967 5968 ret = 0; 5969 tflag = 0; 5970 5971 /* If the name really consists of a special variable, then make sure 5972 that we have the entire name. We don't allow indirect references 5973 to special variables except `#', `?', `@' and `*'. */ 5974 if ((sindex == t_index && 5975 (string[t_index] == '-' || 5976 string[t_index] == '?' || 5977 string[t_index] == '#')) || 5978 (sindex == t_index - 1 && string[sindex] == '!' && 5979 (string[t_index] == '#' || 5980 string[t_index] == '?' || 5981 string[t_index] == '@' || 5982 string[t_index] == '*'))) 5983 { 5984 t_index++; 5985 free (name); 5986 temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0); 5987 name = (char *)xmalloc (3 + (strlen (temp1))); 5988 *name = string[sindex]; 5989 if (string[sindex] == '!') 5990 { 5991 /* indirect reference of $#, $?, $@, or $* */ 5992 name[1] = string[sindex + 1]; 5993 strcpy (name + 2, temp1); 5994 } 5995 else 5996 strcpy (name + 1, temp1); 5997 free (temp1); 5998 } 5999 sindex = t_index; 6000 6001 /* Find out what character ended the variable name. Then 6002 do the appropriate thing. */ 6003 if (c = string[sindex]) 6004 sindex++; 6005 6006 /* If c is followed by one of the valid parameter expansion 6007 characters, move past it as normal. If not, assume that 6008 a substring specification is being given, and do not move 6009 past it. */ 6010 if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex])) 6011 { 6012 check_nullness++; 6013 if (c = string[sindex]) 6014 sindex++; 6015 } 6016 else if (c == ':' && string[sindex] != RBRACE) 6017 want_substring = 1; 6018 else if (c == '/' && string[sindex] != RBRACE) 6019 want_patsub = 1; 6020 6021 /* Catch the valid and invalid brace expressions that made it through the 6022 tests above. */ 6023 /* ${#-} is a valid expansion and means to take the length of $-. 6024 Similarly for ${#?} and ${##}... */ 6025 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 && 6026 VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE) 6027 { 6028 name = (char *)xrealloc (name, 3); 6029 name[1] = c; 6030 name[2] = '\0'; 6031 c = string[sindex++]; 6032 } 6033 6034 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */ 6035 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 && 6036 member (c, "%:=+/") && string[sindex] == RBRACE) 6037 { 6038 temp = (char *)NULL; 6039 goto bad_substitution; 6040 } 6041 6042 /* Indirect expansion begins with a `!'. A valid indirect expansion is 6043 either a variable name, one of the positional parameters or a special 6044 variable that expands to one of the positional parameters. */ 6045 want_indir = *name == '!' && 6046 (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1]) 6047 || VALID_INDIR_PARAM (name[1])); 6048 6049 /* Determine the value of this variable. */ 6050 6051 /* Check for special variables, directly referenced. */ 6052 if (SPECIAL_VAR (name, want_indir)) 6053 var_is_special++; 6054 6055 /* Check for special expansion things, like the length of a parameter */ 6056 if (*name == '#' && name[1]) 6057 { 6058 /* If we are not pointing at the character just after the 6059 closing brace, then we haven't gotten all of the name. 6060 Since it begins with a special character, this is a bad 6061 substitution. Also check NAME for validity before trying 6062 to go on. */ 6063 if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0)) 6064 { 6065 temp = (char *)NULL; 6066 goto bad_substitution; 6067 } 6068 6069 number = parameter_brace_expand_length (name); 6070 free (name); 6071 6072 *indexp = sindex; 6073 if (number < 0) 6074 return (&expand_wdesc_error); 6075 else 6076 { 6077 ret = alloc_word_desc (); 6078 ret->word = itos (number); 6079 return ret; 6080 } 6081 } 6082 6083 /* ${@} is identical to $@. */ 6084 if (name[0] == '@' && name[1] == '\0') 6085 { 6086 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) 6087 *quoted_dollar_atp = 1; 6088 6089 if (contains_dollar_at) 6090 *contains_dollar_at = 1; 6091 } 6092 6093 /* Process ${!PREFIX*} expansion. */ 6094 if (want_indir && string[sindex - 1] == RBRACE && 6095 (string[sindex - 2] == '*' || string[sindex - 2] == '@') && 6096 legal_variable_starter ((unsigned char) name[1])) 6097 { 6098 char **x; 6099 WORD_LIST *xlist; 6100 6101 temp1 = savestring (name + 1); 6102 number = strlen (temp1); 6103 temp1[number - 1] = '\0'; 6104 x = all_variables_matching_prefix (temp1); 6105 xlist = strvec_to_word_list (x, 0, 0); 6106 if (string[sindex - 2] == '*') 6107 temp = string_list_dollar_star (xlist); 6108 else 6109 { 6110 temp = string_list_dollar_at (xlist, quoted); 6111 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) 6112 *quoted_dollar_atp = 1; 6113 if (contains_dollar_at) 6114 *contains_dollar_at = 1; 6115 } 6116 free (x); 6117 free (xlist); 6118 free (temp1); 6119 *indexp = sindex; 6120 6121 ret = alloc_word_desc (); 6122 ret->word = temp; 6123 return ret; 6124 } 6125 6126#if defined (ARRAY_VARS) 6127 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */ 6128 if (want_indir && string[sindex - 1] == RBRACE && 6129 string[sindex - 2] == ']' && valid_array_reference (name+1)) 6130 { 6131 char *x, *x1; 6132 6133 temp1 = savestring (name + 1); 6134 x = array_variable_name (temp1, &x1, (int *)0); /* [ */ 6135 FREE (x); 6136 if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']') 6137 { 6138 temp = array_keys (temp1, quoted); 6139 if (x1[0] == '@') 6140 { 6141 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) 6142 *quoted_dollar_atp = 1; 6143 if (contains_dollar_at) 6144 *contains_dollar_at = 1; 6145 } 6146 6147 free (temp1); 6148 *indexp = sindex; 6149 6150 ret = alloc_word_desc (); 6151 ret->word = temp; 6152 return ret; 6153 } 6154 6155 free (temp1); 6156 } 6157#endif /* ARRAY_VARS */ 6158 6159 /* Make sure that NAME is valid before trying to go on. */ 6160 if (valid_brace_expansion_word (want_indir ? name + 1 : name, 6161 var_is_special) == 0) 6162 { 6163 temp = (char *)NULL; 6164 goto bad_substitution; 6165 } 6166 6167 if (want_indir) 6168 tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at); 6169 else 6170 tdesc = parameter_brace_expand_word (name, var_is_special, quoted); 6171 6172 if (tdesc) 6173 { 6174 temp = tdesc->word; 6175 tflag = tdesc->flags; 6176 dispose_word_desc (tdesc); 6177 } 6178 else 6179 temp = (char *)0; 6180 6181#if defined (ARRAY_VARS) 6182 if (valid_array_reference (name)) 6183 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at); 6184#endif 6185 6186 var_is_set = temp != (char *)0; 6187 var_is_null = check_nullness && (var_is_set == 0 || *temp == 0); 6188 6189 /* Get the rest of the stuff inside the braces. */ 6190 if (c && c != RBRACE) 6191 { 6192 /* Extract the contents of the ${ ... } expansion 6193 according to the Posix.2 rules. */ 6194 value = extract_dollar_brace_string (string, &sindex, quoted, 0); 6195 if (string[sindex] == RBRACE) 6196 sindex++; 6197 else 6198 goto bad_substitution; 6199 } 6200 else 6201 value = (char *)NULL; 6202 6203 *indexp = sindex; 6204 6205 /* If this is a substring spec, process it and add the result. */ 6206 if (want_substring) 6207 { 6208 temp1 = parameter_brace_substring (name, temp, value, quoted); 6209 FREE (name); 6210 FREE (value); 6211 FREE (temp); 6212 6213 if (temp1 == &expand_param_error) 6214 return (&expand_wdesc_error); 6215 else if (temp1 == &expand_param_fatal) 6216 return (&expand_wdesc_fatal); 6217 6218 ret = alloc_word_desc (); 6219 ret->word = temp1; 6220 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) 6221 ret->flags |= W_QUOTED|W_HASQUOTEDNULL; 6222 return ret; 6223 } 6224 else if (want_patsub) 6225 { 6226 temp1 = parameter_brace_patsub (name, temp, value, quoted); 6227 FREE (name); 6228 FREE (value); 6229 FREE (temp); 6230 6231 if (temp1 == &expand_param_error) 6232 return (&expand_wdesc_error); 6233 else if (temp1 == &expand_param_fatal) 6234 return (&expand_wdesc_fatal); 6235 6236 ret = alloc_word_desc (); 6237 ret->word = temp1; 6238 return ret; 6239 } 6240 6241 /* Do the right thing based on which character ended the variable name. */ 6242 switch (c) 6243 { 6244 default: 6245 case '\0': 6246 bad_substitution: 6247 report_error (_("%s: bad substitution"), string ? string : "??"); 6248 FREE (value); 6249 FREE (temp); 6250 free (name); 6251 return &expand_wdesc_error; 6252 6253 case RBRACE: 6254 if (var_is_set == 0 && unbound_vars_is_error) 6255 { 6256 err_unboundvar (name); 6257 FREE (value); 6258 FREE (temp); 6259 free (name); 6260 last_command_exit_value = EXECUTION_FAILURE; 6261 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); 6262 } 6263 break; 6264 6265 case '#': /* ${param#[#]pattern} */ 6266 case '%': /* ${param%[%]pattern} */ 6267 if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0') 6268 { 6269 FREE (value); 6270 break; 6271 } 6272 temp1 = parameter_brace_remove_pattern (name, temp, value, c, quoted); 6273 free (temp); 6274 free (value); 6275 temp = temp1; 6276 break; 6277 6278 case '-': 6279 case '=': 6280 case '?': 6281 case '+': 6282 if (var_is_set && var_is_null == 0) 6283 { 6284 /* If the operator is `+', we don't want the value of the named 6285 variable for anything, just the value of the right hand side. */ 6286 6287 if (c == '+') 6288 { 6289 /* XXX -- if we're double-quoted and the named variable is "$@", 6290 we want to turn off any special handling of "$@" -- 6291 we're not using it, so whatever is on the rhs applies. */ 6292 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) 6293 *quoted_dollar_atp = 0; 6294 if (contains_dollar_at) 6295 *contains_dollar_at = 0; 6296 6297 FREE (temp); 6298 if (value) 6299 { 6300 ret = parameter_brace_expand_rhs (name, value, c, 6301 quoted, 6302 quoted_dollar_atp, 6303 contains_dollar_at); 6304 /* XXX - fix up later, esp. noting presence of 6305 W_HASQUOTEDNULL in ret->flags */ 6306 free (value); 6307 } 6308 else 6309 temp = (char *)NULL; 6310 } 6311 else 6312 { 6313 FREE (value); 6314 } 6315 /* Otherwise do nothing; just use the value in TEMP. */ 6316 } 6317 else /* VAR not set or VAR is NULL. */ 6318 { 6319 FREE (temp); 6320 temp = (char *)NULL; 6321 if (c == '=' && var_is_special) 6322 { 6323 report_error (_("$%s: cannot assign in this way"), name); 6324 free (name); 6325 free (value); 6326 return &expand_wdesc_error; 6327 } 6328 else if (c == '?') 6329 { 6330 parameter_brace_expand_error (name, value); 6331 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); 6332 } 6333 else if (c != '+') 6334 { 6335 /* XXX -- if we're double-quoted and the named variable is "$@", 6336 we want to turn off any special handling of "$@" -- 6337 we're not using it, so whatever is on the rhs applies. */ 6338 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp) 6339 *quoted_dollar_atp = 0; 6340 if (contains_dollar_at) 6341 *contains_dollar_at = 0; 6342 6343 ret = parameter_brace_expand_rhs (name, value, c, quoted, 6344 quoted_dollar_atp, 6345 contains_dollar_at); 6346 /* XXX - fix up later, esp. noting presence of 6347 W_HASQUOTEDNULL in tdesc->flags */ 6348 } 6349 free (value); 6350 } 6351 6352 break; 6353 } 6354 free (name); 6355 6356 if (ret == 0) 6357 { 6358 ret = alloc_word_desc (); 6359 ret->flags = tflag; 6360 ret->word = temp; 6361 } 6362 return (ret); 6363} 6364 6365/* Expand a single ${xxx} expansion. The braces are optional. When 6366 the braces are used, parameter_brace_expand() does the work, 6367 possibly calling param_expand recursively. */ 6368static WORD_DESC * 6369param_expand (string, sindex, quoted, expanded_something, 6370 contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p, 6371 pflags) 6372 char *string; 6373 int *sindex, quoted, *expanded_something, *contains_dollar_at; 6374 int *quoted_dollar_at_p, *had_quoted_null_p, pflags; 6375{ 6376 char *temp, *temp1, uerror[3]; 6377 int zindex, t_index, expok; 6378 unsigned char c; 6379 intmax_t number; 6380 SHELL_VAR *var; 6381 WORD_LIST *list; 6382 WORD_DESC *tdesc, *ret; 6383 int tflag; 6384 6385 zindex = *sindex; 6386 c = string[++zindex]; 6387 6388 temp = (char *)NULL; 6389 ret = tdesc = (WORD_DESC *)NULL; 6390 tflag = 0; 6391 6392 /* Do simple cases first. Switch on what follows '$'. */ 6393 switch (c) 6394 { 6395 /* $0 .. $9? */ 6396 case '0': 6397 case '1': 6398 case '2': 6399 case '3': 6400 case '4': 6401 case '5': 6402 case '6': 6403 case '7': 6404 case '8': 6405 case '9': 6406 temp1 = dollar_vars[TODIGIT (c)]; 6407 if (unbound_vars_is_error && temp1 == (char *)NULL) 6408 { 6409 uerror[0] = '$'; 6410 uerror[1] = c; 6411 uerror[2] = '\0'; 6412 err_unboundvar (uerror); 6413 last_command_exit_value = EXECUTION_FAILURE; 6414 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); 6415 } 6416 if (temp1) 6417 temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) 6418 ? quote_string (temp1) 6419 : quote_escapes (temp1); 6420 else 6421 temp = (char *)NULL; 6422 6423 break; 6424 6425 /* $$ -- pid of the invoking shell. */ 6426 case '$': 6427 temp = itos (dollar_dollar_pid); 6428 break; 6429 6430 /* $# -- number of positional parameters. */ 6431 case '#': 6432 temp = itos (number_of_args ()); 6433 break; 6434 6435 /* $? -- return value of the last synchronous command. */ 6436 case '?': 6437 temp = itos (last_command_exit_value); 6438 break; 6439 6440 /* $- -- flags supplied to the shell on invocation or by `set'. */ 6441 case '-': 6442 temp = which_set_flags (); 6443 break; 6444 6445 /* $! -- Pid of the last asynchronous command. */ 6446 case '!': 6447 /* If no asynchronous pids have been created, expand to nothing. 6448 If `set -u' has been executed, and no async processes have 6449 been created, this is an expansion error. */ 6450 if (last_asynchronous_pid == NO_PID) 6451 { 6452 if (expanded_something) 6453 *expanded_something = 0; 6454 temp = (char *)NULL; 6455 if (unbound_vars_is_error) 6456 { 6457 uerror[0] = '$'; 6458 uerror[1] = c; 6459 uerror[2] = '\0'; 6460 err_unboundvar (uerror); 6461 last_command_exit_value = EXECUTION_FAILURE; 6462 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal); 6463 } 6464 } 6465 else 6466 temp = itos (last_asynchronous_pid); 6467 break; 6468 6469 /* The only difference between this and $@ is when the arg is quoted. */ 6470 case '*': /* `$*' */ 6471 list = list_rest_of_args (); 6472 6473 /* If there are no command-line arguments, this should just 6474 disappear if there are other characters in the expansion, 6475 even if it's quoted. */ 6476 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0) 6477 temp = (char *)NULL; 6478 else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) 6479 { 6480 /* If we have "$*" we want to make a string of the positional 6481 parameters, separated by the first character of $IFS, and 6482 quote the whole string, including the separators. If IFS 6483 is unset, the parameters are separated by ' '; if $IFS is 6484 null, the parameters are concatenated. */ 6485 temp = (quoted & Q_DOUBLE_QUOTES) ? string_list_dollar_star (list) : string_list (list); 6486 temp1 = quote_string (temp); 6487 if (*temp == 0) 6488 tflag |= W_HASQUOTEDNULL; 6489 free (temp); 6490 temp = temp1; 6491 } 6492 else 6493 { 6494 /* We check whether or not we're eventually going to split $* here, 6495 for example when IFS is empty and we are processing the rhs of 6496 an assignment statement. In that case, we don't separate the 6497 arguments at all. Otherwise, if the $* is not quoted it is 6498 identical to $@ */ 6499#if 1 6500# if defined (HANDLE_MULTIBYTE) 6501 if (expand_no_split_dollar_star && ifs_firstc[0] == 0) 6502# else 6503 if (expand_no_split_dollar_star && ifs_firstc == 0) 6504# endif 6505 temp = string_list_dollar_star (list); 6506 else 6507 temp = string_list_dollar_at (list, quoted); 6508#else 6509 temp = string_list_dollar_at (list, quoted); 6510#endif 6511 if (expand_no_split_dollar_star == 0 && contains_dollar_at) 6512 *contains_dollar_at = 1; 6513 } 6514 6515 dispose_words (list); 6516 break; 6517 6518 /* When we have "$@" what we want is "$1" "$2" "$3" ... This 6519 means that we have to turn quoting off after we split into 6520 the individually quoted arguments so that the final split 6521 on the first character of $IFS is still done. */ 6522 case '@': /* `$@' */ 6523 list = list_rest_of_args (); 6524 6525 /* We want to flag the fact that we saw this. We can't turn 6526 off quoting entirely, because other characters in the 6527 string might need it (consider "\"$@\""), but we need some 6528 way to signal that the final split on the first character 6529 of $IFS should be done, even though QUOTED is 1. */ 6530 if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) 6531 *quoted_dollar_at_p = 1; 6532 if (contains_dollar_at) 6533 *contains_dollar_at = 1; 6534 6535 /* We want to separate the positional parameters with the first 6536 character of $IFS in case $IFS is something other than a space. 6537 We also want to make sure that splitting is done no matter what -- 6538 according to POSIX.2, this expands to a list of the positional 6539 parameters no matter what IFS is set to. */ 6540 temp = string_list_dollar_at (list, quoted); 6541 6542 dispose_words (list); 6543 break; 6544 6545 case LBRACE: 6546 tdesc = parameter_brace_expand (string, &zindex, quoted, 6547 quoted_dollar_at_p, 6548 contains_dollar_at); 6549 6550 if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal) 6551 return (tdesc); 6552 temp = tdesc ? tdesc->word : (char *)0; 6553 6554 /* XXX */ 6555 /* Quoted nulls should be removed if there is anything else 6556 in the string. */ 6557 /* Note that we saw the quoted null so we can add one back at 6558 the end of this function if there are no other characters 6559 in the string, discard TEMP, and go on. The exception to 6560 this is when we have "${@}" and $1 is '', since $@ needs 6561 special handling. */ 6562 if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp)) 6563 { 6564 if (had_quoted_null_p) 6565 *had_quoted_null_p = 1; 6566 if (*quoted_dollar_at_p == 0) 6567 { 6568 free (temp); 6569 tdesc->word = temp = (char *)NULL; 6570 } 6571 6572 } 6573 6574 ret = tdesc; 6575 goto return0; 6576 6577 /* Do command or arithmetic substitution. */ 6578 case LPAREN: 6579 /* We have to extract the contents of this paren substitution. */ 6580 t_index = zindex + 1; 6581 temp = extract_command_subst (string, &t_index); 6582 zindex = t_index; 6583 6584 /* For Posix.2-style `$(( ))' arithmetic substitution, 6585 extract the expression and pass it to the evaluator. */ 6586 if (temp && *temp == LPAREN) 6587 { 6588 char *temp2; 6589 temp1 = temp + 1; 6590 temp2 = savestring (temp1); 6591 t_index = strlen (temp2) - 1; 6592 6593 if (temp2[t_index] != RPAREN) 6594 { 6595 free (temp2); 6596 goto comsub; 6597 } 6598 6599 /* Cut off ending `)' */ 6600 temp2[t_index] = '\0'; 6601 6602 if (chk_arithsub (temp2, t_index) == 0) 6603 { 6604 free (temp2); 6605 goto comsub; 6606 } 6607 6608 /* Expand variables found inside the expression. */ 6609 temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES); 6610 free (temp2); 6611 6612arithsub: 6613 /* No error messages. */ 6614 this_command_name = (char *)NULL; 6615 number = evalexp (temp1, &expok); 6616 free (temp); 6617 free (temp1); 6618 if (expok == 0) 6619 { 6620 if (interactive_shell == 0 && posixly_correct) 6621 { 6622 last_command_exit_value = EXECUTION_FAILURE; 6623 return (&expand_wdesc_fatal); 6624 } 6625 else 6626 return (&expand_wdesc_error); 6627 } 6628 temp = itos (number); 6629 break; 6630 } 6631 6632comsub: 6633 if (pflags & PF_NOCOMSUB) 6634 /* we need zindex+1 because string[zindex] == RPAREN */ 6635 temp1 = substring (string, *sindex, zindex+1); 6636 else 6637 temp1 = command_substitute (temp, quoted); 6638 FREE (temp); 6639 temp = temp1; 6640 break; 6641 6642 /* Do POSIX.2d9-style arithmetic substitution. This will probably go 6643 away in a future bash release. */ 6644 case '[': 6645 /* Extract the contents of this arithmetic substitution. */ 6646 t_index = zindex + 1; 6647 temp = extract_arithmetic_subst (string, &t_index); 6648 zindex = t_index; 6649 6650 /* Do initial variable expansion. */ 6651 temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES); 6652 6653 goto arithsub; 6654 6655 default: 6656 /* Find the variable in VARIABLE_LIST. */ 6657 temp = (char *)NULL; 6658 6659 for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++) 6660 ; 6661 temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL; 6662 6663 /* If this isn't a variable name, then just output the `$'. */ 6664 if (temp1 == 0 || *temp1 == '\0') 6665 { 6666 FREE (temp1); 6667 temp = (char *)xmalloc (2); 6668 temp[0] = '$'; 6669 temp[1] = '\0'; 6670 if (expanded_something) 6671 *expanded_something = 0; 6672 goto return0; 6673 } 6674 6675 /* If the variable exists, return its value cell. */ 6676 var = find_variable (temp1); 6677 6678 if (var && invisible_p (var) == 0 && var_isset (var)) 6679 { 6680#if defined (ARRAY_VARS) 6681 if (array_p (var)) 6682 { 6683 temp = array_reference (array_cell (var), 0); 6684 if (temp) 6685 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) 6686 ? quote_string (temp) 6687 : quote_escapes (temp); 6688 else if (unbound_vars_is_error) 6689 goto unbound_variable; 6690 } 6691 else 6692#endif 6693 { 6694 temp = value_cell (var); 6695 6696 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))) 6697 ? quote_string (temp) 6698 : quote_escapes (temp); 6699 } 6700 6701 free (temp1); 6702 6703 goto return0; 6704 } 6705 6706 temp = (char *)NULL; 6707 6708unbound_variable: 6709 if (unbound_vars_is_error) 6710 err_unboundvar (temp1); 6711 else 6712 { 6713 free (temp1); 6714 goto return0; 6715 } 6716 6717 free (temp1); 6718 last_command_exit_value = EXECUTION_FAILURE; 6719 return ((unbound_vars_is_error && interactive_shell == 0) 6720 ? &expand_wdesc_fatal 6721 : &expand_wdesc_error); 6722 } 6723 6724 if (string[zindex]) 6725 zindex++; 6726 6727return0: 6728 *sindex = zindex; 6729 6730 if (ret == 0) 6731 { 6732 ret = alloc_word_desc (); 6733 ret->flags = tflag; /* XXX */ 6734 ret->word = temp; 6735 } 6736 return ret; 6737} 6738 6739/* Make a word list which is the result of parameter and variable 6740 expansion, command substitution, arithmetic substitution, and 6741 quote removal of WORD. Return a pointer to a WORD_LIST which is 6742 the result of the expansion. If WORD contains a null word, the 6743 word list returned is also null. 6744 6745 QUOTED contains flag values defined in shell.h. 6746 6747 ISEXP is used to tell expand_word_internal that the word should be 6748 treated as the result of an expansion. This has implications for 6749 how IFS characters in the word are treated. 6750 6751 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null 6752 they point to an integer value which receives information about expansion. 6753 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero. 6754 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions, 6755 else zero. 6756 6757 This only does word splitting in the case of $@ expansion. In that 6758 case, we split on ' '. */ 6759 6760/* Values for the local variable quoted_state. */ 6761#define UNQUOTED 0 6762#define PARTIALLY_QUOTED 1 6763#define WHOLLY_QUOTED 2 6764 6765static WORD_LIST * 6766expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something) 6767 WORD_DESC *word; 6768 int quoted, isexp; 6769 int *contains_dollar_at; 6770 int *expanded_something; 6771{ 6772 WORD_LIST *list; 6773 WORD_DESC *tword; 6774 6775 /* The intermediate string that we build while expanding. */ 6776 char *istring; 6777 6778 /* The current size of the above object. */ 6779 int istring_size; 6780 6781 /* Index into ISTRING. */ 6782 int istring_index; 6783 6784 /* Temporary string storage. */ 6785 char *temp, *temp1; 6786 6787 /* The text of WORD. */ 6788 register char *string; 6789 6790 /* The size of STRING. */ 6791 size_t string_size; 6792 6793 /* The index into STRING. */ 6794 int sindex; 6795 6796 /* This gets 1 if we see a $@ while quoted. */ 6797 int quoted_dollar_at; 6798 6799 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on 6800 whether WORD contains no quoting characters, a partially quoted 6801 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */ 6802 int quoted_state; 6803 6804 /* State flags */ 6805 int had_quoted_null; 6806 int has_dollar_at; 6807 int tflag; 6808 6809 int assignoff; /* If assignment, offset of `=' */ 6810 6811 register unsigned char c; /* Current character. */ 6812 int t_index; /* For calls to string_extract_xxx. */ 6813 6814 char twochars[2]; 6815 6816 DECLARE_MBSTATE; 6817 6818 istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE); 6819 istring[istring_index = 0] = '\0'; 6820 quoted_dollar_at = had_quoted_null = has_dollar_at = 0; 6821 quoted_state = UNQUOTED; 6822 6823 string = word->word; 6824 if (string == 0) 6825 goto finished_with_string; 6826 /* Don't need the string length for the SADD... and COPY_ macros unless 6827 multibyte characters are possible. */ 6828 string_size = (MB_CUR_MAX > 1) ? strlen (string) : 1; 6829 6830 if (contains_dollar_at) 6831 *contains_dollar_at = 0; 6832 6833 assignoff = -1; 6834 6835 /* Begin the expansion. */ 6836 6837 for (sindex = 0; ;) 6838 { 6839 c = string[sindex]; 6840 6841 /* Case on toplevel character. */ 6842 switch (c) 6843 { 6844 case '\0': 6845 goto finished_with_string; 6846 6847 case CTLESC: 6848 sindex++; 6849#if HANDLE_MULTIBYTE 6850 if (MB_CUR_MAX > 1 && string[sindex]) 6851 { 6852 SADD_MBQCHAR_BODY(temp, string, sindex, string_size); 6853 } 6854 else 6855#endif 6856 { 6857 temp = (char *)xmalloc (3); 6858 temp[0] = CTLESC; 6859 temp[1] = c = string[sindex]; 6860 temp[2] = '\0'; 6861 } 6862 6863dollar_add_string: 6864 if (string[sindex]) 6865 sindex++; 6866 6867add_string: 6868 if (temp) 6869 { 6870 istring = sub_append_string (temp, istring, &istring_index, &istring_size); 6871 temp = (char *)0; 6872 } 6873 6874 break; 6875 6876#if defined (PROCESS_SUBSTITUTION) 6877 /* Process substitution. */ 6878 case '<': 6879 case '>': 6880 { 6881 if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct) 6882 { 6883 sindex--; /* add_character: label increments sindex */ 6884 goto add_character; 6885 } 6886 else 6887 t_index = sindex + 1; /* skip past both '<' and LPAREN */ 6888 6889 temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/ 6890 sindex = t_index; 6891 6892 /* If the process substitution specification is `<()', we want to 6893 open the pipe for writing in the child and produce output; if 6894 it is `>()', we want to open the pipe for reading in the child 6895 and consume input. */ 6896 temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0; 6897 6898 FREE (temp1); 6899 6900 goto dollar_add_string; 6901 } 6902#endif /* PROCESS_SUBSTITUTION */ 6903 6904 case '=': 6905 /* Posix.2 section 3.6.1 says that tildes following `=' in words 6906 which are not assignment statements are not expanded. If the 6907 shell isn't in posix mode, though, we perform tilde expansion 6908 on `likely candidate' unquoted assignment statements (flags 6909 include W_ASSIGNMENT but not W_QUOTED). A likely candidate 6910 contains an unquoted :~ or =~. Something to think about: we 6911 now have a flag that says to perform tilde expansion on arguments 6912 to `assignment builtins' like declare and export that look like 6913 assignment statements. We now do tilde expansion on such words 6914 even in POSIX mode. */ 6915 if (word->flags & (W_ASSIGNRHS|W_NOTILDE)) 6916 goto add_character; 6917 /* If we're not in posix mode or forcing assignment-statement tilde 6918 expansion, note where the `=' appears in the word and prepare to 6919 do tilde expansion following the first `='. */ 6920 if ((word->flags & W_ASSIGNMENT) && 6921 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) && 6922 assignoff == -1 && sindex > 0) 6923 assignoff = sindex; 6924 if (sindex == assignoff && string[sindex+1] == '~') /* XXX */ 6925 word->flags |= W_ITILDE; 6926#if 0 6927 else if ((word->flags & W_ASSIGNMENT) && 6928 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) && 6929 string[sindex+1] == '~') 6930 word->flags |= W_ITILDE; 6931#endif 6932 goto add_character; 6933 6934 case ':': 6935 if (word->flags & W_NOTILDE) 6936 goto add_character; 6937 6938 if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) && 6939 string[sindex+1] == '~') 6940 word->flags |= W_ITILDE; 6941 goto add_character; 6942 6943 case '~': 6944 /* If the word isn't supposed to be tilde expanded, or we're not 6945 at the start of a word or after an unquoted : or = in an 6946 assignment statement, we don't do tilde expansion. */ 6947 if ((word->flags & (W_NOTILDE|W_DQUOTE)) || 6948 (sindex > 0 && ((word->flags & W_ITILDE) == 0)) || 6949 (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) 6950 { 6951 word->flags &= ~W_ITILDE; 6952 goto add_character; 6953 } 6954 6955 if (word->flags & W_ASSIGNRHS) 6956 tflag = 2; 6957 else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP)) 6958 tflag = 1; 6959 else 6960 tflag = 0; 6961 6962 temp = bash_tilde_find_word (string + sindex, tflag, &t_index); 6963 6964 word->flags &= ~W_ITILDE; 6965 6966 if (temp && *temp && t_index > 0) 6967 { 6968 temp1 = bash_tilde_expand (temp, tflag); 6969 if (temp1 && *temp1 == '~' && STREQ (temp, temp1)) 6970 { 6971 FREE (temp); 6972 FREE (temp1); 6973 goto add_character; /* tilde expansion failed */ 6974 } 6975 free (temp); 6976 temp = temp1; 6977 sindex += t_index; 6978 goto add_string; 6979 } 6980 else 6981 { 6982 FREE (temp); 6983 goto add_character; 6984 } 6985 6986 case '$': 6987 if (expanded_something) 6988 *expanded_something = 1; 6989 6990 has_dollar_at = 0; 6991 tword = param_expand (string, &sindex, quoted, expanded_something, 6992 &has_dollar_at, "ed_dollar_at, 6993 &had_quoted_null, 6994 (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0); 6995 6996 if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal) 6997 { 6998 free (string); 6999 free (istring); 7000 return ((tword == &expand_wdesc_error) ? &expand_word_error 7001 : &expand_word_fatal); 7002 } 7003 if (contains_dollar_at && has_dollar_at) 7004 *contains_dollar_at = 1; 7005 7006 if (tword && (tword->flags & W_HASQUOTEDNULL)) 7007 had_quoted_null = 1; 7008 7009 temp = tword->word; 7010 dispose_word_desc (tword); 7011 7012 goto add_string; 7013 break; 7014 7015 case '`': /* Backquoted command substitution. */ 7016 { 7017 t_index = sindex++; 7018 7019 temp = string_extract (string, &sindex, "`", EX_REQMATCH); 7020 /* The test of sindex against t_index is to allow bare instances of 7021 ` to pass through, for backwards compatibility. */ 7022 if (temp == &extract_string_error || temp == &extract_string_fatal) 7023 { 7024 if (sindex - 1 == t_index) 7025 { 7026 sindex = t_index; 7027 goto add_character; 7028 } 7029 report_error ("bad substitution: no closing \"`\" in %s", string+t_index); 7030 free (string); 7031 free (istring); 7032 return ((temp == &extract_string_error) ? &expand_word_error 7033 : &expand_word_fatal); 7034 } 7035 7036 if (expanded_something) 7037 *expanded_something = 1; 7038 7039 if (word->flags & W_NOCOMSUB) 7040 /* sindex + 1 because string[sindex] == '`' */ 7041 temp1 = substring (string, t_index, sindex + 1); 7042 else 7043 { 7044 de_backslash (temp); 7045 temp1 = command_substitute (temp, quoted); 7046 } 7047 FREE (temp); 7048 temp = temp1; 7049 goto dollar_add_string; 7050 } 7051 7052 case '\\': 7053 if (string[sindex + 1] == '\n') 7054 { 7055 sindex += 2; 7056 continue; 7057 } 7058 7059 c = string[++sindex]; 7060 7061 if (quoted & Q_HERE_DOCUMENT) 7062 tflag = CBSHDOC; 7063 else if (quoted & Q_DOUBLE_QUOTES) 7064 tflag = CBSDQUOTE; 7065 else 7066 tflag = 0; 7067 7068 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0)) 7069 { 7070 SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size); 7071 } 7072 else if (c == 0) 7073 { 7074 c = CTLNUL; 7075 sindex--; /* add_character: label increments sindex */ 7076 goto add_character; 7077 } 7078 else 7079 { 7080 SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size); 7081 } 7082 7083 sindex++; 7084add_twochars: 7085 /* BEFORE jumping here, we need to increment sindex if appropriate */ 7086 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, 7087 DEFAULT_ARRAY_SIZE); 7088 istring[istring_index++] = twochars[0]; 7089 istring[istring_index++] = twochars[1]; 7090 istring[istring_index] = '\0'; 7091 7092 break; 7093 7094 case '"': 7095#if 0 7096 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE)) 7097#else 7098 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) 7099#endif 7100 goto add_character; 7101 7102 t_index = ++sindex; 7103 temp = string_extract_double_quoted (string, &sindex, 0); 7104 7105 /* If the quotes surrounded the entire string, then the 7106 whole word was quoted. */ 7107 quoted_state = (t_index == 1 && string[sindex] == '\0') 7108 ? WHOLLY_QUOTED 7109 : PARTIALLY_QUOTED; 7110 7111 if (temp && *temp) 7112 { 7113 tword = alloc_word_desc (); 7114 tword->word = temp; 7115 7116 temp = (char *)NULL; 7117 7118 has_dollar_at = 0; 7119 /* Need to get W_HASQUOTEDNULL flag through this function. */ 7120 list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL); 7121 7122 if (list == &expand_word_error || list == &expand_word_fatal) 7123 { 7124 free (istring); 7125 free (string); 7126 /* expand_word_internal has already freed temp_word->word 7127 for us because of the way it prints error messages. */ 7128 tword->word = (char *)NULL; 7129 dispose_word (tword); 7130 return list; 7131 } 7132 7133 dispose_word (tword); 7134 7135 /* "$@" (a double-quoted dollar-at) expands into nothing, 7136 not even a NULL word, when there are no positional 7137 parameters. */ 7138 if (list == 0 && has_dollar_at) 7139 { 7140 quoted_dollar_at++; 7141 break; 7142 } 7143 7144 /* If we get "$@", we know we have expanded something, so we 7145 need to remember it for the final split on $IFS. This is 7146 a special case; it's the only case where a quoted string 7147 can expand into more than one word. It's going to come back 7148 from the above call to expand_word_internal as a list with 7149 a single word, in which all characters are quoted and 7150 separated by blanks. What we want to do is to turn it back 7151 into a list for the next piece of code. */ 7152 if (list) 7153 dequote_list (list); 7154 7155 if (list && list->word && (list->word->flags & W_HASQUOTEDNULL)) 7156 had_quoted_null = 1; 7157 7158 if (has_dollar_at) 7159 { 7160 quoted_dollar_at++; 7161 if (contains_dollar_at) 7162 *contains_dollar_at = 1; 7163 if (expanded_something) 7164 *expanded_something = 1; 7165 } 7166 } 7167 else 7168 { 7169 /* What we have is "". This is a minor optimization. */ 7170 FREE (temp); 7171 list = (WORD_LIST *)NULL; 7172 } 7173 7174 /* The code above *might* return a list (consider the case of "$@", 7175 where it returns "$1", "$2", etc.). We can't throw away the 7176 rest of the list, and we have to make sure each word gets added 7177 as quoted. We test on tresult->next: if it is non-NULL, we 7178 quote the whole list, save it to a string with string_list, and 7179 add that string. We don't need to quote the results of this 7180 (and it would be wrong, since that would quote the separators 7181 as well), so we go directly to add_string. */ 7182 if (list) 7183 { 7184 if (list->next) 7185 { 7186 /* Testing quoted_dollar_at makes sure that "$@" is 7187 split correctly when $IFS does not contain a space. */ 7188 temp = quoted_dollar_at 7189 ? string_list_dollar_at (list, Q_DOUBLE_QUOTES) 7190 : string_list (quote_list (list)); 7191 dispose_words (list); 7192 goto add_string; 7193 } 7194 else 7195 { 7196 temp = savestring (list->word->word); 7197 tflag = list->word->flags; 7198 dispose_words (list); 7199 7200 /* If the string is not a quoted null string, we want 7201 to remove any embedded unquoted CTLNUL characters. 7202 We do not want to turn quoted null strings back into 7203 the empty string, though. We do this because we 7204 want to remove any quoted nulls from expansions that 7205 contain other characters. For example, if we have 7206 x"$*"y or "x$*y" and there are no positional parameters, 7207 the $* should expand into nothing. */ 7208 /* We use the W_HASQUOTEDNULL flag to differentiate the 7209 cases: a quoted null character as above and when 7210 CTLNUL is contained in the (non-null) expansion 7211 of some variable. We use the had_quoted_null flag to 7212 pass the value through this function to its caller. */ 7213 if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0) 7214 remove_quoted_nulls (temp); /* XXX */ 7215 } 7216 } 7217 else 7218 temp = (char *)NULL; 7219 7220 /* We do not want to add quoted nulls to strings that are only 7221 partially quoted; we can throw them away. */ 7222 if (temp == 0 && quoted_state == PARTIALLY_QUOTED) 7223 continue; 7224 7225 add_quoted_string: 7226 7227 if (temp) 7228 { 7229 temp1 = temp; 7230 temp = quote_string (temp); 7231 free (temp1); 7232 goto add_string; 7233 } 7234 else 7235 { 7236 /* Add NULL arg. */ 7237 c = CTLNUL; 7238 sindex--; /* add_character: label increments sindex */ 7239 goto add_character; 7240 } 7241 7242 /* break; */ 7243 7244 case '\'': 7245#if 0 7246 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE)) 7247#else 7248 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) 7249#endif 7250 goto add_character; 7251 7252 t_index = ++sindex; 7253 temp = string_extract_single_quoted (string, &sindex); 7254 7255 /* If the entire STRING was surrounded by single quotes, 7256 then the string is wholly quoted. */ 7257 quoted_state = (t_index == 1 && string[sindex] == '\0') 7258 ? WHOLLY_QUOTED 7259 : PARTIALLY_QUOTED; 7260 7261 /* If all we had was '', it is a null expansion. */ 7262 if (*temp == '\0') 7263 { 7264 free (temp); 7265 temp = (char *)NULL; 7266 } 7267 else 7268 remove_quoted_escapes (temp); /* ??? */ 7269 7270 /* We do not want to add quoted nulls to strings that are only 7271 partially quoted; such nulls are discarded. */ 7272 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED)) 7273 continue; 7274 7275 /* If we have a quoted null expansion, add a quoted NULL to istring. */ 7276 if (temp == 0) 7277 { 7278 c = CTLNUL; 7279 sindex--; /* add_character: label increments sindex */ 7280 goto add_character; 7281 } 7282 else 7283 goto add_quoted_string; 7284 7285 /* break; */ 7286 7287 default: 7288 /* This is the fix for " $@ " */ 7289 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c))) 7290 { 7291 if (string[sindex]) /* from old goto dollar_add_string */ 7292 sindex++; 7293 if (c == 0) 7294 { 7295 c = CTLNUL; 7296 goto add_character; 7297 } 7298 else 7299 { 7300#if HANDLE_MULTIBYTE 7301 if (MB_CUR_MAX > 1) 7302 sindex--; 7303 7304 if (MB_CUR_MAX > 1) 7305 { 7306 SADD_MBQCHAR_BODY(temp, string, sindex, string_size); 7307 } 7308 else 7309#endif 7310 { 7311 twochars[0] = CTLESC; 7312 twochars[1] = c; 7313 goto add_twochars; 7314 } 7315 } 7316 } 7317 7318 SADD_MBCHAR (temp, string, sindex, string_size); 7319 7320 add_character: 7321 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size, 7322 DEFAULT_ARRAY_SIZE); 7323 istring[istring_index++] = c; 7324 istring[istring_index] = '\0'; 7325 7326 /* Next character. */ 7327 sindex++; 7328 } 7329 } 7330 7331finished_with_string: 7332 /* OK, we're ready to return. If we have a quoted string, and 7333 quoted_dollar_at is not set, we do no splitting at all; otherwise 7334 we split on ' '. The routines that call this will handle what to 7335 do if nothing has been expanded. */ 7336 7337 /* Partially and wholly quoted strings which expand to the empty 7338 string are retained as an empty arguments. Unquoted strings 7339 which expand to the empty string are discarded. The single 7340 exception is the case of expanding "$@" when there are no 7341 positional parameters. In that case, we discard the expansion. */ 7342 7343 /* Because of how the code that handles "" and '' in partially 7344 quoted strings works, we need to make ISTRING into a QUOTED_NULL 7345 if we saw quoting characters, but the expansion was empty. 7346 "" and '' are tossed away before we get to this point when 7347 processing partially quoted strings. This makes "" and $xxx"" 7348 equivalent when xxx is unset. We also look to see whether we 7349 saw a quoted null from a ${} expansion and add one back if we 7350 need to. */ 7351 7352 /* If we expand to nothing and there were no single or double quotes 7353 in the word, we throw it away. Otherwise, we return a NULL word. 7354 The single exception is for $@ surrounded by double quotes when 7355 there are no positional parameters. In that case, we also throw 7356 the word away. */ 7357 7358 if (*istring == '\0') 7359 { 7360 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED)) 7361 { 7362 istring[0] = CTLNUL; 7363 istring[1] = '\0'; 7364 tword = make_bare_word (istring); 7365 tword->flags |= W_HASQUOTEDNULL; /* XXX */ 7366 list = make_word_list (tword, (WORD_LIST *)NULL); 7367 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) 7368 tword->flags |= W_QUOTED; 7369 } 7370 /* According to sh, ksh, and Posix.2, if a word expands into nothing 7371 and a double-quoted "$@" appears anywhere in it, then the entire 7372 word is removed. */ 7373 else if (quoted_state == UNQUOTED || quoted_dollar_at) 7374 list = (WORD_LIST *)NULL; 7375#if 0 7376 else 7377 { 7378 tword = make_bare_word (istring); 7379 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) 7380 tword->flags |= W_QUOTED; 7381 list = make_word_list (tword, (WORD_LIST *)NULL); 7382 } 7383#else 7384 else 7385 list = (WORD_LIST *)NULL; 7386#endif 7387 } 7388 else if (word->flags & W_NOSPLIT) 7389 { 7390 tword = make_bare_word (istring); 7391 if (word->flags & W_ASSIGNMENT) 7392 tword->flags |= W_ASSIGNMENT; /* XXX */ 7393 if (word->flags & W_COMPASSIGN) 7394 tword->flags |= W_COMPASSIGN; /* XXX */ 7395 if (word->flags & W_NOGLOB) 7396 tword->flags |= W_NOGLOB; /* XXX */ 7397 if (word->flags & W_NOEXPAND) 7398 tword->flags |= W_NOEXPAND; /* XXX */ 7399 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) 7400 tword->flags |= W_QUOTED; 7401 if (had_quoted_null) 7402 tword->flags |= W_HASQUOTEDNULL; 7403 list = make_word_list (tword, (WORD_LIST *)NULL); 7404 } 7405 else 7406 { 7407 char *ifs_chars; 7408 7409 ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL; 7410 7411 /* If we have $@, we need to split the results no matter what. If 7412 IFS is unset or NULL, string_list_dollar_at has separated the 7413 positional parameters with a space, so we split on space (we have 7414 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set, 7415 string_list_dollar_at has separated the positional parameters 7416 with the first character of $IFS, so we split on $IFS. */ 7417 if (has_dollar_at && ifs_chars) 7418 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1); 7419 else 7420 { 7421 tword = make_bare_word (istring); 7422 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED)) 7423 tword->flags |= W_QUOTED; 7424 if (word->flags & W_ASSIGNMENT) 7425 tword->flags |= W_ASSIGNMENT; 7426 if (word->flags & W_COMPASSIGN) 7427 tword->flags |= W_COMPASSIGN; 7428 if (word->flags & W_NOGLOB) 7429 tword->flags |= W_NOGLOB; 7430 if (word->flags & W_NOEXPAND) 7431 tword->flags |= W_NOEXPAND; 7432 if (had_quoted_null) 7433 tword->flags |= W_HASQUOTEDNULL; /* XXX */ 7434 list = make_word_list (tword, (WORD_LIST *)NULL); 7435 } 7436 } 7437 7438 free (istring); 7439 return (list); 7440} 7441 7442/* **************************************************************** */ 7443/* */ 7444/* Functions for Quote Removal */ 7445/* */ 7446/* **************************************************************** */ 7447 7448/* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the 7449 backslash quoting rules for within double quotes or a here document. */ 7450char * 7451string_quote_removal (string, quoted) 7452 char *string; 7453 int quoted; 7454{ 7455 size_t slen; 7456 char *r, *result_string, *temp, *send; 7457 int sindex, tindex, dquote; 7458 unsigned char c; 7459 DECLARE_MBSTATE; 7460 7461 /* The result can be no longer than the original string. */ 7462 slen = strlen (string); 7463 send = string + slen; 7464 7465 r = result_string = (char *)xmalloc (slen + 1); 7466 7467 for (dquote = sindex = 0; c = string[sindex];) 7468 { 7469 switch (c) 7470 { 7471 case '\\': 7472 c = string[++sindex]; 7473 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0) 7474 *r++ = '\\'; 7475 /* FALLTHROUGH */ 7476 7477 default: 7478 SCOPY_CHAR_M (r, string, send, sindex); 7479 break; 7480 7481 case '\'': 7482 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) 7483 { 7484 *r++ = c; 7485 sindex++; 7486 break; 7487 } 7488 tindex = sindex + 1; 7489 temp = string_extract_single_quoted (string, &tindex); 7490 if (temp) 7491 { 7492 strcpy (r, temp); 7493 r += strlen (r); 7494 free (temp); 7495 } 7496 sindex = tindex; 7497 break; 7498 7499 case '"': 7500 dquote = 1 - dquote; 7501 sindex++; 7502 break; 7503 } 7504 } 7505 *r = '\0'; 7506 return (result_string); 7507} 7508 7509#if 0 7510/* UNUSED */ 7511/* Perform quote removal on word WORD. This allocates and returns a new 7512 WORD_DESC *. */ 7513WORD_DESC * 7514word_quote_removal (word, quoted) 7515 WORD_DESC *word; 7516 int quoted; 7517{ 7518 WORD_DESC *w; 7519 char *t; 7520 7521 t = string_quote_removal (word->word, quoted); 7522 w = alloc_word_desc (); 7523 w->word = t ? t : savestring (""); 7524 return (w); 7525} 7526 7527/* Perform quote removal on all words in LIST. If QUOTED is non-zero, 7528 the members of the list are treated as if they are surrounded by 7529 double quotes. Return a new list, or NULL if LIST is NULL. */ 7530WORD_LIST * 7531word_list_quote_removal (list, quoted) 7532 WORD_LIST *list; 7533 int quoted; 7534{ 7535 WORD_LIST *result, *t, *tresult, *e; 7536 7537 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next) 7538 { 7539 tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL); 7540#if 0 7541 result = (WORD_LIST *) list_append (result, tresult); 7542#else 7543 if (result == 0) 7544 result = e = tresult; 7545 else 7546 { 7547 e->next = tresult; 7548 while (e->next) 7549 e = e->next; 7550 } 7551#endif 7552 } 7553 return (result); 7554} 7555#endif 7556 7557/******************************************* 7558 * * 7559 * Functions to perform word splitting * 7560 * * 7561 *******************************************/ 7562 7563void 7564setifs (v) 7565 SHELL_VAR *v; 7566{ 7567 char *t; 7568 unsigned char uc; 7569 7570 ifs_var = v; 7571#if 0 7572 ifs_value = v ? value_cell (v) : " \t\n"; 7573#else 7574 ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n"; 7575#endif 7576 7577 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet 7578 handle multibyte chars in IFS */ 7579 memset (ifs_cmap, '\0', sizeof (ifs_cmap)); 7580 for (t = ifs_value ; t && *t; t++) 7581 { 7582 uc = *t; 7583 ifs_cmap[uc] = 1; 7584 } 7585 7586#if defined (HANDLE_MULTIBYTE) 7587 if (ifs_value == 0) 7588 { 7589 ifs_firstc[0] = '\0'; 7590 ifs_firstc_len = 1; 7591 } 7592 else 7593 { 7594 size_t ifs_len; 7595 ifs_len = strnlen (ifs_value, MB_CUR_MAX); 7596 ifs_firstc_len = MBLEN (ifs_value, ifs_len); 7597 if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len)) 7598 { 7599 ifs_firstc[0] = ifs_value[0]; 7600 ifs_firstc[1] = '\0'; 7601 ifs_firstc_len = 1; 7602 } 7603 else 7604 memcpy (ifs_firstc, ifs_value, ifs_firstc_len); 7605 } 7606#else 7607 ifs_firstc = ifs_value ? *ifs_value : 0; 7608#endif 7609} 7610 7611char * 7612getifs () 7613{ 7614 return ifs_value; 7615} 7616 7617/* This splits a single word into a WORD LIST on $IFS, but only if the word 7618 is not quoted. list_string () performs quote removal for us, even if we 7619 don't do any splitting. */ 7620WORD_LIST * 7621word_split (w, ifs_chars) 7622 WORD_DESC *w; 7623 char *ifs_chars; 7624{ 7625 WORD_LIST *result; 7626 7627 if (w) 7628 { 7629 char *xifs; 7630 7631 xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars; 7632 result = list_string (w->word, xifs, w->flags & W_QUOTED); 7633 } 7634 else 7635 result = (WORD_LIST *)NULL; 7636 7637 return (result); 7638} 7639 7640/* Perform word splitting on LIST and return the RESULT. It is possible 7641 to return (WORD_LIST *)NULL. */ 7642static WORD_LIST * 7643word_list_split (list) 7644 WORD_LIST *list; 7645{ 7646 WORD_LIST *result, *t, *tresult, *e; 7647 7648 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next) 7649 { 7650 tresult = word_split (t->word, ifs_value); 7651 if (result == 0) 7652 result = e = tresult; 7653 else 7654 { 7655 e->next = tresult; 7656 while (e->next) 7657 e = e->next; 7658 } 7659 } 7660 return (result); 7661} 7662 7663/************************************************** 7664 * * 7665 * Functions to expand an entire WORD_LIST * 7666 * * 7667 **************************************************/ 7668 7669/* Do any word-expansion-specific cleanup and jump to top_level */ 7670static void 7671exp_jump_to_top_level (v) 7672 int v; 7673{ 7674 /* Cleanup code goes here. */ 7675 expand_no_split_dollar_star = 0; /* XXX */ 7676 expanding_redir = 0; 7677 7678 if (parse_and_execute_level == 0) 7679 top_level_cleanup (); /* from sig.c */ 7680 7681 7682 jump_to_top_level (v); 7683} 7684 7685/* Put NLIST (which is a WORD_LIST * of only one element) at the front of 7686 ELIST, and set ELIST to the new list. */ 7687#define PREPEND_LIST(nlist, elist) \ 7688 do { nlist->next = elist; elist = nlist; } while (0) 7689 7690/* Separate out any initial variable assignments from TLIST. If set -k has 7691 been executed, remove all assignment statements from TLIST. Initial 7692 variable assignments and other environment assignments are placed 7693 on SUBST_ASSIGN_VARLIST. */ 7694static WORD_LIST * 7695separate_out_assignments (tlist) 7696 WORD_LIST *tlist; 7697{ 7698 register WORD_LIST *vp, *lp; 7699 7700 if (!tlist) 7701 return ((WORD_LIST *)NULL); 7702 7703 if (subst_assign_varlist) 7704 dispose_words (subst_assign_varlist); /* Clean up after previous error */ 7705 7706 subst_assign_varlist = (WORD_LIST *)NULL; 7707 vp = lp = tlist; 7708 7709 /* Separate out variable assignments at the start of the command. 7710 Loop invariant: vp->next == lp 7711 Loop postcondition: 7712 lp = list of words left after assignment statements skipped 7713 tlist = original list of words 7714 */ 7715 while (lp && (lp->word->flags & W_ASSIGNMENT)) 7716 { 7717 vp = lp; 7718 lp = lp->next; 7719 } 7720 7721 /* If lp != tlist, we have some initial assignment statements. 7722 We make SUBST_ASSIGN_VARLIST point to the list of assignment 7723 words and TLIST point to the remaining words. */ 7724 if (lp != tlist) 7725 { 7726 subst_assign_varlist = tlist; 7727 /* ASSERT(vp->next == lp); */ 7728 vp->next = (WORD_LIST *)NULL; /* terminate variable list */ 7729 tlist = lp; /* remainder of word list */ 7730 } 7731 7732 /* vp == end of variable list */ 7733 /* tlist == remainder of original word list without variable assignments */ 7734 if (!tlist) 7735 /* All the words in tlist were assignment statements */ 7736 return ((WORD_LIST *)NULL); 7737 7738 /* ASSERT(tlist != NULL); */ 7739 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */ 7740 7741 /* If the -k option is in effect, we need to go through the remaining 7742 words, separate out the assignment words, and place them on 7743 SUBST_ASSIGN_VARLIST. */ 7744 if (place_keywords_in_env) 7745 { 7746 WORD_LIST *tp; /* tp == running pointer into tlist */ 7747 7748 tp = tlist; 7749 lp = tlist->next; 7750 7751 /* Loop Invariant: tp->next == lp */ 7752 /* Loop postcondition: tlist == word list without assignment statements */ 7753 while (lp) 7754 { 7755 if (lp->word->flags & W_ASSIGNMENT) 7756 { 7757 /* Found an assignment statement, add this word to end of 7758 subst_assign_varlist (vp). */ 7759 if (!subst_assign_varlist) 7760 subst_assign_varlist = vp = lp; 7761 else 7762 { 7763 vp->next = lp; 7764 vp = lp; 7765 } 7766 7767 /* Remove the word pointed to by LP from TLIST. */ 7768 tp->next = lp->next; 7769 /* ASSERT(vp == lp); */ 7770 lp->next = (WORD_LIST *)NULL; 7771 lp = tp->next; 7772 } 7773 else 7774 { 7775 tp = lp; 7776 lp = lp->next; 7777 } 7778 } 7779 } 7780 return (tlist); 7781} 7782 7783#define WEXP_VARASSIGN 0x001 7784#define WEXP_BRACEEXP 0x002 7785#define WEXP_TILDEEXP 0x004 7786#define WEXP_PARAMEXP 0x008 7787#define WEXP_PATHEXP 0x010 7788 7789/* All of the expansions, including variable assignments at the start of 7790 the list. */ 7791#define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP) 7792 7793/* All of the expansions except variable assignments at the start of 7794 the list. */ 7795#define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP) 7796 7797/* All of the `shell expansions': brace expansion, tilde expansion, parameter 7798 expansion, command substitution, arithmetic expansion, word splitting, and 7799 quote removal. */ 7800#define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP) 7801 7802/* Take the list of words in LIST and do the various substitutions. Return 7803 a new list of words which is the expanded list, and without things like 7804 variable assignments. */ 7805 7806WORD_LIST * 7807expand_words (list) 7808 WORD_LIST *list; 7809{ 7810 return (expand_word_list_internal (list, WEXP_ALL)); 7811} 7812 7813/* Same as expand_words (), but doesn't hack variable or environment 7814 variables. */ 7815WORD_LIST * 7816expand_words_no_vars (list) 7817 WORD_LIST *list; 7818{ 7819 return (expand_word_list_internal (list, WEXP_NOVARS)); 7820} 7821 7822WORD_LIST * 7823expand_words_shellexp (list) 7824 WORD_LIST *list; 7825{ 7826 return (expand_word_list_internal (list, WEXP_SHELLEXP)); 7827} 7828 7829static WORD_LIST * 7830glob_expand_word_list (tlist, eflags) 7831 WORD_LIST *tlist; 7832 int eflags; 7833{ 7834 char **glob_array, *temp_string; 7835 register int glob_index; 7836 WORD_LIST *glob_list, *output_list, *disposables, *next; 7837 WORD_DESC *tword; 7838 7839 output_list = disposables = (WORD_LIST *)NULL; 7840 glob_array = (char **)NULL; 7841 while (tlist) 7842 { 7843 /* For each word, either globbing is attempted or the word is 7844 added to orig_list. If globbing succeeds, the results are 7845 added to orig_list and the word (tlist) is added to the list 7846 of disposable words. If globbing fails and failed glob 7847 expansions are left unchanged (the shell default), the 7848 original word is added to orig_list. If globbing fails and 7849 failed glob expansions are removed, the original word is 7850 added to the list of disposable words. orig_list ends up 7851 in reverse order and requires a call to REVERSE_LIST to 7852 be set right. After all words are examined, the disposable 7853 words are freed. */ 7854 next = tlist->next; 7855 7856 /* If the word isn't an assignment and contains an unquoted 7857 pattern matching character, then glob it. */ 7858 if ((tlist->word->flags & W_NOGLOB) == 0 && 7859 unquoted_glob_pattern_p (tlist->word->word)) 7860 { 7861 glob_array = shell_glob_filename (tlist->word->word); 7862 7863 /* Handle error cases. 7864 I don't think we should report errors like "No such file 7865 or directory". However, I would like to report errors 7866 like "Read failed". */ 7867 7868 if (glob_array == 0 || GLOB_FAILED (glob_array)) 7869 { 7870 glob_array = (char **)xmalloc (sizeof (char *)); 7871 glob_array[0] = (char *)NULL; 7872 } 7873 7874 /* Dequote the current word in case we have to use it. */ 7875 if (glob_array[0] == NULL) 7876 { 7877 temp_string = dequote_string (tlist->word->word); 7878 free (tlist->word->word); 7879 tlist->word->word = temp_string; 7880 } 7881 7882 /* Make the array into a word list. */ 7883 glob_list = (WORD_LIST *)NULL; 7884 for (glob_index = 0; glob_array[glob_index]; glob_index++) 7885 { 7886 tword = make_bare_word (glob_array[glob_index]); 7887 tword->flags |= W_GLOBEXP; /* XXX */ 7888 glob_list = make_word_list (tword, glob_list); 7889 } 7890 7891 if (glob_list) 7892 { 7893 output_list = (WORD_LIST *)list_append (glob_list, output_list); 7894 PREPEND_LIST (tlist, disposables); 7895 } 7896 else if (fail_glob_expansion != 0) 7897 { 7898 report_error (_("no match: %s"), tlist->word->word); 7899 exp_jump_to_top_level (DISCARD); 7900 } 7901 else if (allow_null_glob_expansion == 0) 7902 { 7903 /* Failed glob expressions are left unchanged. */ 7904 PREPEND_LIST (tlist, output_list); 7905 } 7906 else 7907 { 7908 /* Failed glob expressions are removed. */ 7909 PREPEND_LIST (tlist, disposables); 7910 } 7911 } 7912 else 7913 { 7914 /* Dequote the string. */ 7915 temp_string = dequote_string (tlist->word->word); 7916 free (tlist->word->word); 7917 tlist->word->word = temp_string; 7918 PREPEND_LIST (tlist, output_list); 7919 } 7920 7921 strvec_dispose (glob_array); 7922 glob_array = (char **)NULL; 7923 7924 tlist = next; 7925 } 7926 7927 if (disposables) 7928 dispose_words (disposables); 7929 7930 if (output_list) 7931 output_list = REVERSE_LIST (output_list, WORD_LIST *); 7932 7933 return (output_list); 7934} 7935 7936#if defined (BRACE_EXPANSION) 7937static WORD_LIST * 7938brace_expand_word_list (tlist, eflags) 7939 WORD_LIST *tlist; 7940 int eflags; 7941{ 7942 register char **expansions; 7943 char *temp_string; 7944 WORD_LIST *disposables, *output_list, *next; 7945 WORD_DESC *w; 7946 int eindex; 7947 7948 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next) 7949 { 7950 next = tlist->next; 7951 7952 /* Only do brace expansion if the word has a brace character. If 7953 not, just add the word list element to BRACES and continue. In 7954 the common case, at least when running shell scripts, this will 7955 degenerate to a bunch of calls to `xstrchr', and then what is 7956 basically a reversal of TLIST into BRACES, which is corrected 7957 by a call to REVERSE_LIST () on BRACES when the end of TLIST 7958 is reached. */ 7959 if (xstrchr (tlist->word->word, LBRACE)) 7960 { 7961 expansions = brace_expand (tlist->word->word); 7962 7963 for (eindex = 0; temp_string = expansions[eindex]; eindex++) 7964 { 7965 w = make_word (temp_string); 7966 /* If brace expansion didn't change the word, preserve 7967 the flags. We may want to preserve the flags 7968 unconditionally someday -- XXX */ 7969 if (STREQ (temp_string, tlist->word->word)) 7970 w->flags = tlist->word->flags; 7971 output_list = make_word_list (w, output_list); 7972 free (expansions[eindex]); 7973 } 7974 free (expansions); 7975 7976 /* Add TLIST to the list of words to be freed after brace 7977 expansion has been performed. */ 7978 PREPEND_LIST (tlist, disposables); 7979 } 7980 else 7981 PREPEND_LIST (tlist, output_list); 7982 } 7983 7984 if (disposables) 7985 dispose_words (disposables); 7986 7987 if (output_list) 7988 output_list = REVERSE_LIST (output_list, WORD_LIST *); 7989 7990 return (output_list); 7991} 7992#endif 7993 7994static WORD_LIST * 7995shell_expand_word_list (tlist, eflags) 7996 WORD_LIST *tlist; 7997 int eflags; 7998{ 7999 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list; 8000 int expanded_something, has_dollar_at; 8001 char *temp_string; 8002 8003 /* We do tilde expansion all the time. This is what 1003.2 says. */ 8004 new_list = (WORD_LIST *)NULL; 8005 for (orig_list = tlist; tlist; tlist = next) 8006 { 8007 temp_string = tlist->word->word; 8008 8009 next = tlist->next; 8010 8011#if defined (ARRAY_VARS) 8012 /* If this is a compound array assignment to a builtin that accepts 8013 such assignments (e.g., `declare'), take the assignment and perform 8014 it separately, handling the semantics of declarations inside shell 8015 functions. This avoids the double-evaluation of such arguments, 8016 because `declare' does some evaluation of compound assignments on 8017 its own. */ 8018 if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG)) 8019 { 8020 int t; 8021 8022 t = do_word_assignment (tlist->word); 8023 if (t == 0) 8024 { 8025 last_command_exit_value = EXECUTION_FAILURE; 8026 exp_jump_to_top_level (DISCARD); 8027 } 8028 8029 /* Now transform the word as ksh93 appears to do and go on */ 8030 t = assignment (tlist->word->word, 0); 8031 tlist->word->word[t] = '\0'; 8032 tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG); 8033 } 8034#endif 8035 8036 expanded_something = 0; 8037 expanded = expand_word_internal 8038 (tlist->word, 0, 0, &has_dollar_at, &expanded_something); 8039 8040 if (expanded == &expand_word_error || expanded == &expand_word_fatal) 8041 { 8042 /* By convention, each time this error is returned, 8043 tlist->word->word has already been freed. */ 8044 tlist->word->word = (char *)NULL; 8045 8046 /* Dispose our copy of the original list. */ 8047 dispose_words (orig_list); 8048 /* Dispose the new list we're building. */ 8049 dispose_words (new_list); 8050 8051 last_command_exit_value = EXECUTION_FAILURE; 8052 if (expanded == &expand_word_error) 8053 exp_jump_to_top_level (DISCARD); 8054 else 8055 exp_jump_to_top_level (FORCE_EOF); 8056 } 8057 8058 /* Don't split words marked W_NOSPLIT. */ 8059 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0) 8060 { 8061 temp_list = word_list_split (expanded); 8062 dispose_words (expanded); 8063 } 8064 else 8065 { 8066 /* If no parameter expansion, command substitution, process 8067 substitution, or arithmetic substitution took place, then 8068 do not do word splitting. We still have to remove quoted 8069 null characters from the result. */ 8070 word_list_remove_quoted_nulls (expanded); 8071 temp_list = expanded; 8072 } 8073 8074 expanded = REVERSE_LIST (temp_list, WORD_LIST *); 8075 new_list = (WORD_LIST *)list_append (expanded, new_list); 8076 } 8077 8078 if (orig_list) 8079 dispose_words (orig_list); 8080 8081 if (new_list) 8082 new_list = REVERSE_LIST (new_list, WORD_LIST *); 8083 8084 return (new_list); 8085} 8086 8087/* The workhorse for expand_words () and expand_words_no_vars (). 8088 First arg is LIST, a WORD_LIST of words. 8089 Second arg EFLAGS is a flags word controlling which expansions are 8090 performed. 8091 8092 This does all of the substitutions: brace expansion, tilde expansion, 8093 parameter expansion, command substitution, arithmetic expansion, 8094 process substitution, word splitting, and pathname expansion, according 8095 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits 8096 set, or for which no expansion is done, do not undergo word splitting. 8097 Words with the W_NOGLOB bit set do not undergo pathname expansion. */ 8098static WORD_LIST * 8099expand_word_list_internal (list, eflags) 8100 WORD_LIST *list; 8101 int eflags; 8102{ 8103 WORD_LIST *new_list, *temp_list; 8104 int tint; 8105 8106 if (list == 0) 8107 return ((WORD_LIST *)NULL); 8108 8109 garglist = new_list = copy_word_list (list); 8110 if (eflags & WEXP_VARASSIGN) 8111 { 8112 garglist = new_list = separate_out_assignments (new_list); 8113 if (new_list == 0) 8114 { 8115 if (subst_assign_varlist) 8116 { 8117 /* All the words were variable assignments, so they are placed 8118 into the shell's environment. */ 8119 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next) 8120 { 8121 this_command_name = (char *)NULL; /* no arithmetic errors */ 8122 tint = do_word_assignment (temp_list->word); 8123 /* Variable assignment errors in non-interactive shells 8124 running in Posix.2 mode cause the shell to exit. */ 8125 if (tint == 0) 8126 { 8127 last_command_exit_value = EXECUTION_FAILURE; 8128 if (interactive_shell == 0 && posixly_correct) 8129 exp_jump_to_top_level (FORCE_EOF); 8130 else 8131 exp_jump_to_top_level (DISCARD); 8132 } 8133 } 8134 dispose_words (subst_assign_varlist); 8135 subst_assign_varlist = (WORD_LIST *)NULL; 8136 } 8137 return ((WORD_LIST *)NULL); 8138 } 8139 } 8140 8141 /* Begin expanding the words that remain. The expansions take place on 8142 things that aren't really variable assignments. */ 8143 8144#if defined (BRACE_EXPANSION) 8145 /* Do brace expansion on this word if there are any brace characters 8146 in the string. */ 8147 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list) 8148 new_list = brace_expand_word_list (new_list, eflags); 8149#endif /* BRACE_EXPANSION */ 8150 8151 /* Perform the `normal' shell expansions: tilde expansion, parameter and 8152 variable substitution, command substitution, arithmetic expansion, 8153 and word splitting. */ 8154 new_list = shell_expand_word_list (new_list, eflags); 8155 8156 /* Okay, we're almost done. Now let's just do some filename 8157 globbing. */ 8158 if (new_list) 8159 { 8160 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0) 8161 /* Glob expand the word list unless globbing has been disabled. */ 8162 new_list = glob_expand_word_list (new_list, eflags); 8163 else 8164 /* Dequote the words, because we're not performing globbing. */ 8165 new_list = dequote_list (new_list); 8166 } 8167 8168 if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist) 8169 { 8170 sh_wassign_func_t *assign_func; 8171 8172 /* If the remainder of the words expand to nothing, Posix.2 requires 8173 that the variable and environment assignments affect the shell's 8174 environment. */ 8175 assign_func = new_list ? assign_in_env : do_word_assignment; 8176 tempenv_assign_error = 0; 8177 8178 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next) 8179 { 8180 this_command_name = (char *)NULL; 8181 tint = (*assign_func) (temp_list->word); 8182 /* Variable assignment errors in non-interactive shells running 8183 in Posix.2 mode cause the shell to exit. */ 8184 if (tint == 0) 8185 { 8186 if (assign_func == do_word_assignment) 8187 { 8188 last_command_exit_value = EXECUTION_FAILURE; 8189 if (interactive_shell == 0 && posixly_correct) 8190 exp_jump_to_top_level (FORCE_EOF); 8191 else 8192 exp_jump_to_top_level (DISCARD); 8193 } 8194 else 8195 tempenv_assign_error++; 8196 } 8197 } 8198 8199 dispose_words (subst_assign_varlist); 8200 subst_assign_varlist = (WORD_LIST *)NULL; 8201 } 8202 8203#if 0 8204 tint = list_length (new_list) + 1; 8205 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16); 8206 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next) 8207 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0'; 8208 glob_argv_flags[tint] = '\0'; 8209#endif 8210 8211 return (new_list); 8212} 8213