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