commit bash-20170428 snapshot

This commit is contained in:
Chet Ramey
2017-05-01 15:46:46 -04:00
parent 787bb204f9
commit 2a39157723
14 changed files with 426 additions and 570 deletions
+51
View File
@@ -13716,3 +13716,54 @@ bashline.c
NEW_LINE is NULL. Report from Jaren Stangret <sirjaren@gmail.com>,
fix from Eduardo Bustamante <dualbus@gmail.com>
4/24
----
parse.y
- xparse_dolparen: if the current token (the last thing read_token
returned to yylex) is shell_eof_token, assume that it is the new
bison lookahead token and clear it. Fixes bug reported by
Werner Fink <werner@suse.de>
4/25
----
doc/{bash.1,bashref.texi}
- cmdhist: clarify that this option only has an effect if history is
enabled. Suggested by Matthew Braun <matthew@powerplug.com>
4/26
----
jobs.c
- wait_for: if a non-interactive shell with job control enabled (set -m)
detects that a foreground job died due to SIGINT, act as if the shell
also received the SIGINT. Prompted by an austin-group-l discussion
- waitchld: run SIGCHLD trap for each child exited even if job control
is not enabled when in Posix mode. Prompted by an austin-group-l
discussion
4/27
----
lib/readline/histfile.c
- read_history_range: if the history file is empty, free the history
filename before returning. Report and fix from Eduardo Bustamante
<dualbus@gmail.com>
lib/readline/bind.c
- rl_parse_and_bind: make sure there is something, even if it's a
quoted empty string, before the `:' in a key binding. Report from
Eduardo Bustamante <dualbus@gmail.com>
- rl_parse_and_bind: if the right side of a key binding starts with a
quote, make sure there's a matching close quote before treating it
as a macro definition
- rl_translate_keyseq: if a key sequence ends with \C- or \M- (or
\C-\M-) make sure we break out of the loop if moving to the character
to be translated is a NUL. Old code did this only in the \C-\M-
case. Report from Eduardo Bustamante <dualbus@gmail.com>
4/28
----
lib/glob/sm_loop.c
- GMATCH: implement a clever technique from glibc that avoids
backtracking past a `*' if we've already chosen to use it and need
matches beyond it. Look at https://research.swtch.com/glob for a
longer explanation. This results in a significant speedup for globs
with multiple instances of `*', especially with more than 4.
+9 -3
View File
@@ -5,12 +5,12 @@
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
.\" Last Change: Tue Apr 4 14:55:46 EDT 2017
.\" Last Change: Tue Apr 25 09:44:48 EDT 2017
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
.TH BASH 1 "2017 April 4" "GNU Bash 4.4"
.TH BASH 1 "2017 April 25" "GNU Bash 4.4"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
@@ -8768,7 +8768,7 @@ Options, if supplied, have the following meanings:
.B \-d
The first character of \fIdelim\fP is used to terminate each input line,
rather than newline.
If \fIdelim\fP is the empty string, \fBread\fP will terminate a line
If \fIdelim\fP is the empty string, \fBmapfile\fP will terminate a line
when it reads a NUL character.
.TP
.B \-n
@@ -9029,6 +9029,8 @@ Other \fIname\fP arguments are ignored.
.B \-d \fIdelim\fP
The first character of \fIdelim\fP is used to terminate the input line,
rather than newline.
If \fIdelim\fP is the empty string, \fBread\fP will terminate a line
when it reads a NUL character.
.TP
.B \-e
If the standard input
@@ -9691,6 +9693,10 @@ If set,
attempts to save all lines of a multiple-line
command in the same history entry. This allows
easy re-editing of multi-line commands.
This option is enabled by default, but only has an effect if command
history is enabled, as described above under
.SM
.BR HISTORY .
.TP 8
.B compat31
If set,
+5 -1
View File
@@ -4360,7 +4360,7 @@ Options, if supplied, have the following meanings:
@item -d
The first character of @var{delim} is used to terminate each input line,
rather than newline.
If @var{delim} is the empty string, @code{read} will terminate a line
If @var{delim} is the empty string, @code{mapfile} will terminate a line
when it reads a NUL character.
@item -n
Copy at most @var{count} lines. If @var{count} is 0, all lines are copied.
@@ -4487,6 +4487,8 @@ Other @var{name} arguments are ignored.
@item -d @var{delim}
The first character of @var{delim} is used to terminate the input line,
rather than newline.
If @var{delim} is the empty string, @code{read} will terminate a line
when it reads a NUL character.
@item -e
Readline (@pxref{Command Line Editing}) is used to obtain the line.
@@ -5135,6 +5137,8 @@ If set, Bash
attempts to save all lines of a multiple-line
command in the same history entry. This allows
easy re-editing of multi-line commands.
This option is enabled by default, but only has an effect if command
history is enabled (@pxref{Bash History Facilities}).
@item compat31
If set, Bash
+2 -2
View File
@@ -2,10 +2,10 @@
Copyright (C) 1988-2017 Free Software Foundation, Inc.
@end ignore
@set LASTCHANGE Tue Apr 4 14:56:04 EDT 2017
@set LASTCHANGE Tue Apr 25 09:45:02 EDT 2017
@set EDITION 4.4
@set VERSION 4.4
@set UPDATED 4 April 2017
@set UPDATED 25 April 2017
@set UPDATED-MONTH April 2017
+17 -3
View File
@@ -2963,8 +2963,21 @@ if (job == NO_JOB)
kill (getpid (), SIGINT);
}
}
else if (interactive_shell == 0 && IS_FOREGROUND (job) && check_window_size)
get_new_window_size (0, (int *)0, (int *)0);
else if (interactive_shell == 0 && subshell_environment == 0 && IS_FOREGROUND (job))
{
s = job_signal_status (job);
/* XXX - bash-5.0 */
/* If we are non-interactive, but job control is enabled, and the job
died due to SIGINT, pretend we got the SIGINT */
if (job_control && IS_JOBCONTROL (job) && WIFSIGNALED (s) && WTERMSIG (s) == SIGINT)
{
ADDINTERRUPT; /* For now */
}
if (check_window_size)
get_new_window_size (0, (int *)0, (int *)0);
}
/* Moved here from set_job_status_and_cleanup, which is in the SIGCHLD
signal handler path */
@@ -3669,7 +3682,8 @@ itrace("waitchld: waitpid returns %d block = %d children_exited = %d", pid, bloc
}
/* Call a SIGCHLD trap handler for each child that exits, if one is set. */
if (job_control && children_exited &&
/* XXX - bash-5.0 adds posixly_correct test */
if ((job_control || posixly_correct) && children_exited &&
(signal_is_trapped (SIGCHLD) || trap_list[SIGCHLD] == (char *)IMPOSSIBLE_TRAP_HANDLER) &&
trap_list[SIGCHLD] != (char *)IGNORE_SIG)
{
+52 -25
View File
@@ -1,4 +1,4 @@
/* Copyright (C) 1991-2011 Free Software Foundation, Inc.
/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -16,9 +16,15 @@
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
struct STRUCT
{
CHAR *pattern;
CHAR *string;
};
int FCT __P((CHAR *, CHAR *, int));
static int GMATCH __P((CHAR *, CHAR *, CHAR *, CHAR *, int));
static int GMATCH __P((CHAR *, CHAR *, CHAR *, CHAR *, struct STRUCT *, int));
static CHAR *PARSE_COLLSYM __P((CHAR *, INT *));
static CHAR *BRACKMATCH __P((CHAR *, U_CHAR, int));
static int EXTMATCH __P((INT, CHAR *, CHAR *, CHAR *, CHAR *, int));
@@ -39,15 +45,16 @@ FCT (pattern, string, flags)
se = string + STRLEN ((XCHAR *)string);
pe = pattern + STRLEN ((XCHAR *)pattern);
return (GMATCH (string, se, pattern, pe, flags));
return (GMATCH (string, se, pattern, pe, (struct STRUCT *)NULL, flags));
}
/* Match STRING against the filename pattern PATTERN, returning zero if
it matches, FNM_NOMATCH if not. */
static int
GMATCH (string, se, pattern, pe, flags)
GMATCH (string, se, pattern, pe, ends, flags)
CHAR *string, *se;
CHAR *pattern, *pe;
struct STRUCT *ends;
int flags;
{
CHAR *p, *n; /* pattern, string */
@@ -121,7 +128,16 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
return FNM_NOMATCH;
break;
case '*': /* Match zero or more characters */
case L('*'): /* Match zero or more characters */
/* See below for the reason for using this. It avoids backtracking
back to a previous `*'. Picked up from glibc. */
if (ends != NULL)
{
ends->pattern = p - 1;
ends->string = n;
return (0);
}
if ((flags & FNM_PERIOD) && sc == L('.') &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/'))))
/* `*' cannot match a `.' if it is the first character of the
@@ -144,17 +160,9 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
{
CHAR *newn;
#if 0
for (newn = n; newn < se; ++newn)
{
if (EXTMATCH (c, newn, se, p, pe, flags) == 0)
return (0);
}
#else
/* We can match 0 or 1 times. If we match, return success */
if (EXTMATCH (c, n, se, p, pe, flags) == 0)
return (0);
#endif
/* We didn't match the extended glob pattern, but
that's OK, since we can match 0 or 1 occurrences.
@@ -244,7 +252,7 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
{
while (n < se && *n != L('/'))
++n;
if (n < se && *n == L('/') && (GMATCH (n+1, se, p, pe, flags) == 0))
if (n < se && *n == L('/') && (GMATCH (n+1, se, p, pe, NULL, flags) == 0))
return 0;
return FNM_NOMATCH; /* XXX */
}
@@ -253,10 +261,13 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
{
U_CHAR c1;
const CHAR *endp;
struct STRUCT end;
end.pattern = NULL;
endp = MEMCHR (n, (flags & FNM_PATHNAME) ? L('/') : L('\0'), se - n);
if (endp == 0)
endp = se;
c1 = ((flags & FNM_NOESCAPE) == 0 && c == L('\\')) ? *p : c;
c1 = FOLD (c1);
for (--p; n < endp; ++n)
@@ -275,9 +286,24 @@ fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
continue;
/* Otherwise, we just recurse. */
if (GMATCH (n, se, p, pe, flags & ~FNM_PERIOD) == 0)
return (0);
if (GMATCH (n, se, p, pe, &end, flags & ~FNM_PERIOD) == 0)
{
if (end.pattern == NULL)
return (0);
break;
}
}
/* This is a clever idea from glibc, used to avoid backtracking
to a `*' that appears earlier in the pattern. We get away
without saving se and pe because they are always the same,
even in the recursive calls to gmatch */
if (end.pattern != NULL)
{
p = end.pattern;
n = end.string;
continue;
}
return FNM_NOMATCH;
}
@@ -753,7 +779,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
/* If we can get away with no matches, don't even bother. Just
call GMATCH on the rest of the pattern and return success if
it succeeds. */
if (xc == L('*') && (GMATCH (s, se, prest, pe, flags) == 0))
if (xc == L('*') && (GMATCH (s, se, prest, pe, NULL, flags) == 0))
return 0;
/* OK, we have to do this the hard way. First, we make sure one of
@@ -766,7 +792,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
{
/* Match this substring (S -> SREST) against this
subpattern (psub -> pnext - 1) */
m1 = GMATCH (s, srest, psub, pnext - 1, flags) == 0;
m1 = GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0;
/* OK, we matched a subpattern, so make sure the rest of the
string matches the rest of the pattern. Also handle
multiple matches of the pattern. */
@@ -774,8 +800,8 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
{
/* if srest > s, we are not at start of string */
xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
m2 = (GMATCH (srest, se, prest, pe, xflags) == 0) ||
(s != srest && GMATCH (srest, se, p - 1, pe, xflags) == 0);
m2 = (GMATCH (srest, se, prest, pe, NULL, xflags) == 0) ||
(s != srest && GMATCH (srest, se, p - 1, pe, NULL, xflags) == 0);
}
if (m1 && m2)
return (0);
@@ -790,7 +816,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
/* If we can get away with no matches, don't even bother. Just
call gmatch on the rest of the pattern and return success if
it succeeds. */
if (xc == L('?') && (GMATCH (s, se, prest, pe, flags) == 0))
if (xc == L('?') && (GMATCH (s, se, prest, pe, NULL, flags) == 0))
return 0;
/* OK, we have to do this the hard way. First, we see if one of
@@ -804,8 +830,8 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
{
/* if srest > s, we are not at start of string */
xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
if (GMATCH (s, srest, psub, pnext - 1, flags) == 0 &&
GMATCH (srest, se, prest, pe, xflags) == 0)
if (GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0 &&
GMATCH (srest, se, prest, pe, NULL, xflags) == 0)
return (0);
}
if (pnext == prest)
@@ -821,14 +847,14 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
{
pnext = PATSCAN (psub, pe, L('|'));
/* If one of the patterns matches, just bail immediately. */
if (m1 = (GMATCH (s, srest, psub, pnext - 1, flags) == 0))
if (m1 = (GMATCH (s, srest, psub, pnext - 1, NULL, flags) == 0))
break;
if (pnext == prest)
break;
}
/* if srest > s, we are not at start of string */
xflags = (srest > s) ? (flags & ~FNM_PERIOD) : flags;
if (m1 == 0 && GMATCH (srest, se, prest, pe, xflags) == 0)
if (m1 == 0 && GMATCH (srest, se, prest, pe, NULL, xflags) == 0)
return (0);
}
return (FNM_NOMATCH);
@@ -852,6 +878,7 @@ fprintf(stderr, "extmatch: flags = %d\n", flags);
#undef PATSCAN
#undef STRCOMPARE
#undef EXTMATCH
#undef STRUCT
#undef BRACKMATCH
#undef STRCHR
#undef STRCOLL
+3 -1
View File
@@ -1,7 +1,7 @@
/* strmatch.c -- ksh-like extended pattern matching for the shell and filename
globbing. */
/* Copyright (C) 1991-2011 Free Software Foundation, Inc.
/* Copyright (C) 1991-2017 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -254,6 +254,7 @@ is_cclass (c, name)
#define PATSCAN glob_patscan
#define STRCOMPARE strcompare
#define EXTMATCH extmatch
#define STRUCT smat_struct
#define STRCHR(S, C) strchr((S), (C))
#define MEMCHR(S, C, N) memchr((S), (C), (N))
#define STRCOLL(S1, S2) strcoll((S1), (S2))
@@ -389,6 +390,7 @@ is_wcclass (wc, name)
#define PATSCAN glob_patscan_wc
#define STRCOMPARE wscompare
#define EXTMATCH extmatch_wc
#define STRUCT wcsmat_struct
#define STRCHR(S, C) wcschr((S), (C))
#define MEMCHR(S, C, N) wmemchr((S), (C), (N))
#define STRCOLL(S1, S2) wcscoll((S1), (S2))
+13 -2
View File
@@ -452,8 +452,6 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
array[l++] = ESC; /* ESC is meta-prefix */
i += 5;
array[l++] = CTRL (_rl_to_upper (seq[i]));
if (seq[i] == '\0')
i--;
}
else if (c == 'M')
{
@@ -482,6 +480,8 @@ rl_translate_keyseq (const char *seq, char *array, int *len)
/* Special hack for C-?... */
array[l++] = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
}
if (seq[i] == '\0')
break;
continue;
}
@@ -1263,6 +1263,12 @@ rl_parse_and_bind (char *string)
/* Advance to the colon (:) or whitespace which separates the two objects. */
for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ );
if (i == 0)
{
_rl_init_file_error ("`%s': invalid key binding: missing key sequence", string);
return 1;
}
equivalency = (c == ':' && string[i + 1] == '=');
foundsep = c != 0;
@@ -1341,6 +1347,11 @@ remove_trailing:
i = _rl_skip_to_delim (string, i+1, *funname);
if (string[i])
i++;
else
{
_rl_init_file_error ("`%s': missing closing quote for macro", funname);
return 1;
}
}
/* Advance to the end of the string. */
+4 -1
View File
@@ -293,7 +293,10 @@ read_history_range (const char *filename, int from, int to)
}
if (file_size == 0)
return 0; /* don't waste time if we don't have to */
{
free (input);
return 0; /* don't waste time if we don't have to */
}
#ifdef HISTORY_USE_MMAP
/* We map read/write and private so we can change newlines to NULs without
+13 -2
View File
@@ -318,6 +318,9 @@ static WORD_DESC *word_desc_to_read;
static REDIRECTEE source;
static REDIRECTEE redir;
static FILE *yyoutstream;
static FILE *yyerrstream;
%}
%union {
@@ -1310,6 +1313,8 @@ debug_parser (i)
{
#if YYDEBUG != 0
yydebug = i;
yyoutstream = stdout;
yyerrstream = stderr;
#endif
}
#endif
@@ -2675,7 +2680,7 @@ yylex ()
if (bash_input.type == st_string)
rewind_input_string ();
}
parser_state &= ~PST_EOFTOKEN;
parser_state &= ~PST_EOFTOKEN; /* ??? */
return (current_token);
}
@@ -4267,7 +4272,7 @@ xparse_dolparen (base, string, indp, flags)
STRING_SAVER *saved_pushed_strings;
#endif
/*yydebug = 1;*/
/*debug_parser(1);*/
orig_ind = *indp;
ostring = string;
@@ -4287,8 +4292,14 @@ xparse_dolparen (base, string, indp, flags)
parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/
shell_eof_token = ')';
/* Should we save and restore the bison/yacc lookahead token (yychar) here?
Or only if it's not YYEMPTY? */
nc = parse_string (string, "command substitution", sflags, &ep);
if (current_token == shell_eof_token)
yyclearin; /* might want to clear lookahead token unconditionally */
shell_eof_token = orig_eof_token;
restore_parser_state (&ps);
reset_parser ();
+248 -528
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -5948,6 +5948,8 @@ command_substitute (string, quoted, flags)
/* Flags to pass to parse_and_execute() */
pflags = (interactive && sourcelevel == 0) ? SEVAL_RESETLINE : 0;
old_pid = last_made_pid;
/* Pipe the output of executing STRING into the current shell. */
if (pipe (fildes) < 0)
{
@@ -5955,7 +5957,6 @@ command_substitute (string, quoted, flags)
goto error_exit;
}
old_pid = last_made_pid;
#if defined (JOB_CONTROL)
old_pipeline_pgrp = pipeline_pgrp;
/* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/chet/bash/bash-current
BUILD_DIR=/usr/local/build/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+6
View File
@@ -44,6 +44,12 @@ bar')
# long-standing parse error in all versions up through bash-4.3
echo ${foo:-$(echo a{b,c})} >/dev/null
# parsing problem based on recursively calling bison parser through bash-4.4
for (( INDEX=0; INDEX<$((10-$(expr length $V_NAME))); INDEX++ ))
do
:
done
${THIS_SH} ./comsub1.sub
${THIS_SH} ./comsub2.sub
${THIS_SH} ./comsub3.sub