Imported from ../bash-3.2.48.tar.gz.
This commit is contained in:
parent
0628567a28
commit
f1be666c7d
47 changed files with 703 additions and 159 deletions
119
subst.c
119
subst.c
|
|
@ -4,7 +4,7 @@
|
|||
/* ``Have a little faith, there's magic in the night. You ain't a
|
||||
beauty, but, hey, you're alright.'' */
|
||||
|
||||
/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ unsigned char ifs_firstc;
|
|||
/* Extern functions and variables from different files. */
|
||||
extern int last_command_exit_value, last_command_exit_signal;
|
||||
extern int subshell_environment;
|
||||
extern int subshell_level;
|
||||
extern int subshell_level, parse_and_execute_level;
|
||||
extern int eof_encountered;
|
||||
extern int return_catch_flag, return_catch_value;
|
||||
extern pid_t dollar_dollar_pid;
|
||||
|
|
@ -1278,7 +1278,7 @@ extract_dollar_brace_string (string, sindex, quoted, flags)
|
|||
{
|
||||
if (no_longjmp_on_fatal_error == 0)
|
||||
{ /* { */
|
||||
report_error ("bad substitution: no closing `%s' in %s", "}", string);
|
||||
report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
|
||||
last_command_exit_value = EXECUTION_FAILURE;
|
||||
exp_jump_to_top_level (DISCARD);
|
||||
}
|
||||
|
|
@ -1887,7 +1887,13 @@ string_list_dollar_at (list, quoted)
|
|||
sep[1] = '\0';
|
||||
#endif
|
||||
|
||||
/* XXX -- why call quote_list if ifs == 0? we can get away without doing
|
||||
it now that quote_escapes quotes spaces */
|
||||
#if 0
|
||||
tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
|
||||
#else
|
||||
tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
|
||||
#endif
|
||||
? quote_list (list)
|
||||
: list_quote_escapes (list);
|
||||
|
||||
|
|
@ -2646,11 +2652,12 @@ remove_backslashes (string)
|
|||
|
||||
/* This needs better error handling. */
|
||||
/* Expand W for use as an argument to a unary or binary operator in a
|
||||
[[...]] expression. If SPECIAL is nonzero, this is the rhs argument
|
||||
[[...]] expression. If SPECIAL is 1, this is the rhs argument
|
||||
to the != or == operator, and should be treated as a pattern. In
|
||||
this case, we quote the string specially for the globbing code. The
|
||||
caller is responsible for removing the backslashes if the unquoted
|
||||
words is needed later. */
|
||||
this case, we quote the string specially for the globbing code. If
|
||||
SPECIAL is 2, this is an rhs argument for the =~ operator, and should
|
||||
be quoted appropriately for regcomp/regexec. The caller is responsible
|
||||
for removing the backslashes if the unquoted word is needed later. */
|
||||
char *
|
||||
cond_expand_word (w, special)
|
||||
WORD_DESC *w;
|
||||
|
|
@ -2658,6 +2665,7 @@ cond_expand_word (w, special)
|
|||
{
|
||||
char *r, *p;
|
||||
WORD_LIST *l;
|
||||
int qflags;
|
||||
|
||||
if (w->word == 0 || w->word[0] == '\0')
|
||||
return ((char *)NULL);
|
||||
|
|
@ -2672,8 +2680,11 @@ cond_expand_word (w, special)
|
|||
}
|
||||
else
|
||||
{
|
||||
qflags = QGLOB_CVTNULL;
|
||||
if (special == 2)
|
||||
qflags |= QGLOB_REGEXP;
|
||||
p = string_list (l);
|
||||
r = quote_string_for_globbing (p, QGLOB_CVTNULL);
|
||||
r = quote_string_for_globbing (p, qflags);
|
||||
free (p);
|
||||
}
|
||||
dispose_words (l);
|
||||
|
|
@ -2803,9 +2814,10 @@ expand_string_assignment (string, quoted)
|
|||
passed string when an error occurs. Might want to trap other calls
|
||||
to jump_to_top_level here so we don't endlessly loop. */
|
||||
WORD_LIST *
|
||||
expand_prompt_string (string, quoted)
|
||||
expand_prompt_string (string, quoted, wflags)
|
||||
char *string;
|
||||
int quoted;
|
||||
int wflags;
|
||||
{
|
||||
WORD_LIST *value;
|
||||
WORD_DESC td;
|
||||
|
|
@ -2813,7 +2825,7 @@ expand_prompt_string (string, quoted)
|
|||
if (string == 0 || *string == 0)
|
||||
return ((WORD_LIST *)NULL);
|
||||
|
||||
td.flags = 0;
|
||||
td.flags = wflags;
|
||||
td.word = savestring (string);
|
||||
|
||||
no_longjmp_on_fatal_error = 1;
|
||||
|
|
@ -2916,7 +2928,12 @@ expand_string (string, quoted)
|
|||
|
||||
/* Quote escape characters in string s, but no other characters. This is
|
||||
used to protect CTLESC and CTLNUL in variable values from the rest of
|
||||
the word expansion process after the variable is expanded. */
|
||||
the word expansion process after the variable is expanded. If IFS is
|
||||
null, we quote spaces as well, just in case we split on spaces later
|
||||
(in the case of unquoted $@, we will eventually attempt to split the
|
||||
entire word on spaces). Corresponding code exists in dequote_escapes.
|
||||
Even if we don't end up splitting on spaces, quoting spaces is not a
|
||||
problem. */
|
||||
char *
|
||||
quote_escapes (string)
|
||||
char *string;
|
||||
|
|
@ -2924,17 +2941,19 @@ quote_escapes (string)
|
|||
register char *s, *t;
|
||||
size_t slen;
|
||||
char *result, *send;
|
||||
int quote_spaces;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
slen = strlen (string);
|
||||
send = string + slen;
|
||||
|
||||
quote_spaces = (ifs_value && *ifs_value == 0);
|
||||
t = result = (char *)xmalloc ((slen * 2) + 1);
|
||||
s = string;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
if (*s == CTLESC || *s == CTLNUL)
|
||||
if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' '))
|
||||
*t++ = CTLESC;
|
||||
COPY_CHAR_P (t, s, send);
|
||||
}
|
||||
|
|
@ -2976,6 +2995,7 @@ dequote_escapes (string)
|
|||
register char *s, *t;
|
||||
size_t slen;
|
||||
char *result, *send;
|
||||
int quote_spaces;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
if (string == 0)
|
||||
|
|
@ -2990,9 +3010,10 @@ dequote_escapes (string)
|
|||
if (strchr (string, CTLESC) == 0)
|
||||
return (strcpy (result, s));
|
||||
|
||||
quote_spaces = (ifs_value && *ifs_value == 0);
|
||||
while (*s)
|
||||
{
|
||||
if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
|
||||
if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
|
||||
{
|
||||
s++;
|
||||
if (*s == '\0')
|
||||
|
|
@ -3954,7 +3975,11 @@ parameter_brace_remove_pattern (varname, value, patstr, rtype, quoted)
|
|||
if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
|
||||
patstr++;
|
||||
|
||||
pattern = getpattern (patstr, quoted, 1);
|
||||
/* Need to pass getpattern newly-allocated memory in case of expansion --
|
||||
the expansion code will free the passed string on an error. */
|
||||
temp1 = savestring (patstr);
|
||||
pattern = getpattern (temp1, quoted, 1);
|
||||
free (temp1);
|
||||
|
||||
temp1 = (char *)NULL; /* shut up gcc */
|
||||
switch (vtype)
|
||||
|
|
@ -4123,6 +4148,12 @@ unlink_fifo_list ()
|
|||
nfifo = 0;
|
||||
}
|
||||
|
||||
int
|
||||
fifos_pending ()
|
||||
{
|
||||
return nfifo;
|
||||
}
|
||||
|
||||
static char *
|
||||
make_named_pipe ()
|
||||
{
|
||||
|
|
@ -4172,6 +4203,12 @@ add_fifo_list (fd)
|
|||
nfds++;
|
||||
}
|
||||
|
||||
int
|
||||
fifos_pending ()
|
||||
{
|
||||
return 0; /* used for cleanup; not needed with /dev/fd */
|
||||
}
|
||||
|
||||
void
|
||||
unlink_fifo_list ()
|
||||
{
|
||||
|
|
@ -4456,7 +4493,15 @@ read_comsub (fd, quoted)
|
|||
/* Add the character to ISTRING, possibly after resizing it. */
|
||||
RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
|
||||
|
||||
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL)
|
||||
/* This is essentially quote_string inline */
|
||||
if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
|
||||
istring[istring_index++] = CTLESC;
|
||||
/* Escape CTLESC and CTLNUL in the output to protect those characters
|
||||
from the rest of the word expansions (word splitting and globbing.)
|
||||
This is essentially quote_escapes inline. */
|
||||
else if (c == CTLESC)
|
||||
istring[istring_index++] = CTLESC;
|
||||
else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0)))
|
||||
istring[istring_index++] = CTLESC;
|
||||
|
||||
istring[istring_index++] = c;
|
||||
|
|
@ -4578,7 +4623,8 @@ command_substitute (string, quoted)
|
|||
#if defined (JOB_CONTROL)
|
||||
set_sigchld_handler ();
|
||||
stop_making_children ();
|
||||
pipeline_pgrp = old_pipeline_pgrp;
|
||||
if (pid != 0)
|
||||
pipeline_pgrp = old_pipeline_pgrp;
|
||||
#else
|
||||
stop_making_children ();
|
||||
#endif /* JOB_CONTROL */
|
||||
|
|
@ -4665,6 +4711,9 @@ command_substitute (string, quoted)
|
|||
|
||||
last_command_exit_value = rc;
|
||||
rc = run_exit_trap ();
|
||||
#if defined (PROCESS_SUBSTITUTION)
|
||||
unlink_fifo_list ();
|
||||
#endif
|
||||
exit (rc);
|
||||
}
|
||||
else
|
||||
|
|
@ -4763,7 +4812,7 @@ array_length_reference (s)
|
|||
else
|
||||
t = (ind == 0) ? value_cell (var) : (char *)NULL;
|
||||
|
||||
len = STRLEN (t);
|
||||
len = MB_STRLEN (t);
|
||||
return (len);
|
||||
}
|
||||
#endif /* ARRAY_VARS */
|
||||
|
|
@ -4860,10 +4909,11 @@ parameter_brace_expand_word (name, var_is_special, quoted)
|
|||
char *temp, *tt;
|
||||
intmax_t arg_index;
|
||||
SHELL_VAR *var;
|
||||
int atype;
|
||||
int atype, rflags;
|
||||
|
||||
ret = 0;
|
||||
temp = 0;
|
||||
rflags = 0;
|
||||
|
||||
/* Handle multiple digit arguments, as in ${11}. */
|
||||
if (legal_number (name, &arg_index))
|
||||
|
|
@ -4896,6 +4946,8 @@ parameter_brace_expand_word (name, var_is_special, quoted)
|
|||
temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
|
||||
? quote_string (temp)
|
||||
: quote_escapes (temp);
|
||||
else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
|
||||
rflags |= W_HASQUOTEDNULL;
|
||||
}
|
||||
#endif
|
||||
else if (var = find_variable (name))
|
||||
|
|
@ -4923,6 +4975,7 @@ parameter_brace_expand_word (name, var_is_special, quoted)
|
|||
{
|
||||
ret = alloc_word_desc ();
|
||||
ret->word = temp;
|
||||
ret->flags |= rflags;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -5546,12 +5599,16 @@ parameter_brace_substring (varname, value, substr, quoted)
|
|||
so verify_substring_values just returns the numbers specified and we
|
||||
rely on array_subrange to understand how to deal with them). */
|
||||
tt = array_subrange (array_cell (v), e1, e2, starsub, quoted);
|
||||
#if 0
|
||||
/* array_subrange now calls array_quote_escapes as appropriate, so the
|
||||
caller no longer needs to. */
|
||||
if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
|
||||
{
|
||||
temp = tt ? quote_escapes (tt) : (char *)NULL;
|
||||
FREE (tt);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
temp = tt;
|
||||
break;
|
||||
#endif
|
||||
|
|
@ -5707,6 +5764,11 @@ parameter_brace_patsub (varname, value, patsub, quoted)
|
|||
vtype &= ~VT_STARSUB;
|
||||
|
||||
mflags = 0;
|
||||
if (patsub && *patsub == '/')
|
||||
{
|
||||
mflags |= MATCH_GLOBREP;
|
||||
patsub++;
|
||||
}
|
||||
|
||||
/* Malloc this because expand_string_if_necessary or one of the expansion
|
||||
functions in its call chain may free it on a substitution error. */
|
||||
|
|
@ -5741,13 +5803,12 @@ parameter_brace_patsub (varname, value, patsub, quoted)
|
|||
}
|
||||
|
||||
/* ksh93 doesn't allow the match specifier to be a part of the expanded
|
||||
pattern. This is an extension. */
|
||||
pattern. This is an extension. Make sure we don't anchor the pattern
|
||||
at the beginning or end of the string if we're doing global replacement,
|
||||
though. */
|
||||
p = pat;
|
||||
if (pat && pat[0] == '/')
|
||||
{
|
||||
mflags |= MATCH_GLOBREP|MATCH_ANY;
|
||||
p++;
|
||||
}
|
||||
if (mflags & MATCH_GLOBREP)
|
||||
mflags |= MATCH_ANY;
|
||||
else if (pat && pat[0] == '#')
|
||||
{
|
||||
mflags |= MATCH_BEG;
|
||||
|
|
@ -5798,12 +5859,16 @@ parameter_brace_patsub (varname, value, patsub, quoted)
|
|||
#if defined (ARRAY_VARS)
|
||||
case VT_ARRAYVAR:
|
||||
temp = array_patsub (array_cell (v), p, rep, mflags);
|
||||
#if 0
|
||||
/* Don't need to do this anymore; array_patsub calls array_quote_escapes
|
||||
as appropriate before adding the space separators. */
|
||||
if (temp && (mflags & MATCH_QUOTED) == 0)
|
||||
{
|
||||
tt = quote_escapes (temp);
|
||||
free (temp);
|
||||
temp = tt;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -7607,6 +7672,10 @@ exp_jump_to_top_level (v)
|
|||
expand_no_split_dollar_star = 0; /* XXX */
|
||||
expanding_redir = 0;
|
||||
|
||||
if (parse_and_execute_level == 0)
|
||||
top_level_cleanup (); /* from sig.c */
|
||||
|
||||
|
||||
jump_to_top_level (v);
|
||||
}
|
||||
|
||||
|
|
@ -7824,7 +7893,7 @@ glob_expand_word_list (tlist, eflags)
|
|||
else if (fail_glob_expansion != 0)
|
||||
{
|
||||
report_error (_("no match: %s"), tlist->word->word);
|
||||
jump_to_top_level (DISCARD);
|
||||
exp_jump_to_top_level (DISCARD);
|
||||
}
|
||||
else if (allow_null_glob_expansion == 0)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue