mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-22 05:17:59 +02:00
commit bash-20161108 snapshot
This commit is contained in:
+90
-1
@@ -12008,7 +12008,7 @@ aclocal.m4
|
||||
-----
|
||||
variables.c
|
||||
- get_bashpid: BASHPID is no longer readonly; assignments to it are
|
||||
just ignored. Suggested by Martijn Dekker <martijn@inlv.org>
|
||||
just ignored.
|
||||
|
||||
doc/{bash.1,bashref.texi}
|
||||
- BASHPID: note that assignments are ignored and unsetting BASHPID
|
||||
@@ -12199,3 +12199,92 @@ lib/glob/sm_loop.c
|
||||
- GMATCH: allow trailing backslash in pattern to explicitly match a
|
||||
backslash that is the last character in the string. Bug report from
|
||||
Stephane Chazelas <stephane.chazelas@gmail.com>
|
||||
|
||||
11/5
|
||||
----
|
||||
builtins/common.c
|
||||
- display_signal_list: if displaying a signal name corresponding to an
|
||||
exit status > 128, don't display the SIG prefix at all. Old code
|
||||
made displaying the SIG prefix dependent on JOB_CONTROL define.
|
||||
Report and fix from Martijn Dekker <martijn@inlv.org>
|
||||
|
||||
execute_cmd.c
|
||||
- execute_subshell_builtin_or_function: call without_job_control even
|
||||
if JOB_CONTROL is not defined. Similar to fix from 9/23.
|
||||
Report from Martijn Dekker <martijn@inlv.org>
|
||||
|
||||
execute_cmd.c
|
||||
- execute_simple_command: free memory allocated and passed to
|
||||
make_child in the child process if JOB_CONTROL is defined
|
||||
- execute_command_internal: free memory allocated and passed to
|
||||
make_child in the child process created to run a () subshell or a
|
||||
compound command within a pipeline if JOB_CONTROL is defined
|
||||
- execute_coproc: free memory allocated and passed to make_child in
|
||||
the child process if JOB_CONTROL is defined
|
||||
- execute_disk_command: free memory allocated and passed to
|
||||
make_child in the child process if JOB_CONTROL is defined. This
|
||||
series of fixes is the result of reports from
|
||||
Eduardo A. Bustamante López <dualbus@gmail.com>
|
||||
|
||||
11/6
|
||||
----
|
||||
lib/sh/unicode.c
|
||||
- u32toutf16: fix to prevent outputting broken surrogate pairs for
|
||||
Japanese locales (ja_JP.UTF-8) on cygwin (which uses UTF-16 natively).
|
||||
Report and fix from Koichi MURASE <myoga.murase@gmail.com>
|
||||
|
||||
builtins/trap.def
|
||||
- trap_builtin: if OP is `-' (revert), set the SIGINT signal handler
|
||||
to sigint_sighandler if the shell is interactive and sourcing a
|
||||
file (interactive_shell && sourcelevel) or running a trap
|
||||
(interactive_shell && running_trap) even if it's not currently
|
||||
interactive. Report from Martijn Dekker <martijn@inlv.org>
|
||||
|
||||
builtins/read.def
|
||||
- check for and read multibyte characters in all cases, not just when
|
||||
we are reading a specific number of characters, as long as
|
||||
mb_cur_max > 1
|
||||
|
||||
subst.c
|
||||
- expand_word_internal: some improvements to code that converts istring
|
||||
into a WORD_LIST * to avoid multiple allocations and copies of
|
||||
istring, which is already malloc'ed memory -- reduce number of malloc
|
||||
and free calls
|
||||
|
||||
test.c
|
||||
- unary_test: make sure if we test -v array[@] or array[*] that we
|
||||
free the return value from array_value
|
||||
|
||||
11/8
|
||||
----
|
||||
expr.c
|
||||
- expcond: make sure to set `noeval' before reading tokens depending on
|
||||
the result of the conditional test, since readtok() can evaluate
|
||||
identifiers (and recursively those containing expressions). Report
|
||||
and fix from Koichi MURASE <myoga.murase@gmail.com>
|
||||
|
||||
builtins/evalstring.c
|
||||
- should_suppress_fork: make sure to check for traps on EXIT and
|
||||
ERR, since any_signals_trapped() only checks for `real' signals,
|
||||
not the fake shell ones. Fixes bug reported by Werner Fink
|
||||
<werner@suse.de>
|
||||
- optimize_subshell_command: ditto
|
||||
|
||||
11/9
|
||||
----
|
||||
eval.c
|
||||
- reader_loop: change so that we don't reset the SIGINT handler every
|
||||
time through the command loop in an interactive shell if the signal
|
||||
is trapped (as the comment noted). Reported by Report from Martijn
|
||||
Dekker <martijn@inlv.org>
|
||||
|
||||
subst.c
|
||||
- parameter_brace_{patsub,remove_pattern,transform,casemod}: save and
|
||||
restore this_command_name while temporarily setting it for use in
|
||||
error messages. Fixes use-after-free error reported by
|
||||
op7ic \x00 <op7ica@gmail.com>
|
||||
- string_extract_verbatim: make sure when we increment i by 2 due to
|
||||
a CTLESC or CTLESC-CTLNUL that we don't read past the end of the
|
||||
string. This can happen if the string ends with an odd number of
|
||||
CTLESC chars. Fixes oob-read error reported by
|
||||
op7ic \x00 <op7ica@gmail.com>
|
||||
|
||||
@@ -782,13 +782,9 @@ display_signal_list (list, forcecols)
|
||||
list = list->next;
|
||||
continue;
|
||||
}
|
||||
#if defined (JOB_CONTROL)
|
||||
/* POSIX.2 says that `kill -l signum' prints the signal name without
|
||||
the `SIG' prefix. */
|
||||
printf ("%s\n", (this_shell_builtin == kill_builtin) ? name + 3 : name);
|
||||
#else
|
||||
printf ("%s\n", name);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -104,12 +104,9 @@ should_suppress_fork (command)
|
||||
running_trap == 0 &&
|
||||
*bash_input.location.string == '\0' &&
|
||||
command->type == cm_simple &&
|
||||
#if 0
|
||||
signal_is_trapped (EXIT_TRAP) == 0 &&
|
||||
signal_is_trapped (ERROR_TRAP) == 0 &&
|
||||
#else
|
||||
any_signals_trapped () < 0 &&
|
||||
#endif
|
||||
command->redirects == 0 && command->value.Simple->redirects == 0 &&
|
||||
((command->flags & CMD_TIME_PIPELINE) == 0) &&
|
||||
((command->flags & CMD_INVERT_RETURN) == 0));
|
||||
@@ -134,6 +131,8 @@ optimize_subshell_command (command)
|
||||
{
|
||||
if (running_trap == 0 &&
|
||||
command->type == cm_simple &&
|
||||
signal_is_trapped (EXIT_TRAP) == 0 &&
|
||||
signal_is_trapped (ERROR_TRAP) == 0 &&
|
||||
any_signals_trapped () < 0 &&
|
||||
command->redirects == 0 && command->value.Simple->redirects == 0 &&
|
||||
((command->flags & CMD_TIME_PIPELINE) == 0) &&
|
||||
|
||||
+7
-1
@@ -181,6 +181,7 @@ read_builtin (list)
|
||||
int size, i, nr, pass_next, saw_escape, eof, opt, retval, code, print_ps2;
|
||||
int input_is_tty, input_is_pipe, unbuffered_read, skip_ctlesc, skip_ctlnul;
|
||||
int raw, edit, nchars, silent, have_timeout, ignore_delim, fd, lastsig, t_errno;
|
||||
int mb_cur_max;
|
||||
unsigned int tmsec, tmusec;
|
||||
long ival, uval;
|
||||
intmax_t intval;
|
||||
@@ -235,6 +236,7 @@ read_builtin (list)
|
||||
rlind = 0;
|
||||
#endif
|
||||
|
||||
mb_cur_max = MB_CUR_MAX;
|
||||
tmsec = tmusec = 0; /* no timeout */
|
||||
nr = nchars = input_is_tty = input_is_pipe = unbuffered_read = have_timeout = 0;
|
||||
delim = '\n'; /* read until newline */
|
||||
@@ -664,7 +666,11 @@ add_char:
|
||||
CHECK_ALRM;
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (nchars > 0 && MB_CUR_MAX > 1 && is_basic (c) == 0)
|
||||
# if 0
|
||||
if (nchars > 0 && mb_cur_max > 1 && is_basic (c) == 0)
|
||||
# else
|
||||
if (mb_cur_max > 1 && is_basic (c) == 0)
|
||||
# endif
|
||||
{
|
||||
input_string[i] = '\0'; /* for simplicity and debugging */
|
||||
i += read_mbchar (fd, input_string, i, c, unbuffered_read);
|
||||
|
||||
@@ -98,6 +98,7 @@ static int display_traps __P((WORD_LIST *));
|
||||
#define IGNORE 2 /* Ignore this signal. */
|
||||
|
||||
extern int posixly_correct, subshell_environment;
|
||||
extern int sourcelevel, running_trap;
|
||||
|
||||
int
|
||||
trap_builtin (list)
|
||||
@@ -212,6 +213,9 @@ trap_builtin (list)
|
||||
was SIG_IGN? */
|
||||
if (interactive)
|
||||
set_signal_handler (SIGINT, sigint_sighandler);
|
||||
/* special cases for interactive == 0 */
|
||||
else if (interactive_shell && (sourcelevel||running_trap))
|
||||
set_signal_handler (SIGINT, sigint_sighandler);
|
||||
else
|
||||
set_signal_handler (SIGINT, termsig_sighandler);
|
||||
break;
|
||||
|
||||
@@ -90,7 +90,7 @@ reader_loop ()
|
||||
|
||||
/* XXX - why do we set this every time through the loop? And why do
|
||||
it if SIGINT is trapped in an interactive shell? */
|
||||
if (interactive_shell && signal_is_ignored (SIGINT) == 0)
|
||||
if (interactive_shell && signal_is_ignored (SIGINT) == 0 && signal_is_trapped (SIGINT) == 0)
|
||||
set_signal_handler (SIGINT, sigint_sighandler);
|
||||
|
||||
if (code != NOT_JUMPED)
|
||||
|
||||
+23
-6
@@ -602,12 +602,13 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
{
|
||||
pid_t paren_pid;
|
||||
int s;
|
||||
char *p;
|
||||
|
||||
/* Fork a subshell, turn off the subshell bit, turn off job
|
||||
control and call execute_command () on the command again. */
|
||||
line_number_for_err_trap = line_number; /* XXX - save value? */
|
||||
tcmd = make_command_string (command);
|
||||
paren_pid = make_child (savestring (tcmd), asynchronous);
|
||||
paren_pid = make_child (p = savestring (tcmd), asynchronous);
|
||||
|
||||
if (user_subshell && signal_is_trapped (ERROR_TRAP) &&
|
||||
signal_in_progress (DEBUG_TRAP) == 0 && running_trap == 0)
|
||||
@@ -618,6 +619,9 @@ execute_command_internal (command, asynchronous, pipe_in, pipe_out,
|
||||
|
||||
if (paren_pid == 0)
|
||||
{
|
||||
#if defined (JOB_CONTROL)
|
||||
FREE (p); /* child doesn't use pointer */
|
||||
#endif
|
||||
/* We want to run the exit trap for forced {} subshells, and we
|
||||
want to note this before execute_in_subshell modifies the
|
||||
COMMAND struct. Need to keep in mind that execute_in_subshell
|
||||
@@ -2279,7 +2283,7 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
|
||||
int rpipe[2], wpipe[2], estat, invert;
|
||||
pid_t coproc_pid;
|
||||
Coproc *cp;
|
||||
char *tcmd;
|
||||
char *tcmd, *p;
|
||||
sigset_t set, oset;
|
||||
|
||||
/* XXX -- can be removed after changes to handle multiple coprocs */
|
||||
@@ -2298,13 +2302,17 @@ execute_coproc (command, pipe_in, pipe_out, fds_to_close)
|
||||
|
||||
BLOCK_SIGNAL (SIGCHLD, set, oset);
|
||||
|
||||
coproc_pid = make_child (savestring (tcmd), 1);
|
||||
coproc_pid = make_child (p = savestring (tcmd), 1);
|
||||
|
||||
if (coproc_pid == 0)
|
||||
{
|
||||
close (rpipe[0]);
|
||||
close (wpipe[1]);
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
FREE (p);
|
||||
#endif
|
||||
|
||||
UNBLOCK_SIGNAL (oset);
|
||||
estat = execute_in_subshell (command, 1, wpipe[0], rpipe[1], fds_to_close);
|
||||
|
||||
@@ -4138,7 +4146,9 @@ execute_simple_command (simple_command, pipe_in, pipe_out, async, fds_to_close)
|
||||
if (async)
|
||||
subshell_level++; /* not for pipes yet */
|
||||
|
||||
FREE (p);
|
||||
#if defined (JOB_CONTROL)
|
||||
FREE (p); /* child doesn't use pointer */
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4936,6 +4946,8 @@ execute_subshell_builtin_or_function (words, redirects, builtin, var,
|
||||
without_job_control ();
|
||||
|
||||
set_sigchld_handler ();
|
||||
#else
|
||||
without_job_control ();
|
||||
#endif /* JOB_CONTROL */
|
||||
|
||||
set_sigint_handler ();
|
||||
@@ -5166,7 +5178,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
|
||||
struct fd_bitmap *fds_to_close;
|
||||
int cmdflags;
|
||||
{
|
||||
char *pathname, *command, **args;
|
||||
char *pathname, *command, **args, *p;
|
||||
int nofork, stdpath, result;
|
||||
pid_t pid;
|
||||
SHELL_VAR *hookf;
|
||||
@@ -5176,6 +5188,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
|
||||
nofork = (cmdflags & CMD_NO_FORK); /* Don't fork, just exec, if no pipes */
|
||||
pathname = words->word->word;
|
||||
|
||||
p = 0;
|
||||
result = EXECUTION_SUCCESS;
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
command = (char *)NULL;
|
||||
@@ -5214,7 +5227,7 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
|
||||
if (nofork && pipe_in == NO_PIPE && pipe_out == NO_PIPE)
|
||||
pid = 0;
|
||||
else
|
||||
pid = make_child (savestring (command_line), async);
|
||||
pid = make_child (p = savestring (command_line), async);
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
@@ -5226,6 +5239,10 @@ execute_disk_command (words, redirects, command_line, pipe_in, pipe_out,
|
||||
|
||||
CHECK_SIGTERM;
|
||||
|
||||
#if defined (JOB_CONTROL)
|
||||
FREE (p);
|
||||
#endif
|
||||
|
||||
/* restore_original_signals may have undone the work done
|
||||
by make_child to ensure that SIGINT and SIGQUIT are ignored
|
||||
in asynchronous children. */
|
||||
|
||||
@@ -578,24 +578,23 @@ expcond ()
|
||||
rval = cval = explor ();
|
||||
if (curtok == QUES) /* found conditional expr */
|
||||
{
|
||||
readtok ();
|
||||
if (curtok == 0 || curtok == COL)
|
||||
evalerror (_("expression expected"));
|
||||
if (cval == 0)
|
||||
{
|
||||
set_noeval = 1;
|
||||
noeval++;
|
||||
}
|
||||
|
||||
readtok ();
|
||||
if (curtok == 0 || curtok == COL)
|
||||
evalerror (_("expression expected"));
|
||||
|
||||
val1 = EXP_HIGHEST ();
|
||||
|
||||
if (set_noeval)
|
||||
noeval--;
|
||||
if (curtok != COL)
|
||||
evalerror (_("`:' expected for conditional expression"));
|
||||
readtok ();
|
||||
if (curtok == 0)
|
||||
evalerror (_("expression expected"));
|
||||
|
||||
set_noeval = 0;
|
||||
if (cval)
|
||||
{
|
||||
@@ -603,7 +602,11 @@ expcond ()
|
||||
noeval++;
|
||||
}
|
||||
|
||||
readtok ();
|
||||
if (curtok == 0)
|
||||
evalerror (_("expression expected"));
|
||||
val2 = expcond ();
|
||||
|
||||
if (set_noeval)
|
||||
noeval--;
|
||||
rval = cval ? val1 : val2;
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
/* unicode.c - functions to convert unicode characters */
|
||||
|
||||
/* Copyright (C) 2010-2015 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2010-2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -219,12 +219,12 @@ u32toutf16 (c, s)
|
||||
int l;
|
||||
|
||||
l = 0;
|
||||
if (c < 0x0d800)
|
||||
if (c < 0x0d800 || (c >= 0x0e000 && c <= 0x0ffff))
|
||||
{
|
||||
s[0] = (unsigned short) (c & 0xFFFF);
|
||||
l = 1;
|
||||
}
|
||||
else if (c >= 0x0e000 && c <= 0x010ffff)
|
||||
else if (c >= 0x10000 && c <= 0x010ffff)
|
||||
{
|
||||
c -= 0x010000;
|
||||
s[0] = (unsigned short)((c >> 10) + 0xd800);
|
||||
|
||||
@@ -170,7 +170,10 @@ alloc_pid_list ()
|
||||
|
||||
/* None of the newly allocated slots have process id's yet. */
|
||||
for (i = old; i < pid_list_size; i++)
|
||||
pid_list[i].pid = NO_PID;
|
||||
{
|
||||
pid_list[i].pid = NO_PID;
|
||||
pid_list[i].status = pid_list[i].flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the offset within the PID_LIST array of an empty slot. This can
|
||||
@@ -399,8 +402,9 @@ cleanup_dead_jobs ()
|
||||
|
||||
for (i = 0; i < pid_list_size; i++)
|
||||
{
|
||||
if ((pid_list[i].flags & PROC_RUNNING) == 0 &&
|
||||
(pid_list[i].flags & PROC_NOTIFIED))
|
||||
if (pid_list[i].pid != NO_PID &&
|
||||
(pid_list[i].flags & PROC_RUNNING) == 0 &&
|
||||
(pid_list[i].flags & PROC_NOTIFIED))
|
||||
pid_list[i].pid = NO_PID;
|
||||
}
|
||||
|
||||
|
||||
@@ -1166,6 +1166,7 @@ string_extract_verbatim (string, slen, sindex, charlist, flags)
|
||||
if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
|
||||
{
|
||||
i += 2;
|
||||
CHECK_STRING_OVERRUN (i, i, slen, c);
|
||||
continue;
|
||||
}
|
||||
/* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
|
||||
@@ -1174,6 +1175,7 @@ string_extract_verbatim (string, slen, sindex, charlist, flags)
|
||||
else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
|
||||
{
|
||||
i += 2;
|
||||
CHECK_STRING_OVERRUN (i, i, slen, c);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2773,11 +2775,11 @@ list_string (string, separators, quoted)
|
||||
extract a word, stopping at a separator
|
||||
skip sequences of spc, tab, or nl as long as they are separators
|
||||
This obeys the field splitting rules in Posix.2. */
|
||||
slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 1;
|
||||
slen = STRLEN (string);
|
||||
for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
|
||||
{
|
||||
/* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
|
||||
unless multibyte chars are possible. */
|
||||
/* Don't need string length in ADVANCE_CHAR unless multibyte chars are
|
||||
possible, but need it in string_extract_verbatim for bounds checking */
|
||||
current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags);
|
||||
if (current_word == 0)
|
||||
break;
|
||||
@@ -2902,9 +2904,9 @@ get_word_from_string (stringp, separators, endptr)
|
||||
|
||||
This obeys the field splitting rules in Posix.2. */
|
||||
sindex = 0;
|
||||
/* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
|
||||
unless multibyte chars are possible. */
|
||||
slen = (MB_CUR_MAX > 1) ? STRLEN (s) : 1;
|
||||
/* Don't need string length in ADVANCE_CHAR unless multibyte chars are
|
||||
possible, but need it in string_extract_verbatim for bounds checking */
|
||||
slen = STRLEN (s);
|
||||
current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
|
||||
|
||||
/* Set ENDPTR to the first character after the end of the word. */
|
||||
@@ -5015,17 +5017,21 @@ parameter_brace_remove_pattern (varname, value, ind, patstr, rtype, quoted, flag
|
||||
int rtype, quoted, flags;
|
||||
{
|
||||
int vtype, patspec, starsub;
|
||||
char *temp1, *val, *pattern;
|
||||
char *temp1, *val, *pattern, *oname;
|
||||
SHELL_VAR *v;
|
||||
|
||||
if (value == 0)
|
||||
return ((char *)NULL);
|
||||
|
||||
oname = this_command_name;
|
||||
this_command_name = varname;
|
||||
|
||||
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
|
||||
if (vtype == -1)
|
||||
return ((char *)NULL);
|
||||
{
|
||||
this_command_name = oname;
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
starsub = vtype & VT_STARSUB;
|
||||
vtype &= ~VT_STARSUB;
|
||||
@@ -5079,6 +5085,8 @@ parameter_brace_remove_pattern (varname, value, ind, patstr, rtype, quoted, flag
|
||||
break;
|
||||
}
|
||||
|
||||
this_command_name = oname;
|
||||
|
||||
FREE (pattern);
|
||||
return temp1;
|
||||
}
|
||||
@@ -5285,18 +5293,22 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, flags)
|
||||
int rtype, quoted, flags;
|
||||
{
|
||||
int vtype, xc;
|
||||
char *temp1, *val;
|
||||
char *temp1, *val, *oname;
|
||||
SHELL_VAR *v;
|
||||
|
||||
xc = xform[0];
|
||||
if (value == 0 && xc != 'A' && xc != 'a')
|
||||
return ((char *)NULL);
|
||||
|
||||
oname = this_command_name;
|
||||
this_command_name = varname;
|
||||
|
||||
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
|
||||
if (vtype == -1)
|
||||
return ((char *)NULL);
|
||||
{
|
||||
this_command_name = oname;
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
/* check for valid values of xc */
|
||||
switch (xc)
|
||||
@@ -5308,6 +5320,7 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, flags)
|
||||
case 'Q': /* quote reusably */
|
||||
break;
|
||||
default:
|
||||
this_command_name = oname;
|
||||
return &expand_param_error;
|
||||
}
|
||||
|
||||
@@ -5350,6 +5363,7 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, flags)
|
||||
break;
|
||||
}
|
||||
|
||||
this_command_name = oname;
|
||||
return temp1;
|
||||
}
|
||||
|
||||
@@ -7631,17 +7645,21 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, pflags, flags)
|
||||
int quoted, pflags, flags;
|
||||
{
|
||||
int vtype, mflags, starsub, delim;
|
||||
char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
|
||||
char *val, *temp, *pat, *rep, *p, *lpatsub, *tt, *oname;
|
||||
SHELL_VAR *v;
|
||||
|
||||
if (value == 0)
|
||||
return ((char *)NULL);
|
||||
|
||||
this_command_name = varname;
|
||||
oname = this_command_name;
|
||||
this_command_name = varname; /* error messages */
|
||||
|
||||
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
|
||||
if (vtype == -1)
|
||||
return ((char *)NULL);
|
||||
{
|
||||
this_command_name = oname;
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
starsub = vtype & VT_STARSUB;
|
||||
vtype &= ~VT_STARSUB;
|
||||
@@ -7769,6 +7787,8 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, pflags, flags)
|
||||
FREE (rep);
|
||||
free (lpatsub);
|
||||
|
||||
this_command_name = oname;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -7825,17 +7845,21 @@ parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
|
||||
int quoted, flags;
|
||||
{
|
||||
int vtype, starsub, modop, mflags, x;
|
||||
char *val, *temp, *pat, *p, *lpat, *tt;
|
||||
char *val, *temp, *pat, *p, *lpat, *tt, *oname;
|
||||
SHELL_VAR *v;
|
||||
|
||||
if (value == 0)
|
||||
return ((char *)NULL);
|
||||
|
||||
oname = this_command_name;
|
||||
this_command_name = varname;
|
||||
|
||||
vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
|
||||
if (vtype == -1)
|
||||
return ((char *)NULL);
|
||||
{
|
||||
this_command_name = oname;
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
starsub = vtype & VT_STARSUB;
|
||||
vtype &= ~VT_STARSUB;
|
||||
@@ -7912,6 +7936,8 @@ parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
|
||||
FREE (pat);
|
||||
free (lpat);
|
||||
|
||||
this_command_name = oname;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -9779,7 +9805,9 @@ finished_with_string:
|
||||
{
|
||||
istring[0] = CTLNUL;
|
||||
istring[1] = '\0';
|
||||
tword = make_bare_word (istring);
|
||||
tword = alloc_word_desc ();
|
||||
tword->word = istring;
|
||||
istring = 0; /* avoid later free() */
|
||||
tword->flags |= W_HASQUOTEDNULL; /* XXX */
|
||||
list = make_word_list (tword, (WORD_LIST *)NULL);
|
||||
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
|
||||
@@ -9792,22 +9820,16 @@ finished_with_string:
|
||||
null arguments */
|
||||
else if (quoted_state == UNQUOTED || quoted_dollar_at)
|
||||
list = (WORD_LIST *)NULL;
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
tword = make_bare_word (istring);
|
||||
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
|
||||
tword->flags |= W_QUOTED;
|
||||
list = make_word_list (tword, (WORD_LIST *)NULL);
|
||||
}
|
||||
#else
|
||||
else
|
||||
list = (WORD_LIST *)NULL;
|
||||
#endif
|
||||
}
|
||||
else if (word->flags & W_NOSPLIT)
|
||||
{
|
||||
tword = make_bare_word (istring);
|
||||
tword = alloc_word_desc ();
|
||||
tword->word = istring;
|
||||
if (had_quoted_null && QUOTED_NULL (istring))
|
||||
tword->flags |= W_HASQUOTEDNULL;
|
||||
istring = 0; /* avoid later free() */
|
||||
if (word->flags & W_ASSIGNMENT)
|
||||
tword->flags |= W_ASSIGNMENT; /* XXX */
|
||||
if (word->flags & W_COMPASSIGN)
|
||||
@@ -9820,8 +9842,6 @@ finished_with_string:
|
||||
tword->flags |= W_NOEXPAND; /* XXX */
|
||||
if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
|
||||
tword->flags |= W_QUOTED;
|
||||
if (had_quoted_null && QUOTED_NULL (istring))
|
||||
tword->flags |= W_HASQUOTEDNULL;
|
||||
list = make_word_list (tword, (WORD_LIST *)NULL);
|
||||
}
|
||||
else
|
||||
@@ -9855,47 +9875,36 @@ finished_with_string:
|
||||
double-quoted $@ while expanding it. */
|
||||
else if (has_dollar_at && quoted_dollar_at == 0 && ifs_chars && quoted == 0 && (word->flags & W_NOSPLIT2))
|
||||
{
|
||||
tword = alloc_word_desc ();
|
||||
/* Only split and rejoin if we have to */
|
||||
if (*ifs_chars && *ifs_chars != ' ')
|
||||
{
|
||||
list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
|
||||
tstring = string_list (list);
|
||||
tword->word = string_list (list);
|
||||
}
|
||||
else
|
||||
tstring = istring;
|
||||
tword = make_bare_word (tstring);
|
||||
if (tstring != istring)
|
||||
free (tstring);
|
||||
tword->word = istring;
|
||||
if (had_quoted_null && QUOTED_NULL (istring))
|
||||
tword->flags |= W_HASQUOTEDNULL; /* XXX */
|
||||
if (tword->word != istring)
|
||||
free (istring);
|
||||
istring = 0; /* avoid later free() */
|
||||
goto set_word_flags;
|
||||
}
|
||||
/* This is the attempt to make $* in an assignment context (a=$*) and
|
||||
array variables subscripted with * in an assignment context (a=${foo[*]})
|
||||
behave similarly. It has side effects that, though they increase
|
||||
compatibility with other shells, are not backwards compatible. */
|
||||
#if 0
|
||||
else if (has_dollar_at && quoted == 0 && ifs_chars && (word->flags & W_ASSIGNRHS))
|
||||
{
|
||||
tword = make_bare_word (istring);
|
||||
goto set_word_flags;
|
||||
}
|
||||
#endif
|
||||
else if (has_dollar_at && ifs_chars)
|
||||
list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
/* XXX might want to use *expanded_something == 0 instead of
|
||||
local_expanded here */
|
||||
if (local_expanded == 0 && has_quoted_ifs)
|
||||
#else
|
||||
tword = alloc_word_desc ();
|
||||
if (expanded_something && *expanded_something == 0 && has_quoted_ifs)
|
||||
#endif
|
||||
{
|
||||
tword = alloc_word_desc ();
|
||||
tword->word = remove_quoted_ifs (istring);
|
||||
}
|
||||
tword->word = remove_quoted_ifs (istring);
|
||||
else
|
||||
tword = make_bare_word (istring);
|
||||
tword->word = istring;
|
||||
if (had_quoted_null && QUOTED_NULL (istring))
|
||||
tword->flags |= W_HASQUOTEDNULL; /* XXX */
|
||||
if (tword->word != istring)
|
||||
free (istring);
|
||||
istring = 0; /* avoid later free() */
|
||||
set_word_flags:
|
||||
if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
|
||||
tword->flags |= W_QUOTED;
|
||||
@@ -9909,8 +9918,6 @@ set_word_flags:
|
||||
tword->flags |= W_NOBRACE;
|
||||
if (word->flags & W_NOEXPAND)
|
||||
tword->flags |= W_NOEXPAND;
|
||||
if (had_quoted_null && QUOTED_NULL (istring))
|
||||
tword->flags |= W_HASQUOTEDNULL; /* XXX */
|
||||
list = make_word_list (tword, (WORD_LIST *)NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,8 +627,12 @@ unary_test (op, arg)
|
||||
if (v == 0 && valid_array_reference (arg, 0))
|
||||
{
|
||||
char *t;
|
||||
t = array_value (arg, 0, 0, (int *)0, (arrayind_t *)0);
|
||||
return (t ? TRUE : FALSE);
|
||||
int rtype, ret;
|
||||
t = array_value (arg, 0, 0, &rtype, (arrayind_t *)0);
|
||||
ret = t ? TRUE : FALSE;
|
||||
if (rtype > 0) /* subscript is * or @ */
|
||||
free (t);
|
||||
return ret;
|
||||
}
|
||||
else if (v && invisible_p (v) == 0 && array_p (v))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user