PageRenderTime 69ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/subst.c

https://github.com/SnkBitten/android_external_bash
C | 9071 lines | 7503 code | 704 blank | 864 comment | 1375 complexity | 27d13ea50af0f630524507c4f96fee2d MD5 | raw file
Possible License(s): GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /* subst.c -- The part of the shell that does parameter, command, arithmetic,
  2. and globbing substitutions. */
  3. /* ``Have a little faith, there's magic in the night. You ain't a
  4. beauty, but, hey, you're alright.'' */
  5. /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
  6. This file is part of GNU Bash, the Bourne Again SHell.
  7. Bash is free software: you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation, either version 3 of the License, or
  10. (at your option) any later version.
  11. Bash is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with Bash. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "config.h"
  19. #include "bashtypes.h"
  20. #include <stdio.h>
  21. #include "chartypes.h"
  22. #if defined (HAVE_PWD_H)
  23. # include <pwd.h>
  24. #endif
  25. #include <signal.h>
  26. #include <errno.h>
  27. #if defined (HAVE_UNISTD_H)
  28. # include <unistd.h>
  29. #endif
  30. #include "bashansi.h"
  31. #include "posixstat.h"
  32. #include "bashintl.h"
  33. #include "shell.h"
  34. #include "flags.h"
  35. #include "jobs.h"
  36. #include "execute_cmd.h"
  37. #include "filecntl.h"
  38. #include "trap.h"
  39. #include "pathexp.h"
  40. #include "mailcheck.h"
  41. #include "shmbutil.h"
  42. #include "builtins/getopt.h"
  43. #include "builtins/common.h"
  44. #include "builtins/builtext.h"
  45. #include <tilde/tilde.h>
  46. #include <glob/strmatch.h>
  47. #if !defined (errno)
  48. extern int errno;
  49. #endif /* !errno */
  50. /* The size that strings change by. */
  51. #define DEFAULT_INITIAL_ARRAY_SIZE 112
  52. #define DEFAULT_ARRAY_SIZE 128
  53. /* Variable types. */
  54. #define VT_VARIABLE 0
  55. #define VT_POSPARMS 1
  56. #define VT_ARRAYVAR 2
  57. #define VT_ARRAYMEMBER 3
  58. #define VT_ASSOCVAR 4
  59. #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
  60. /* Flags for quoted_strchr */
  61. #define ST_BACKSL 0x01
  62. #define ST_CTLESC 0x02
  63. #define ST_SQUOTE 0x04 /* unused yet */
  64. #define ST_DQUOTE 0x08 /* unused yet */
  65. /* Flags for the `pflags' argument to param_expand() */
  66. #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
  67. #define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */
  68. #define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */
  69. /* These defs make it easier to use the editor. */
  70. #define LBRACE '{'
  71. #define RBRACE '}'
  72. #define LPAREN '('
  73. #define RPAREN ')'
  74. #if defined (HANDLE_MULTIBYTE)
  75. #define WLPAREN L'('
  76. #define WRPAREN L')'
  77. #endif
  78. /* Evaluates to 1 if C is one of the shell's special parameters whose length
  79. can be taken, but is also one of the special expansion characters. */
  80. #define VALID_SPECIAL_LENGTH_PARAM(c) \
  81. ((c) == '-' || (c) == '?' || (c) == '#')
  82. /* Evaluates to 1 if C is one of the shell's special parameters for which an
  83. indirect variable reference may be made. */
  84. #define VALID_INDIR_PARAM(c) \
  85. ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
  86. /* Evaluates to 1 if C is one of the OP characters that follows the parameter
  87. in ${parameter[:]OPword}. */
  88. #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
  89. /* Evaluates to 1 if this is one of the shell's special variables. */
  90. #define SPECIAL_VAR(name, wi) \
  91. ((DIGIT (*name) && all_digits (name)) || \
  92. (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
  93. (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
  94. /* An expansion function that takes a string and a quoted flag and returns
  95. a WORD_LIST *. Used as the type of the third argument to
  96. expand_string_if_necessary(). */
  97. typedef WORD_LIST *EXPFUNC __P((char *, int));
  98. /* Process ID of the last command executed within command substitution. */
  99. pid_t last_command_subst_pid = NO_PID;
  100. pid_t current_command_subst_pid = NO_PID;
  101. /* Variables used to keep track of the characters in IFS. */
  102. SHELL_VAR *ifs_var;
  103. char *ifs_value;
  104. unsigned char ifs_cmap[UCHAR_MAX + 1];
  105. #if defined (HANDLE_MULTIBYTE)
  106. unsigned char ifs_firstc[MB_LEN_MAX];
  107. size_t ifs_firstc_len;
  108. #else
  109. unsigned char ifs_firstc;
  110. #endif
  111. /* Sentinel to tell when we are performing variable assignments preceding a
  112. command name and putting them into the environment. Used to make sure
  113. we use the temporary environment when looking up variable values. */
  114. int assigning_in_environment;
  115. /* Used to hold a list of variable assignments preceding a command. Global
  116. so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
  117. SIGCHLD trap and so it can be saved and restored by the trap handlers. */
  118. WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
  119. /* Extern functions and variables from different files. */
  120. extern int last_command_exit_value, last_command_exit_signal;
  121. extern int subshell_environment, line_number;
  122. extern int subshell_level, parse_and_execute_level, sourcelevel;
  123. extern int eof_encountered;
  124. extern int return_catch_flag, return_catch_value;
  125. extern pid_t dollar_dollar_pid;
  126. extern int posixly_correct;
  127. extern char *this_command_name;
  128. extern struct fd_bitmap *current_fds_to_close;
  129. extern int wordexp_only;
  130. extern int expanding_redir;
  131. extern int tempenv_assign_error;
  132. #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
  133. extern wchar_t *wcsdup __P((const wchar_t *));
  134. #endif
  135. /* Non-zero means to allow unmatched globbed filenames to expand to
  136. a null file. */
  137. int allow_null_glob_expansion;
  138. /* Non-zero means to throw an error when globbing fails to match anything. */
  139. int fail_glob_expansion;
  140. #if 0
  141. /* Variables to keep track of which words in an expanded word list (the
  142. output of expand_word_list_internal) are the result of globbing
  143. expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
  144. (CURRENTLY UNUSED). */
  145. char *glob_argv_flags;
  146. static int glob_argv_flags_size;
  147. #endif
  148. static WORD_LIST expand_word_error, expand_word_fatal;
  149. static WORD_DESC expand_wdesc_error, expand_wdesc_fatal;
  150. static char expand_param_error, expand_param_fatal;
  151. static char extract_string_error, extract_string_fatal;
  152. /* Tell the expansion functions to not longjmp back to top_level on fatal
  153. errors. Enabled when doing completion and prompt string expansion. */
  154. static int no_longjmp_on_fatal_error = 0;
  155. /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
  156. $* on $IFS, primarily when doing assignment statements. */
  157. static int expand_no_split_dollar_star = 0;
  158. /* A WORD_LIST of words to be expanded by expand_word_list_internal,
  159. without any leading variable assignments. */
  160. static WORD_LIST *garglist = (WORD_LIST *)NULL;
  161. static char *quoted_substring __P((char *, int, int));
  162. static int quoted_strlen __P((char *));
  163. static char *quoted_strchr __P((char *, int, int));
  164. static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
  165. static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
  166. static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
  167. static WORD_LIST *expand_string_internal __P((char *, int));
  168. static WORD_LIST *expand_string_leave_quoted __P((char *, int));
  169. static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
  170. static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
  171. static char *make_quoted_char __P((int));
  172. static WORD_LIST *quote_list __P((WORD_LIST *));
  173. static int unquoted_substring __P((char *, char *));
  174. static int unquoted_member __P((int, char *));
  175. #if defined (ARRAY_VARS)
  176. static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
  177. #endif
  178. static int do_assignment_internal __P((const WORD_DESC *, int));
  179. static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));
  180. static char *string_extract __P((char *, int *, char *, int));
  181. static char *string_extract_double_quoted __P((char *, int *, int));
  182. static inline char *string_extract_single_quoted __P((char *, int *));
  183. static inline int skip_single_quoted __P((const char *, size_t, int));
  184. static int skip_double_quoted __P((char *, size_t, int));
  185. static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
  186. static char *extract_dollar_brace_string __P((char *, int *, int, int));
  187. static int skip_matched_pair __P((const char *, int, int, int, int));
  188. static char *pos_params __P((char *, int, int, int));
  189. static unsigned char *mb_getcharlens __P((char *, int));
  190. static char *remove_upattern __P((char *, char *, int));
  191. #if defined (HANDLE_MULTIBYTE)
  192. static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));
  193. #endif
  194. static char *remove_pattern __P((char *, char *, int));
  195. static int match_pattern_char __P((char *, char *));
  196. static int match_upattern __P((char *, char *, int, char **, char **));
  197. #if defined (HANDLE_MULTIBYTE)
  198. static int match_pattern_wchar __P((wchar_t *, wchar_t *));
  199. static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
  200. #endif
  201. static int match_pattern __P((char *, char *, int, char **, char **));
  202. static int getpatspec __P((int, char *));
  203. static char *getpattern __P((char *, int, int));
  204. static char *variable_remove_pattern __P((char *, char *, int, int));
  205. static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
  206. static char *parameter_list_remove_pattern __P((int, char *, int, int));
  207. #ifdef ARRAY_VARS
  208. static char *array_remove_pattern __P((SHELL_VAR *, char *, int, char *, int));
  209. #endif
  210. static char *parameter_brace_remove_pattern __P((char *, char *, char *, int, int));
  211. static char *process_substitute __P((char *, int));
  212. static char *read_comsub __P((int, int, int *));
  213. #ifdef ARRAY_VARS
  214. static arrayind_t array_length_reference __P((char *));
  215. #endif
  216. static int valid_brace_expansion_word __P((char *, int));
  217. static int chk_atstar __P((char *, int, int *, int *));
  218. static int chk_arithsub __P((const char *, int));
  219. static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int));
  220. static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
  221. static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
  222. static void parameter_brace_expand_error __P((char *, char *));
  223. static int valid_length_expression __P((char *));
  224. static intmax_t parameter_brace_expand_length __P((char *));
  225. static char *skiparith __P((char *, int));
  226. static int verify_substring_values __P((SHELL_VAR *, char *, char *, int, intmax_t *, intmax_t *));
  227. static int get_var_and_type __P((char *, char *, int, SHELL_VAR **, char **));
  228. static char *mb_substring __P((char *, int, int));
  229. static char *parameter_brace_substring __P((char *, char *, char *, int));
  230. static char *pos_params_pat_subst __P((char *, char *, char *, int));
  231. static char *parameter_brace_patsub __P((char *, char *, char *, int));
  232. static char *pos_params_casemod __P((char *, char *, int, int));
  233. static char *parameter_brace_casemod __P((char *, char *, int, char *, int));
  234. static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int, int *, int *));
  235. static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
  236. static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
  237. static WORD_LIST *word_list_split __P((WORD_LIST *));
  238. static void exp_jump_to_top_level __P((int));
  239. static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
  240. static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
  241. #ifdef BRACE_EXPANSION
  242. static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
  243. #endif
  244. #if defined (ARRAY_VARS)
  245. static int make_internal_declare __P((char *, char *));
  246. #endif
  247. static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
  248. static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
  249. /* **************************************************************** */
  250. /* */
  251. /* Utility Functions */
  252. /* */
  253. /* **************************************************************** */
  254. #if defined (DEBUG)
  255. void
  256. dump_word_flags (flags)
  257. int flags;
  258. {
  259. int f;
  260. f = flags;
  261. fprintf (stderr, "%d -> ", f);
  262. if (f & W_ASSIGNASSOC)
  263. {
  264. f &= ~W_ASSIGNASSOC;
  265. fprintf (stderr, "W_ASSIGNASSOC%s", f ? "|" : "");
  266. }
  267. if (f & W_HASCTLESC)
  268. {
  269. f &= ~W_HASCTLESC;
  270. fprintf (stderr, "W_HASCTLESC%s", f ? "|" : "");
  271. }
  272. if (f & W_NOPROCSUB)
  273. {
  274. f &= ~W_NOPROCSUB;
  275. fprintf (stderr, "W_NOPROCSUB%s", f ? "|" : "");
  276. }
  277. if (f & W_DQUOTE)
  278. {
  279. f &= ~W_DQUOTE;
  280. fprintf (stderr, "W_DQUOTE%s", f ? "|" : "");
  281. }
  282. if (f & W_HASQUOTEDNULL)
  283. {
  284. f &= ~W_HASQUOTEDNULL;
  285. fprintf (stderr, "W_HASQUOTEDNULL%s", f ? "|" : "");
  286. }
  287. if (f & W_ASSIGNARG)
  288. {
  289. f &= ~W_ASSIGNARG;
  290. fprintf (stderr, "W_ASSIGNARG%s", f ? "|" : "");
  291. }
  292. if (f & W_ASSNBLTIN)
  293. {
  294. f &= ~W_ASSNBLTIN;
  295. fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
  296. }
  297. if (f & W_COMPASSIGN)
  298. {
  299. f &= ~W_COMPASSIGN;
  300. fprintf (stderr, "W_COMPASSIGN%s", f ? "|" : "");
  301. }
  302. if (f & W_NOEXPAND)
  303. {
  304. f &= ~W_NOEXPAND;
  305. fprintf (stderr, "W_NOEXPAND%s", f ? "|" : "");
  306. }
  307. if (f & W_ITILDE)
  308. {
  309. f &= ~W_ITILDE;
  310. fprintf (stderr, "W_ITILDE%s", f ? "|" : "");
  311. }
  312. if (f & W_NOTILDE)
  313. {
  314. f &= ~W_NOTILDE;
  315. fprintf (stderr, "W_NOTILDE%s", f ? "|" : "");
  316. }
  317. if (f & W_ASSIGNRHS)
  318. {
  319. f &= ~W_ASSIGNRHS;
  320. fprintf (stderr, "W_ASSIGNRHS%s", f ? "|" : "");
  321. }
  322. if (f & W_NOCOMSUB)
  323. {
  324. f &= ~W_NOCOMSUB;
  325. fprintf (stderr, "W_NOCOMSUB%s", f ? "|" : "");
  326. }
  327. if (f & W_DOLLARSTAR)
  328. {
  329. f &= ~W_DOLLARSTAR;
  330. fprintf (stderr, "W_DOLLARSTAR%s", f ? "|" : "");
  331. }
  332. if (f & W_DOLLARAT)
  333. {
  334. f &= ~W_DOLLARAT;
  335. fprintf (stderr, "W_DOLLARAT%s", f ? "|" : "");
  336. }
  337. if (f & W_TILDEEXP)
  338. {
  339. f &= ~W_TILDEEXP;
  340. fprintf (stderr, "W_TILDEEXP%s", f ? "|" : "");
  341. }
  342. if (f & W_NOSPLIT2)
  343. {
  344. f &= ~W_NOSPLIT2;
  345. fprintf (stderr, "W_NOSPLIT2%s", f ? "|" : "");
  346. }
  347. if (f & W_NOGLOB)
  348. {
  349. f &= ~W_NOGLOB;
  350. fprintf (stderr, "W_NOGLOB%s", f ? "|" : "");
  351. }
  352. if (f & W_NOSPLIT)
  353. {
  354. f &= ~W_NOSPLIT;
  355. fprintf (stderr, "W_NOSPLIT%s", f ? "|" : "");
  356. }
  357. if (f & W_GLOBEXP)
  358. {
  359. f &= ~W_GLOBEXP;
  360. fprintf (stderr, "W_GLOBEXP%s", f ? "|" : "");
  361. }
  362. if (f & W_ASSIGNMENT)
  363. {
  364. f &= ~W_ASSIGNMENT;
  365. fprintf (stderr, "W_ASSIGNMENT%s", f ? "|" : "");
  366. }
  367. if (f & W_QUOTED)
  368. {
  369. f &= ~W_QUOTED;
  370. fprintf (stderr, "W_QUOTED%s", f ? "|" : "");
  371. }
  372. if (f & W_HASDOLLAR)
  373. {
  374. f &= ~W_HASDOLLAR;
  375. fprintf (stderr, "W_HASDOLLAR%s", f ? "|" : "");
  376. }
  377. fprintf (stderr, "\n");
  378. fflush (stderr);
  379. }
  380. #endif
  381. #ifdef INCLUDE_UNUSED
  382. static char *
  383. quoted_substring (string, start, end)
  384. char *string;
  385. int start, end;
  386. {
  387. register int len, l;
  388. register char *result, *s, *r;
  389. len = end - start;
  390. /* Move to string[start], skipping quoted characters. */
  391. for (s = string, l = 0; *s && l < start; )
  392. {
  393. if (*s == CTLESC)
  394. {
  395. s++;
  396. continue;
  397. }
  398. l++;
  399. if (*s == 0)
  400. break;
  401. }
  402. r = result = (char *)xmalloc (2*len + 1); /* save room for quotes */
  403. /* Copy LEN characters, including quote characters. */
  404. s = string + l;
  405. for (l = 0; l < len; s++)
  406. {
  407. if (*s == CTLESC)
  408. *r++ = *s++;
  409. *r++ = *s;
  410. l++;
  411. if (*s == 0)
  412. break;
  413. }
  414. *r = '\0';
  415. return result;
  416. }
  417. #endif
  418. #ifdef INCLUDE_UNUSED
  419. /* Return the length of S, skipping over quoted characters */
  420. static int
  421. quoted_strlen (s)
  422. char *s;
  423. {
  424. register char *p;
  425. int i;
  426. i = 0;
  427. for (p = s; *p; p++)
  428. {
  429. if (*p == CTLESC)
  430. {
  431. p++;
  432. if (*p == 0)
  433. return (i + 1);
  434. }
  435. i++;
  436. }
  437. return i;
  438. }
  439. #endif
  440. /* Find the first occurrence of character C in string S, obeying shell
  441. quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
  442. characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
  443. escaped with CTLESC are skipped. */
  444. static char *
  445. quoted_strchr (s, c, flags)
  446. char *s;
  447. int c, flags;
  448. {
  449. register char *p;
  450. for (p = s; *p; p++)
  451. {
  452. if (((flags & ST_BACKSL) && *p == '\\')
  453. || ((flags & ST_CTLESC) && *p == CTLESC))
  454. {
  455. p++;
  456. if (*p == '\0')
  457. return ((char *)NULL);
  458. continue;
  459. }
  460. else if (*p == c)
  461. return p;
  462. }
  463. return ((char *)NULL);
  464. }
  465. /* Return 1 if CHARACTER appears in an unquoted portion of
  466. STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
  467. static int
  468. unquoted_member (character, string)
  469. int character;
  470. char *string;
  471. {
  472. size_t slen;
  473. int sindex, c;
  474. DECLARE_MBSTATE;
  475. slen = strlen (string);
  476. sindex = 0;
  477. while (c = string[sindex])
  478. {
  479. if (c == character)
  480. return (1);
  481. switch (c)
  482. {
  483. default:
  484. ADVANCE_CHAR (string, slen, sindex);
  485. break;
  486. case '\\':
  487. sindex++;
  488. if (string[sindex])
  489. ADVANCE_CHAR (string, slen, sindex);
  490. break;
  491. case '\'':
  492. sindex = skip_single_quoted (string, slen, ++sindex);
  493. break;
  494. case '"':
  495. sindex = skip_double_quoted (string, slen, ++sindex);
  496. break;
  497. }
  498. }
  499. return (0);
  500. }
  501. /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
  502. static int
  503. unquoted_substring (substr, string)
  504. char *substr, *string;
  505. {
  506. size_t slen;
  507. int sindex, c, sublen;
  508. DECLARE_MBSTATE;
  509. if (substr == 0 || *substr == '\0')
  510. return (0);
  511. slen = strlen (string);
  512. sublen = strlen (substr);
  513. for (sindex = 0; c = string[sindex]; )
  514. {
  515. if (STREQN (string + sindex, substr, sublen))
  516. return (1);
  517. switch (c)
  518. {
  519. case '\\':
  520. sindex++;
  521. if (string[sindex])
  522. ADVANCE_CHAR (string, slen, sindex);
  523. break;
  524. case '\'':
  525. sindex = skip_single_quoted (string, slen, ++sindex);
  526. break;
  527. case '"':
  528. sindex = skip_double_quoted (string, slen, ++sindex);
  529. break;
  530. default:
  531. ADVANCE_CHAR (string, slen, sindex);
  532. break;
  533. }
  534. }
  535. return (0);
  536. }
  537. /* Most of the substitutions must be done in parallel. In order
  538. to avoid using tons of unclear goto's, I have some functions
  539. for manipulating malloc'ed strings. They all take INDX, a
  540. pointer to an integer which is the offset into the string
  541. where manipulation is taking place. They also take SIZE, a
  542. pointer to an integer which is the current length of the
  543. character array for this string. */
  544. /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
  545. of space allocated to TARGET. SOURCE can be NULL, in which
  546. case nothing happens. Gets rid of SOURCE by freeing it.
  547. Returns TARGET in case the location has changed. */
  548. INLINE char *
  549. sub_append_string (source, target, indx, size)
  550. char *source, *target;
  551. int *indx, *size;
  552. {
  553. if (source)
  554. {
  555. int srclen, n;
  556. srclen = STRLEN (source);
  557. if (srclen >= (int)(*size - *indx))
  558. {
  559. n = srclen + *indx;
  560. n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
  561. target = (char *)xrealloc (target, (*size = n));
  562. }
  563. FASTCOPY (source, target + *indx, srclen);
  564. *indx += srclen;
  565. target[*indx] = '\0';
  566. free (source);
  567. }
  568. return (target);
  569. }
  570. #if 0
  571. /* UNUSED */
  572. /* Append the textual representation of NUMBER to TARGET.
  573. INDX and SIZE are as in SUB_APPEND_STRING. */
  574. char *
  575. sub_append_number (number, target, indx, size)
  576. intmax_t number;
  577. int *indx, *size;
  578. char *target;
  579. {
  580. char *temp;
  581. temp = itos (number);
  582. return (sub_append_string (temp, target, indx, size));
  583. }
  584. #endif
  585. /* Extract a substring from STRING, starting at SINDEX and ending with
  586. one of the characters in CHARLIST. Don't make the ending character
  587. part of the string. Leave SINDEX pointing at the ending character.
  588. Understand about backslashes in the string. If (flags & SX_VARNAME)
  589. is non-zero, and array variables have been compiled into the shell,
  590. everything between a `[' and a corresponding `]' is skipped over.
  591. If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
  592. update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must
  593. contain a closing character from CHARLIST. */
  594. static char *
  595. string_extract (string, sindex, charlist, flags)
  596. char *string;
  597. int *sindex;
  598. char *charlist;
  599. int flags;
  600. {
  601. register int c, i;
  602. int found;
  603. size_t slen;
  604. char *temp;
  605. DECLARE_MBSTATE;
  606. slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
  607. i = *sindex;
  608. found = 0;
  609. while (c = string[i])
  610. {
  611. if (c == '\\')
  612. {
  613. if (string[i + 1])
  614. i++;
  615. else
  616. break;
  617. }
  618. #if defined (ARRAY_VARS)
  619. else if ((flags & SX_VARNAME) && c == '[')
  620. {
  621. int ni;
  622. /* If this is an array subscript, skip over it and continue. */
  623. ni = skipsubscript (string, i, 0);
  624. if (string[ni] == ']')
  625. i = ni;
  626. }
  627. #endif
  628. else if (MEMBER (c, charlist))
  629. {
  630. found = 1;
  631. break;
  632. }
  633. ADVANCE_CHAR (string, slen, i);
  634. }
  635. /* If we had to have a matching delimiter and didn't find one, return an
  636. error and let the caller deal with it. */
  637. if ((flags & SX_REQMATCH) && found == 0)
  638. {
  639. *sindex = i;
  640. return (&extract_string_error);
  641. }
  642. temp = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
  643. *sindex = i;
  644. return (temp);
  645. }
  646. /* Extract the contents of STRING as if it is enclosed in double quotes.
  647. SINDEX, when passed in, is the offset of the character immediately
  648. following the opening double quote; on exit, SINDEX is left pointing after
  649. the closing double quote. If STRIPDQ is non-zero, unquoted double
  650. quotes are stripped and the string is terminated by a null byte.
  651. Backslashes between the embedded double quotes are processed. If STRIPDQ
  652. is zero, an unquoted `"' terminates the string. */
  653. static char *
  654. string_extract_double_quoted (string, sindex, stripdq)
  655. char *string;
  656. int *sindex, stripdq;
  657. {
  658. size_t slen;
  659. char *send;
  660. int j, i, t;
  661. unsigned char c;
  662. char *temp, *ret; /* The new string we return. */
  663. int pass_next, backquote, si; /* State variables for the machine. */
  664. int dquote;
  665. DECLARE_MBSTATE;
  666. slen = strlen (string + *sindex) + *sindex;
  667. send = string + slen;
  668. pass_next = backquote = dquote = 0;
  669. temp = (char *)xmalloc (1 + slen - *sindex);
  670. j = 0;
  671. i = *sindex;
  672. while (c = string[i])
  673. {
  674. /* Process a character that was quoted by a backslash. */
  675. if (pass_next)
  676. {
  677. /* Posix.2 sez:
  678. ``The backslash shall retain its special meaning as an escape
  679. character only when followed by one of the characters:
  680. $ ` " \ <newline>''.
  681. If STRIPDQ is zero, we handle the double quotes here and let
  682. expand_word_internal handle the rest. If STRIPDQ is non-zero,
  683. we have already been through one round of backslash stripping,
  684. and want to strip these backslashes only if DQUOTE is non-zero,
  685. indicating that we are inside an embedded double-quoted string. */
  686. /* If we are in an embedded quoted string, then don't strip
  687. backslashes before characters for which the backslash
  688. retains its special meaning, but remove backslashes in
  689. front of other characters. If we are not in an
  690. embedded quoted string, don't strip backslashes at all.
  691. This mess is necessary because the string was already
  692. surrounded by double quotes (and sh has some really weird
  693. quoting rules).
  694. The returned string will be run through expansion as if
  695. it were double-quoted. */
  696. if ((stripdq == 0 && c != '"') ||
  697. (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
  698. temp[j++] = '\\';
  699. pass_next = 0;
  700. add_one_character:
  701. COPY_CHAR_I (temp, j, string, send, i);
  702. continue;
  703. }
  704. /* A backslash protects the next character. The code just above
  705. handles preserving the backslash in front of any character but
  706. a double quote. */
  707. if (c == '\\')
  708. {
  709. pass_next++;
  710. i++;
  711. continue;
  712. }
  713. /* Inside backquotes, ``the portion of the quoted string from the
  714. initial backquote and the characters up to the next backquote
  715. that is not preceded by a backslash, having escape characters
  716. removed, defines that command''. */
  717. if (backquote)
  718. {
  719. if (c == '`')
  720. backquote = 0;
  721. temp[j++] = c;
  722. i++;
  723. continue;
  724. }
  725. if (c == '`')
  726. {
  727. temp[j++] = c;
  728. backquote++;
  729. i++;
  730. continue;
  731. }
  732. /* Pass everything between `$(' and the matching `)' or a quoted
  733. ${ ... } pair through according to the Posix.2 specification. */
  734. if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
  735. {
  736. int free_ret = 1;
  737. si = i + 2;
  738. if (string[i + 1] == LPAREN)
  739. ret = extract_command_subst (string, &si, 0);
  740. else
  741. ret = extract_dollar_brace_string (string, &si, 1, 0);
  742. temp[j++] = '$';
  743. temp[j++] = string[i + 1];
  744. /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
  745. is set. */
  746. if (ret == 0 && no_longjmp_on_fatal_error)
  747. {
  748. free_ret = 0;
  749. ret = string + i + 2;
  750. }
  751. for (t = 0; ret[t]; t++, j++)
  752. temp[j] = ret[t];
  753. temp[j] = string[si];
  754. if (string[si])
  755. {
  756. j++;
  757. i = si + 1;
  758. }
  759. else
  760. i = si;
  761. if (free_ret)
  762. free (ret);
  763. continue;
  764. }
  765. /* Add any character but a double quote to the quoted string we're
  766. accumulating. */
  767. if (c != '"')
  768. goto add_one_character;
  769. /* c == '"' */
  770. if (stripdq)
  771. {
  772. dquote ^= 1;
  773. i++;
  774. continue;
  775. }
  776. break;
  777. }
  778. temp[j] = '\0';
  779. /* Point to after the closing quote. */
  780. if (c)
  781. i++;
  782. *sindex = i;
  783. return (temp);
  784. }
  785. /* This should really be another option to string_extract_double_quoted. */
  786. static int
  787. skip_double_quoted (string, slen, sind)
  788. char *string;
  789. size_t slen;
  790. int sind;
  791. {
  792. int c, i;
  793. char *ret;
  794. int pass_next, backquote, si;
  795. DECLARE_MBSTATE;
  796. pass_next = backquote = 0;
  797. i = sind;
  798. while (c = string[i])
  799. {
  800. if (pass_next)
  801. {
  802. pass_next = 0;
  803. ADVANCE_CHAR (string, slen, i);
  804. continue;
  805. }
  806. else if (c == '\\')
  807. {
  808. pass_next++;
  809. i++;
  810. continue;
  811. }
  812. else if (backquote)
  813. {
  814. if (c == '`')
  815. backquote = 0;
  816. ADVANCE_CHAR (string, slen, i);
  817. continue;
  818. }
  819. else if (c == '`')
  820. {
  821. backquote++;
  822. i++;
  823. continue;
  824. }
  825. else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
  826. {
  827. si = i + 2;
  828. if (string[i + 1] == LPAREN)
  829. ret = extract_command_subst (string, &si, SX_NOALLOC);
  830. else
  831. ret = extract_dollar_brace_string (string, &si, 1, SX_NOALLOC);
  832. i = si + 1;
  833. continue;
  834. }
  835. else if (c != '"')
  836. {
  837. ADVANCE_CHAR (string, slen, i);
  838. continue;
  839. }
  840. else
  841. break;
  842. }
  843. if (c)
  844. i++;
  845. return (i);
  846. }
  847. /* Extract the contents of STRING as if it is enclosed in single quotes.
  848. SINDEX, when passed in, is the offset of the character immediately
  849. following the opening single quote; on exit, SINDEX is left pointing after
  850. the closing single quote. */
  851. static inline char *
  852. string_extract_single_quoted (string, sindex)
  853. char *string;
  854. int *sindex;
  855. {
  856. register int i;
  857. size_t slen;
  858. char *t;
  859. DECLARE_MBSTATE;
  860. /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
  861. slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
  862. i = *sindex;
  863. while (string[i] && string[i] != '\'')
  864. ADVANCE_CHAR (string, slen, i);
  865. t = substring (string, *sindex, i);
  866. if (string[i])
  867. i++;
  868. *sindex = i;
  869. return (t);
  870. }
  871. static inline int
  872. skip_single_quoted (string, slen, sind)
  873. const char *string;
  874. size_t slen;
  875. int sind;
  876. {
  877. register int c;
  878. DECLARE_MBSTATE;
  879. c = sind;
  880. while (string[c] && string[c] != '\'')
  881. ADVANCE_CHAR (string, slen, c);
  882. if (string[c])
  883. c++;
  884. return c;
  885. }
  886. /* Just like string_extract, but doesn't hack backslashes or any of
  887. that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
  888. static char *
  889. string_extract_verbatim (string, slen, sindex, charlist, flags)
  890. char *string;
  891. size_t slen;
  892. int *sindex;
  893. char *charlist;
  894. int flags;
  895. {
  896. register int i;
  897. #if defined (HANDLE_MULTIBYTE)
  898. size_t clen;
  899. wchar_t *wcharlist;
  900. #endif
  901. int c;
  902. char *temp;
  903. DECLARE_MBSTATE;
  904. if (charlist[0] == '\'' && charlist[1] == '\0')
  905. {
  906. temp = string_extract_single_quoted (string, sindex);
  907. --*sindex; /* leave *sindex at separator character */
  908. return temp;
  909. }
  910. i = *sindex;
  911. #if 0
  912. /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
  913. this only if MB_CUR_MAX > 1. */
  914. slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;
  915. #endif
  916. #if defined (HANDLE_MULTIBYTE)
  917. clen = strlen (charlist);
  918. wcharlist = 0;
  919. #endif
  920. while (c = string[i])
  921. {
  922. #if defined (HANDLE_MULTIBYTE)
  923. size_t mblength;
  924. #endif
  925. if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
  926. {
  927. i += 2;
  928. continue;
  929. }
  930. /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
  931. through, to protect the CTLNULs from later calls to
  932. remove_quoted_nulls. */
  933. else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
  934. {
  935. i += 2;
  936. continue;
  937. }
  938. #if defined (HANDLE_MULTIBYTE)
  939. mblength = MBLEN (string + i, slen - i);
  940. if (mblength > 1)
  941. {
  942. wchar_t wc;
  943. mblength = mbtowc (&wc, string + i, slen - i);
  944. if (MB_INVALIDCH (mblength))
  945. {
  946. if (MEMBER (c, charlist))
  947. break;
  948. }
  949. else
  950. {
  951. if (wcharlist == 0)
  952. {
  953. size_t len;
  954. len = mbstowcs (wcharlist, charlist, 0);
  955. if (len == -1)
  956. len = 0;
  957. wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));
  958. mbstowcs (wcharlist, charlist, len + 1);
  959. }
  960. if (wcschr (wcharlist, wc))
  961. break;
  962. }
  963. }
  964. else
  965. #endif
  966. if (MEMBER (c, charlist))
  967. break;
  968. ADVANCE_CHAR (string, slen, i);
  969. }
  970. #if defined (HANDLE_MULTIBYTE)
  971. FREE (wcharlist);
  972. #endif
  973. temp = substring (string, *sindex, i);
  974. *sindex = i;
  975. return (temp);
  976. }
  977. /* Extract the $( construct in STRING, and return a new string.
  978. Start extracting at (SINDEX) as if we had just seen "$(".
  979. Make (SINDEX) get the position of the matching ")". )
  980. XFLAGS is additional flags to pass to other extraction functions. */
  981. char *
  982. extract_command_subst (string, sindex, xflags)
  983. char *string;
  984. int *sindex;
  985. int xflags;
  986. {
  987. if (string[*sindex] == LPAREN)
  988. return (extract_delimited_string (string, sindex, "$(", "(", ")", xflags|SX_COMMAND)); /*)*/
  989. else
  990. {
  991. xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
  992. return (xparse_dolparen (string, string+*sindex, sindex, xflags));
  993. }
  994. }
  995. /* Extract the $[ construct in STRING, and return a new string. (])
  996. Start extracting at (SINDEX) as if we had just seen "$[".
  997. Make (SINDEX) get the position of the matching "]". */
  998. char *
  999. extract_arithmetic_subst (string, sindex)
  1000. char *string;
  1001. int *sindex;
  1002. {
  1003. return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
  1004. }
  1005. #if defined (PROCESS_SUBSTITUTION)
  1006. /* Extract the <( or >( construct in STRING, and return a new string.
  1007. Start extracting at (SINDEX) as if we had just seen "<(".
  1008. Make (SINDEX) get the position of the matching ")". */ /*))*/
  1009. char *
  1010. extract_process_subst (string, starter, sindex)
  1011. char *string;
  1012. char *starter;
  1013. int *sindex;
  1014. {
  1015. return (extract_delimited_string (string, sindex, starter, "(", ")", 0));
  1016. }
  1017. #endif /* PROCESS_SUBSTITUTION */
  1018. #if defined (ARRAY_VARS)
  1019. /* This can be fooled by unquoted right parens in the passed string. If
  1020. each caller verifies that the last character in STRING is a right paren,
  1021. we don't even need to call extract_delimited_string. */
  1022. char *
  1023. extract_array_assignment_list (string, sindex)
  1024. char *string;
  1025. int *sindex;
  1026. {
  1027. int slen;
  1028. char *ret;
  1029. slen = strlen (string); /* ( */
  1030. if (string[slen - 1] == ')')
  1031. {
  1032. ret = substring (string, *sindex, slen - 1);
  1033. *sindex = slen - 1;
  1034. return ret;
  1035. }
  1036. return 0;
  1037. }
  1038. #endif
  1039. /* Extract and create a new string from the contents of STRING, a
  1040. character string delimited with OPENER and CLOSER. SINDEX is
  1041. the address of an int describing the current offset in STRING;
  1042. it should point to just after the first OPENER found. On exit,
  1043. SINDEX gets the position of the last character of the matching CLOSER.
  1044. If OPENER is more than a single character, ALT_OPENER, if non-null,
  1045. contains a character string that can also match CLOSER and thus
  1046. needs to be skipped. */
  1047. static char *
  1048. extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
  1049. char *string;
  1050. int *sindex;
  1051. char *opener, *alt_opener, *closer;
  1052. int flags;
  1053. {
  1054. int i, c, si;
  1055. size_t slen;
  1056. char *t, *result;
  1057. int pass_character, nesting_level, in_comment;
  1058. int len_closer, len_opener, len_alt_opener;
  1059. DECLARE_MBSTATE;
  1060. slen = strlen (string + *sindex) + *sindex;
  1061. len_opener = STRLEN (opener);
  1062. len_alt_opener = STRLEN (alt_opener);
  1063. len_closer = STRLEN (closer);
  1064. pass_character = in_comment = 0;
  1065. nesting_level = 1;
  1066. i = *sindex;
  1067. while (nesting_level)
  1068. {
  1069. c = string[i];
  1070. if (c == 0)
  1071. break;
  1072. if (in_comment)
  1073. {
  1074. if (c == '\n')
  1075. in_comment = 0;
  1076. ADVANCE_CHAR (string, slen, i);
  1077. continue;
  1078. }
  1079. if (pass_character) /* previous char was backslash */
  1080. {
  1081. pass_character = 0;
  1082. ADVANCE_CHAR (string, slen, i);
  1083. continue;
  1084. }
  1085. /* Not exactly right yet; should handle shell metacharacters and
  1086. multibyte characters, too. See COMMENT_BEGIN define in parse.y */
  1087. if ((flags & SX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || shellblank (string[i - 1])))
  1088. {
  1089. in_comment = 1;
  1090. ADVANCE_CHAR (string, slen, i);
  1091. continue;
  1092. }
  1093. if (c == CTLESC || c == '\\')
  1094. {
  1095. pass_character++;
  1096. i++;
  1097. continue;
  1098. }
  1099. #if 0
  1100. /* Process a nested command substitution, but only if we're parsing a
  1101. command substitution. XXX - for bash-4.2 */
  1102. if ((flags & SX_COMMAND) && string[i] == '$' && string[i+1] == LPAREN)
  1103. {
  1104. si = i + 2;
  1105. t = extract_command_subst (string, &si, flags);
  1106. i = si + 1;
  1107. continue;
  1108. }
  1109. #endif
  1110. /* Process a nested OPENER. */
  1111. if (STREQN (string + i, opener, len_opener))
  1112. {
  1113. si = i + len_opener;
  1114. t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|SX_NOALLOC);
  1115. i = si + 1;
  1116. continue;
  1117. }
  1118. /* Process a nested ALT_OPENER */
  1119. if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
  1120. {
  1121. si = i + len_alt_opener;
  1122. t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|SX_NOALLOC);
  1123. i = si + 1;
  1124. continue;
  1125. }
  1126. /* If the current substring terminates the delimited string, decrement
  1127. the nesting level. */
  1128. if (STREQN (string + i, closer, len_closer))
  1129. {
  1130. i += len_closer - 1; /* move to last byte of the closer */
  1131. nesting_level--;
  1132. if (nesting_level == 0)
  1133. break;
  1134. }
  1135. /* Pass old-style command substitution through verbatim. */
  1136. if (c == '`')
  1137. {
  1138. si = i + 1;
  1139. t = string_extract (string, &si, "`", flags|SX_NOALLOC);
  1140. i = si + 1;
  1141. continue;
  1142. }
  1143. /* Pass single-quoted and double-quoted strings through verbatim. */
  1144. if (c == '\'' || c == '"')
  1145. {
  1146. si = i + 1;
  1147. i = (c == '\'') ? skip_single_quoted (string, slen, si)
  1148. : skip_double_quoted (string, slen, si);
  1149. continue;
  1150. }
  1151. /* move past this character, which was not special. */
  1152. ADVANCE_CHAR (string, slen, i);
  1153. }
  1154. if (c == 0 && nesting_level)
  1155. {
  1156. if (no_longjmp_on_fatal_error == 0)
  1157. {
  1158. report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
  1159. last_command_exit_value = EXECUTION_FAILURE;
  1160. exp_jump_to_top_level (DISCARD);
  1161. }
  1162. else
  1163. {
  1164. *sindex = i;
  1165. return (char *)NULL;
  1166. }
  1167. }
  1168. si = i - *sindex - len_closer + 1;
  1169. if (flags & SX_NOALLOC)
  1170. result = (char *)NULL;
  1171. else
  1172. {
  1173. result = (char *)xmalloc (1 + si);
  1174. strncpy (result, string + *sindex, si);
  1175. result[si] = '\0';
  1176. }
  1177. *sindex = i;
  1178. return (result);
  1179. }
  1180. /* Extract a parameter expansion expression within ${ and } from STRING.
  1181. Obey the Posix.2 rules for finding the ending `}': count braces while
  1182. skipping over enclosed quoted strings and command substitutions.
  1183. SINDEX is the address of an int describing the current offset in STRING;
  1184. it should point to just after the first `{' found. On exit, SINDEX
  1185. gets the position of the matching `}'. QUOTED is non-zero if this
  1186. occurs inside double quotes. */
  1187. /* XXX -- this is very similar to extract_delimited_string -- XXX */
  1188. static char *
  1189. extract_dollar_brace_string (string, sindex, quoted, flags)
  1190. char *string;
  1191. int *sindex, quoted, flags;
  1192. {
  1193. register int i, c;
  1194. size_t slen;
  1195. int pass_character, nesting_level, si;
  1196. char *result, *t;
  1197. DECLARE_MBSTATE;
  1198. pass_character = 0;
  1199. nesting_level = 1;
  1200. slen = strlen (string + *sindex) + *sindex;
  1201. i = *sindex;
  1202. while (c = string[i])
  1203. {
  1204. if (pass_character)
  1205. {
  1206. pass_character = 0;
  1207. ADVANCE_CHAR (string, slen, i);
  1208. continue;
  1209. }
  1210. /* CTLESCs and backslashes quote the next character. */
  1211. if (c == CTLESC || c == '\\')
  1212. {
  1213. pass_character++;
  1214. i++;
  1215. continue;
  1216. }
  1217. if (string[i] == '$' && string[i+1] == LBRACE)
  1218. {
  1219. nesting_level++;
  1220. i += 2;
  1221. continue;
  1222. }
  1223. if (c == RBRACE)
  1224. {
  1225. nesting_level--;
  1226. if (nesting_level == 0)
  1227. break;
  1228. i++;
  1229. continue;
  1230. }
  1231. /* Pass the contents of old-style command substitutions through
  1232. verbatim. */
  1233. if (c == '`')
  1234. {
  1235. si = i + 1;
  1236. t = string_extract (string, &si, "`", flags|SX_NOALLOC);
  1237. i = si + 1;
  1238. continue;
  1239. }
  1240. /* Pass the contents of new-style command substitutions and
  1241. arithmetic substitutions through verbatim. */
  1242. if (string[i] == '$' && string[i+1] == LPAREN)
  1243. {
  1244. si = i + 2;
  1245. t = extract_command_subst (string, &si, flags|SX_NOALLOC);
  1246. i = si + 1;
  1247. continue;
  1248. }
  1249. /* Pass the contents of single-quoted and double-quoted strings
  1250. through verbatim. */
  1251. if (c == '\'' || c == '"')
  1252. {
  1253. si = i + 1;
  1254. i = (c == '\'') ? skip_single_quoted (string, slen, si)
  1255. : skip_double_quoted (string, slen, si);
  1256. /* skip_XXX_quoted leaves index one past close quote */
  1257. continue;
  1258. }
  1259. /* move past this character, which was not special. */
  1260. ADVANCE_CHAR (string, slen, i);
  1261. }
  1262. if (c == 0 && nesting_level)
  1263. {
  1264. if (no_longjmp_on_fatal_error == 0)
  1265. { /* { */
  1266. report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
  1267. last_command_exit_value = EXECUTION_FAILURE;
  1268. exp_jump_to_top_level (DISCARD);
  1269. }
  1270. else
  1271. {
  1272. *sindex = i;
  1273. return ((char *)NULL);
  1274. }
  1275. }
  1276. result = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
  1277. *sindex = i;
  1278. return (result);
  1279. }
  1280. /* Remove backslashes which are quoting backquotes from STRING. Modifies
  1281. STRING, and returns a pointer to it. */
  1282. char *
  1283. de_backslash (string)
  1284. char *string;
  1285. {
  1286. register size_t slen;
  1287. register int i, j, prev_i;
  1288. DECLARE_MBSTATE;
  1289. slen = strlen (string);
  1290. i = j = 0;
  1291. /* Loop copying string[i] to string[j], i >= j. */
  1292. while (i < slen)
  1293. {
  1294. if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
  1295. string[i + 1] == '$'))
  1296. i++;
  1297. prev_i = i;
  1298. ADVANCE_CHAR (string, slen, i);
  1299. if (j < prev_i)
  1300. do string[j++] = string[prev_i++]; while (prev_i < i);
  1301. else
  1302. j = i;
  1303. }
  1304. string[j] = '\0';
  1305. return (string);
  1306. }
  1307. #if 0
  1308. /*UNUSED*/
  1309. /* Replace instances of \! in a string with !. */
  1310. void
  1311. unquote_bang (string)
  1312. char *string;
  1313. {
  1314. register int i, j;
  1315. register char *temp;
  1316. temp = (char *)xmalloc (1 + strlen (string));
  1317. for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
  1318. {
  1319. if (string[i] == '\\' && string[i + 1] == '!')
  1320. {
  1321. temp[j] = '!';
  1322. i++;
  1323. }
  1324. }
  1325. strcpy (string, temp);
  1326. free (temp);
  1327. }
  1328. #endif
  1329. #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
  1330. /* This function assumes s[i] == open; returns with s[ret] == close; used to
  1331. parse array subscripts. FLAGS & 1 means to not attempt to skip over
  1332. matched pairs of quotes or backquotes, or skip word expansions; it is
  1333. intended to be used after expansion has been performed and during final
  1334. assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
  1335. static int
  1336. skip_matched_pair (string, start, open, close, flags)
  1337. const char *string;
  1338. int start, open, close, flags;
  1339. {
  1340. int i, pass_next, backq, si, c, count;
  1341. size_t slen;
  1342. char *temp, *ss;
  1343. DECLARE_MBSTATE;
  1344. slen = strlen (string + start) + start;
  1345. no_longjmp_on_fatal_error = 1;
  1346. i = start + 1; /* skip over leading bracket */
  1347. count = 1;
  1348. pass_next = backq = 0;
  1349. ss = (char *)string;
  1350. while (c = string[i])
  1351. {
  1352. if (pass_next)
  1353. {
  1354. pass_next = 0;
  1355. if (c == 0)
  1356. CQ_RETURN(i);
  1357. ADVANCE_CHAR (string, slen, i);
  1358. continue;
  1359. }
  1360. else if (c == '\\')
  1361. {
  1362. pass_next = 1;
  1363. i++;
  1364. continue;
  1365. }
  1366. else if (backq)
  1367. {
  1368. if (c == '`')
  1369. backq = 0;
  1370. ADVANCE_CHAR (string, slen, i);
  1371. continue;
  1372. }
  1373. else if ((flags & 1) == 0 && c == '`')
  1374. {
  1375. backq = 1;
  1376. i++;
  1377. continue;
  1378. }
  1379. else if ((flags & 1) == 0 && c == open)
  1380. {
  1381. count++;
  1382. i++;
  1383. continue;
  1384. }
  1385. else if (c == close)
  1386. {
  1387. count--;
  1388. if (count == 0)
  1389. break;
  1390. i++;
  1391. continue;
  1392. }
  1393. else if ((flags & 1) == 0 && (c == '\'' || c == '"'))
  1394. {
  1395. i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
  1396. : skip_double_quoted (ss, slen, ++i);
  1397. /* no increment, the skip functions increment past the closing quote. */
  1398. }
  1399. else if ((flags&1) == 0 && c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
  1400. {
  1401. si = i + 2;
  1402. if (string[si] == '\0')
  1403. CQ_RETURN(si);
  1404. if (string[i+1] == LPAREN)
  1405. temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
  1406. else
  1407. temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
  1408. i = si;
  1409. if (string[i] == '\0') /* don't increment i past EOS in loop */
  1410. break;
  1411. i++;
  1412. continue;
  1413. }
  1414. else
  1415. ADVANCE_CHAR (string, slen, i);
  1416. }
  1417. CQ_RETURN(i);
  1418. }
  1419. #if defined (ARRAY_VARS)
  1420. int
  1421. skipsubscript (string, start, flags)
  1422. const char *string;
  1423. int start, flags;
  1424. {
  1425. return (skip_matched_pair (string, start, '[', ']', flags));
  1426. }
  1427. #endif
  1428. /* Skip characters in STRING until we find a character in DELIMS, and return
  1429. the index of that character. START is the index into string at which we
  1430. begin. This is similar in spirit to strpbrk, but it returns an index into
  1431. STRING and takes a starting index. This little piece of code knows quite
  1432. a lot of shell syntax. It's very similar to skip_double_quoted and other
  1433. functions of that ilk. */
  1434. int
  1435. skip_to_delim (string, start, delims, flags)
  1436. char *string;
  1437. int start;
  1438. char *delims;
  1439. int flags;
  1440. {
  1441. int i, pass_next, backq, si, c, invert, skipquote, skipcmd;
  1442. size_t slen;
  1443. char *temp;
  1444. DECLARE_MBSTATE;
  1445. slen = strlen (string + start) + start;
  1446. if (flags & SD_NOJMP)
  1447. no_longjmp_on_fatal_error = 1;
  1448. invert = (flags & SD_INVERT);
  1449. skipcmd = (flags & SD_NOSKIPCMD) == 0;
  1450. i = start;
  1451. pass_next = backq = 0;
  1452. while (c = string[i])
  1453. {
  1454. /* If this is non-zero, we should not let quote characters be delimiters
  1455. and the current character is a single or double quote. We should not
  1456. test whether or not it's a delimiter until after we skip single- or
  1457. double-quoted strings. */
  1458. skipquote = ((flags & SD_NOQUOTEDELIM) && (c == '\'' || c =='"'));
  1459. if (pass_next)
  1460. {
  1461. pass_next = 0;
  1462. if (c == 0)
  1463. CQ_RETURN(i);
  1464. ADVANCE_CHAR (string, slen, i);
  1465. continue;
  1466. }
  1467. else if (c == '\\')
  1468. {
  1469. pass_next = 1;
  1470. i++;
  1471. continue;
  1472. }
  1473. else if (backq)
  1474. {
  1475. if (c == '`')
  1476. backq = 0;
  1477. ADVANCE_CHAR (string, slen, i);
  1478. continue;
  1479. }
  1480. else if (c == '`')
  1481. {
  1482. backq = 1;
  1483. i++;
  1484. continue;
  1485. }
  1486. else if (skipquote == 0 && invert == 0 && member (c, delims))
  1487. break;
  1488. else if (c == '\'' || c == '"')
  1489. {
  1490. i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
  1491. : skip_double_quoted (string, slen, ++i);
  1492. /* no increment, the skip functions increment past the closing quote. */
  1493. }
  1494. else if (c == '$' && ((skipcmd && string[i+1] == LPAREN) || string[i+1] == LBRACE))
  1495. {
  1496. si = i + 2;
  1497. if (string[si] == '\0')
  1498. CQ_RETURN(si);
  1499. if (string[i+1] == LPAREN)
  1500. temp = extract_delimited_string (string, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
  1501. else
  1502. temp = extract_dollar_brace_string (string, &si, 0, SX_NOALLOC);
  1503. i = si;
  1504. if (string[i] == '\0') /* don't increment i past EOS in loop */
  1505. break;
  1506. i++;
  1507. continue;
  1508. }
  1509. #if defined (PROCESS_SUBSTITUTION)
  1510. else if (skipcmd && (c == '<' || c == '>') && string[i+1] == LPAREN)
  1511. {
  1512. si = i + 2;
  1513. if (string[si] == '\0')
  1514. CQ_RETURN(si);
  1515. temp = extract_process_subst (string, (c == '<') ? "<(" : ">(", &si);
  1516. i = si;
  1517. if (string[i] == '\0')
  1518. break;
  1519. i++;
  1520. continue;
  1521. }
  1522. #endif /* PROCESS_SUBSTITUTION */
  1523. else if ((skipquote || invert) && (member (c, delims) == 0))
  1524. break;
  1525. else
  1526. ADVANCE_CHAR (string, slen, i);
  1527. }
  1528. CQ_RETURN(i);
  1529. }
  1530. #if defined (READLINE)
  1531. /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
  1532. an unclosed quoted string), or if the character at EINDEX is quoted
  1533. by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
  1534. single and double-quoted string parsing functions should not return an
  1535. error if there are unclosed quotes or braces. The characters that this
  1536. recognizes need to be the same as the contents of
  1537. rl_completer_quote_characters. */
  1538. int
  1539. char_is_quoted (string, eindex)
  1540. char *string;
  1541. int eindex;
  1542. {
  1543. int i, pass_next, c;
  1544. size_t slen;
  1545. DECLARE_MBSTATE;
  1546. slen = strlen (string);
  1547. no_longjmp_on_fatal_error = 1;
  1548. i = pass_next = 0;
  1549. while (i <= eindex)
  1550. {
  1551. c = string[i];
  1552. if (pass_next)
  1553. {
  1554. pass_next = 0;
  1555. if (i >= eindex) /* XXX was if (i >= eindex - 1) */
  1556. CQ_RETURN(1);
  1557. ADVANCE_CHAR (string, slen, i);
  1558. continue;
  1559. }
  1560. else if (c == '\\')
  1561. {
  1562. pass_next = 1;
  1563. i++;
  1564. continue;
  1565. }
  1566. else if (c == '\'' || c == '"')
  1567. {
  1568. i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
  1569. : skip_double_quoted (string, slen, ++i);
  1570. if (i > eindex)
  1571. CQ_RETURN(1);
  1572. /* no increment, the skip_xxx functions go one past end */
  1573. }
  1574. else
  1575. ADVANCE_CHAR (string, slen, i);
  1576. }
  1577. CQ_RETURN(0);
  1578. }
  1579. int
  1580. unclosed_pair (string, eindex, openstr)
  1581. char *string;
  1582. int eindex;
  1583. char *openstr;
  1584. {
  1585. int i, pass_next, openc, olen;
  1586. size_t slen;
  1587. DECLARE_MBSTATE;
  1588. slen = strlen (string);
  1589. olen = strlen (openstr);
  1590. i = pass_next = openc = 0;
  1591. while (i <= eindex)
  1592. {
  1593. if (pass_next)
  1594. {
  1595. pass_next = 0;
  1596. if (i >= eindex) /* XXX was if (i >= eindex - 1) */
  1597. return 0;
  1598. ADVANCE_CHAR (string, slen, i);
  1599. continue;
  1600. }
  1601. else if (string[i] == '\\')
  1602. {
  1603. pass_next = 1;
  1604. i++;
  1605. continue;
  1606. }
  1607. else if (STREQN (string + i, openstr, olen))
  1608. {
  1609. openc = 1 - openc;
  1610. i += olen;
  1611. }
  1612. else if (string[i] == '\'' || string[i] == '"')
  1613. {
  1614. i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
  1615. : skip_double_quoted (string, slen, i);
  1616. if (i > eindex)
  1617. return 0;
  1618. }
  1619. else
  1620. ADVANCE_CHAR (string, slen, i);
  1621. }
  1622. return (openc);
  1623. }
  1624. /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
  1625. individual words. If DELIMS is NULL, the current value of $IFS is used
  1626. to split the string, and the function follows the shell field splitting
  1627. rules. SENTINEL is an index to look for. NWP, if non-NULL,
  1628. gets the number of words in the returned list. CWP, if non-NULL, gets
  1629. the index of the word containing SENTINEL. Non-whitespace chars in
  1630. DELIMS delimit separate fields. */
  1631. WORD_LIST *
  1632. split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp)
  1633. char *string;
  1634. int slen;
  1635. char *delims;
  1636. int sentinel, flags;
  1637. int *nwp, *cwp;
  1638. {
  1639. int ts, te, i, nw, cw, ifs_split, dflags;
  1640. char *token, *d, *d2;
  1641. WORD_LIST *ret, *tl;
  1642. if (string == 0 || *string == '\0')
  1643. {
  1644. if (nwp)
  1645. *nwp = 0;
  1646. if (cwp)
  1647. *cwp = 0;
  1648. return ((WORD_LIST *)NULL);
  1649. }
  1650. d = (delims == 0) ? ifs_value : delims;
  1651. ifs_split = delims == 0;
  1652. /* Make d2 the non-whitespace characters in delims */
  1653. d2 = 0;
  1654. if (delims)
  1655. {
  1656. size_t slength;
  1657. #if defined (HANDLE_MULTIBYTE)
  1658. size_t mblength = 1;
  1659. #endif
  1660. DECLARE_MBSTATE;
  1661. slength = strlen (delims);
  1662. d2 = (char *)xmalloc (slength + 1);
  1663. i = ts = 0;
  1664. while (delims[i])
  1665. {
  1666. #if defined (HANDLE_MULTIBYTE)
  1667. mbstate_t state_bak;
  1668. state_bak = state;
  1669. mblength = MBRLEN (delims + i, slength, &state);
  1670. if (MB_INVALIDCH (mblength))
  1671. state = state_bak;
  1672. else if (mblength > 1)
  1673. {
  1674. memcpy (d2 + ts, delims + i, mblength);
  1675. ts += mblength;
  1676. i += mblength;
  1677. slength -= mblength;
  1678. continue;
  1679. }
  1680. #endif
  1681. if (whitespace (delims[i]) == 0)
  1682. d2[ts++] = delims[i];
  1683. i++;
  1684. slength--;
  1685. }
  1686. d2[ts] = '\0';
  1687. }
  1688. ret = (WORD_LIST *)NULL;
  1689. /* Remove sequences of whitespace characters at the start of the string, as
  1690. long as those characters are delimiters. */
  1691. for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
  1692. ;
  1693. if (string[i] == '\0')
  1694. return (ret);
  1695. ts = i;
  1696. nw = 0;
  1697. cw = -1;
  1698. dflags = flags|SD_NOJMP;
  1699. while (1)
  1700. {
  1701. te = skip_to_delim (string, ts, d, dflags);
  1702. /* If we have a non-whitespace delimiter character, use it to make a
  1703. separate field. This is just about what $IFS splitting does and
  1704. is closer to the behavior of the shell parser. */
  1705. if (ts == te && d2 && member (string[ts], d2))
  1706. {
  1707. te = ts + 1;
  1708. /* If we're using IFS splitting, the non-whitespace delimiter char
  1709. and any additional IFS whitespace delimits a field. */
  1710. if (ifs_split)
  1711. while (member (string[te], d) && spctabnl (string[te]))
  1712. te++;
  1713. else

Large files files are truncated, but you can click here to view the full file