mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-10 13:40:55 +02:00
commit bash-20200422 snapshot
This commit is contained in:
@@ -8141,3 +8141,47 @@ lib/readline/isearch.c
|
||||
- _rl_isearch_dispatch: do translation for keys that map to
|
||||
rl_do_lowercase_version like we do when dispatching while reading a
|
||||
key sequence
|
||||
|
||||
4/23
|
||||
----
|
||||
lib/readline/isearch.c
|
||||
- _rl_isearch_dispatch: if bracketed paste mode is enabled and there are
|
||||
enough characters waiting in the terminal's input queue, try to read
|
||||
the bracketed paste prefix and jump straight to the opcode execution
|
||||
if we read it. Otherwise, just go on with the ESC. Inspired by report
|
||||
from <gentoo_eshoes@tutanota.com>
|
||||
|
||||
parse.y
|
||||
- parse_comsub: posix-mode shells don't allow a closing right paren to
|
||||
delimit a pending here-document -- it requires the newline
|
||||
|
||||
doc/bashref.texi
|
||||
- POSIX mode: updated posix mode description with the new here-document
|
||||
delimiter requirement
|
||||
|
||||
lib/readline/search.c
|
||||
- _rl_nsearch_dispatch: if bracketed paste mode is enabled, and we read
|
||||
an ESC, try to see if we have a bracketed paste op and insert the
|
||||
pasted next. If we don't, go on with the ESC
|
||||
- _rl_nsearch_dosearch: experimental code to highlight the search string
|
||||
when displaying the line found in the history. Only done when we are
|
||||
not searching for a pattern, since we don't have information on the
|
||||
end of the matching portion of the line. Experimental because it
|
||||
changes where we put point and mark if searching is successful
|
||||
|
||||
expr.c
|
||||
- expr_streval: if find_variable for the case where the string is not
|
||||
an array reference doesn't find anything, see if we can find
|
||||
something by using find_variable_last_nameref and use the value
|
||||
from there in the call to expr_streval, kind of using the expression
|
||||
recursion to complement the nameref recursion. Report from
|
||||
Daniel Molina <lluvia@autistici.org>
|
||||
|
||||
4/24
|
||||
----
|
||||
jobs.c
|
||||
- {start,stop}_pipeline: don't reset pipeline_pgrp to 0 if it's already
|
||||
the same as shell_pgrp, since we don't want to reset it in the middle
|
||||
of a shell started to run a command or process substitution (after
|
||||
forking a child to run one command, but before forking another, for
|
||||
instance). Reported by Rob Landley <rob@landley.net>
|
||||
|
||||
@@ -7786,6 +7786,13 @@ not have to appear as matched pairs.
|
||||
The parser does not recognize @code{time} as a reserved word if the next
|
||||
token begins with a @samp{-}.
|
||||
|
||||
@ignore
|
||||
@item
|
||||
When parsing @code{$()} command substitutions containing here-documents,
|
||||
the parser does not allow a here-document to be delimited by the closing
|
||||
right parenthesis. The newline after the here-document delimiter is required.
|
||||
@end ignore
|
||||
|
||||
@item
|
||||
The @samp{!} character does not introduce history expansion within a
|
||||
double-quoted string, even if the @code{histexpand} option is enabled.
|
||||
|
||||
@@ -454,7 +454,7 @@ cut_internal (which, list)
|
||||
return (EXECUTION_FAILURE);
|
||||
}
|
||||
|
||||
if (list == 0)
|
||||
if (list == 0 && which == 0)
|
||||
{
|
||||
builtin_error ("string argument required");
|
||||
return (EX_USAGE);
|
||||
@@ -505,9 +505,6 @@ cut_internal (which, list)
|
||||
op.npos = npos;
|
||||
op.poslist = poslist;
|
||||
|
||||
/* we can eventually implement cut as a builtin with a cutfile() function
|
||||
that opens cutstring as a filename (or `-' for stdin) and runs cutline
|
||||
on every line in the file. */
|
||||
if (which == 0)
|
||||
rval = cutline (v, cutstring, &op);
|
||||
|
||||
@@ -521,22 +518,6 @@ lcut_builtin (list)
|
||||
return (cut_internal (0, list));
|
||||
}
|
||||
|
||||
/* Called when builtin is enabled and loaded from the shared object. If this
|
||||
function returns 0, the load fails. */
|
||||
int
|
||||
lcut_builtin_load (name)
|
||||
char *name;
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Called when builtin is disabled. */
|
||||
void
|
||||
lcut_builtin_unload (name)
|
||||
char *name;
|
||||
{
|
||||
}
|
||||
|
||||
char *lcut_doc[] = {
|
||||
"Extract selected fields from a string.",
|
||||
"",
|
||||
|
||||
@@ -1168,6 +1168,8 @@ expr_streval (tok, e, lvalue)
|
||||
#else
|
||||
v = find_variable (tok);
|
||||
#endif
|
||||
if (v == 0 && e != ']')
|
||||
v = find_variable_last_nameref (tok, 0);
|
||||
|
||||
if ((v == 0 || invisible_p (v)) && unbound_vars_is_error)
|
||||
{
|
||||
|
||||
@@ -519,7 +519,12 @@ start_pipeline ()
|
||||
if (the_pipeline)
|
||||
{
|
||||
cleanup_the_pipeline ();
|
||||
pipeline_pgrp = 0;
|
||||
/* If job_control == 0, pipeline_pgrp will always be equal to shell_pgrp;
|
||||
if job_control != 0, pipeline_pgrp == shell_pgrp for command and
|
||||
process substitution, in which case we want it to be the same as
|
||||
shell_pgrp for the lifetime of this shell instance. */
|
||||
if (pipeline_pgrp != shell_pgrp)
|
||||
pipeline_pgrp = 0;
|
||||
#if defined (PGRP_PIPE)
|
||||
sh_closepipe (pgrp_pipe);
|
||||
#endif
|
||||
@@ -632,7 +637,8 @@ stop_pipeline (async, deferred)
|
||||
|
||||
the_pipeline = (PROCESS *)NULL;
|
||||
newjob->pgrp = pipeline_pgrp;
|
||||
pipeline_pgrp = 0;
|
||||
if (pipeline_pgrp != shell_pgrp)
|
||||
pipeline_pgrp = 0;
|
||||
|
||||
newjob->flags = 0;
|
||||
if (pipefail_opt)
|
||||
|
||||
@@ -355,6 +355,22 @@ _rl_isearch_dispatch (_rl_search_cxt *cxt, int c)
|
||||
|
||||
_rl_add_executing_keyseq (c);
|
||||
|
||||
/* XXX - experimental code to allow users to bracketed-paste into the search
|
||||
string even when ESC is one of the isearch-terminators. Not perfect yet. */
|
||||
if (_rl_enable_bracketed_paste && c == ESC && strchr (cxt->search_terminators, c) && (n = _rl_nchars_available ()) > (2*BRACK_PASTE_SLEN-1))
|
||||
{
|
||||
j = _rl_read_bracketed_paste_prefix (c);
|
||||
if (j == 1)
|
||||
{
|
||||
cxt->lastc = -7; /* bracketed paste, see below */
|
||||
goto opcode_dispatch;
|
||||
}
|
||||
else if (_rl_pushed_input_available ()) /* eat extra char we pushed back */
|
||||
c = cxt->lastc = rl_read_key ();
|
||||
else
|
||||
c = cxt->lastc; /* last ditch */
|
||||
}
|
||||
|
||||
/* If we are moving into a new keymap, modify cxt->keymap and go on.
|
||||
This can be a problem if c == ESC and we want to terminate the
|
||||
incremental search, so we check */
|
||||
@@ -531,6 +547,7 @@ add_character:
|
||||
|
||||
_rl_init_executing_keyseq ();
|
||||
|
||||
opcode_dispatch:
|
||||
/* Now dispatch on the character. `Opcodes' affect the search string or
|
||||
state. Other characters are added to the string. */
|
||||
switch (cxt->lastc)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/* kill.c -- kill ring management. */
|
||||
|
||||
/* Copyright (C) 1994-2019 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
|
||||
+41
-5
@@ -1,6 +1,6 @@
|
||||
/* search.c - code for non-incremental searching in emacs and vi modes. */
|
||||
|
||||
/* Copyright (C) 1992-2017 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1992-2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library (Readline), a library
|
||||
for reading lines of text with interactive input and history editing.
|
||||
@@ -159,7 +159,7 @@ noninc_search_from_pos (char *string, int pos, int dir, int flags, int *ncp)
|
||||
static int
|
||||
noninc_dosearch (char *string, int dir, int flags)
|
||||
{
|
||||
int oldpos, pos;
|
||||
int oldpos, pos, ind;
|
||||
HIST_ENTRY *entry;
|
||||
|
||||
if (string == 0 || *string == '\0' || noninc_history_pos < 0)
|
||||
@@ -168,7 +168,7 @@ noninc_dosearch (char *string, int dir, int flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir, flags, (int *)0);
|
||||
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir, flags, &ind);
|
||||
if (pos == -1)
|
||||
{
|
||||
/* Search failed, current history position unchanged. */
|
||||
@@ -192,8 +192,19 @@ noninc_dosearch (char *string, int dir, int flags)
|
||||
|
||||
make_history_line_current (entry);
|
||||
|
||||
rl_point = 0;
|
||||
rl_mark = rl_end;
|
||||
if (_rl_enable_bracketed_paste && ((flags & SF_PATTERN) == 0) && ind > 0 && ind < rl_end)
|
||||
{
|
||||
rl_point = ind;
|
||||
rl_mark = ind + strlen (string);
|
||||
if (rl_mark > rl_end)
|
||||
rl_mark = rl_end; /* can't happen? */
|
||||
rl_activate_mark ();
|
||||
}
|
||||
else
|
||||
{
|
||||
rl_point = 0;
|
||||
rl_mark = rl_end;
|
||||
}
|
||||
|
||||
rl_clear_message ();
|
||||
return 1;
|
||||
@@ -268,6 +279,8 @@ _rl_nsearch_abort (_rl_search_cxt *cxt)
|
||||
static int
|
||||
_rl_nsearch_dispatch (_rl_search_cxt *cxt, int c)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (c < 0)
|
||||
c = CTRL ('C');
|
||||
|
||||
@@ -301,6 +314,28 @@ _rl_nsearch_dispatch (_rl_search_cxt *cxt, int c)
|
||||
_rl_nsearch_abort (cxt);
|
||||
return -1;
|
||||
|
||||
case ESC:
|
||||
/* XXX - experimental code to allow users to bracketed-paste into the
|
||||
search string. Similar code is in isearch.c:_rl_isearch_dispatch().
|
||||
The difference here is that the bracketed paste sometimes doesn't
|
||||
paste everything, so checking for the prefix and the suffix in the
|
||||
input queue doesn't work well. We just have to check to see if the
|
||||
number of chars in the input queue is enough for the bracketed paste
|
||||
prefix and hope for the best. */
|
||||
if (_rl_enable_bracketed_paste && ((n = _rl_nchars_available ()) >= (BRACK_PASTE_SLEN-1)))
|
||||
{
|
||||
if (_rl_read_bracketed_paste_prefix (c) == 1)
|
||||
rl_bracketed_paste_begin (1, c);
|
||||
else
|
||||
{
|
||||
c = rl_read_key (); /* get the ESC that got pushed back */
|
||||
_rl_insert_char (1, c);
|
||||
}
|
||||
}
|
||||
else
|
||||
_rl_insert_char (1, c);
|
||||
break;
|
||||
|
||||
default:
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
@@ -312,6 +347,7 @@ _rl_nsearch_dispatch (_rl_search_cxt *cxt, int c)
|
||||
}
|
||||
|
||||
(*rl_redisplay_function) ();
|
||||
rl_deactivate_mark ();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -3987,8 +3987,9 @@ eof_error:
|
||||
if (ch == '\n' && SHOULD_PROMPT ())
|
||||
prompt_again ();
|
||||
|
||||
/* XXX -- possibly allow here doc to be delimited by ending right
|
||||
paren. */
|
||||
/* XXX -- we currently allow here doc to be delimited by ending right
|
||||
paren in default mode and posix mode. To change posix mode, change
|
||||
the #if 1 to #if 0 below */
|
||||
if ((tflags & LEX_INHEREDOC) && ch == close && count == 1)
|
||||
{
|
||||
int tind;
|
||||
@@ -3996,7 +3997,14 @@ eof_error:
|
||||
tind = lex_firstind;
|
||||
while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t')
|
||||
tind++;
|
||||
if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen))
|
||||
#if 1
|
||||
if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen))
|
||||
#else
|
||||
/* Posix-mode shells require the newline after the here-document
|
||||
delimiter. */
|
||||
if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen) &&
|
||||
posixly_correct == 0)
|
||||
#endif
|
||||
{
|
||||
tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC|LEX_QUOTEDDOC);
|
||||
/*itrace("parse_comsub:%d: found here doc end `%*s'", line_number, hdlen, ret + tind);*/
|
||||
|
||||
@@ -3,6 +3,7 @@ abmnopyz
|
||||
ab
|
||||
|
||||
|
||||
abcd
|
||||
abcd
|
||||
sh_352.26ax
|
||||
sh_352.26ay
|
||||
@@ -47,11 +48,14 @@ after 5
|
||||
after 6
|
||||
x
|
||||
x
|
||||
x
|
||||
quoted )
|
||||
comment
|
||||
here-doc with )
|
||||
here-doc with \()
|
||||
here-doc terminated with a parenthesis
|
||||
' # or a single back- or doublequote
|
||||
line terminated with a backslash
|
||||
./comsub-posix1.sub: command substitution: line 2: syntax error near unexpected token `)'
|
||||
./comsub-posix1.sub: command substitution: line 2: ` if x; then echo foo )'
|
||||
after
|
||||
|
||||
@@ -27,6 +27,7 @@ echo $(
|
||||
)
|
||||
echo $()
|
||||
echo ab$()cd
|
||||
echo ab$( )cd
|
||||
|
||||
echo $(case a in (a) echo sh_352.26ax; esac )
|
||||
echo $(case a in (a) echo sh_352.26ay; esac)
|
||||
@@ -180,6 +181,10 @@ echo $(
|
||||
case x in x) echo x;; esac
|
||||
)
|
||||
|
||||
echo $(
|
||||
case x in x) echo x;; esac # followed by a comment
|
||||
)
|
||||
|
||||
echo $(
|
||||
case x in (x) echo x;; esac
|
||||
)
|
||||
@@ -198,6 +203,12 @@ cat <<\eof
|
||||
eof
|
||||
)
|
||||
|
||||
echo $(
|
||||
cat <<\eof
|
||||
here-doc with \()
|
||||
eof
|
||||
)
|
||||
|
||||
echo $(
|
||||
cat <<\)
|
||||
here-doc terminated with a parenthesis
|
||||
@@ -210,6 +221,10 @@ cat <<\eof
|
||||
eof
|
||||
)
|
||||
|
||||
echo $(
|
||||
echo line terminated with a backslash # \
|
||||
)
|
||||
|
||||
${THIS_SH} ./comsub-posix1.sub
|
||||
|
||||
${THIS_SH} ./comsub-posix2.sub
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
: ${THIS_SH:=./bash}
|
||||
set -o posix
|
||||
|
||||
# tests from Sven Mascheck that check whether a here-doc in a command
|
||||
# substitution can be terminated by EOF (the closing paren)
|
||||
#
|
||||
# currently unused
|
||||
|
||||
# Example D.3 # should fail with unterminated here-doc
|
||||
${THIS_SH} -o posix -c 'echo $(
|
||||
cat <<\eof
|
||||
D.3: here-doc with )
|
||||
eof)'
|
||||
|
||||
# Example D.4
|
||||
# the first EOF has a trailing blank
|
||||
# the third EOF is the correct one
|
||||
echo $(cat <<'EOF'
|
||||
D.4 error-prone use of here-doc terminator
|
||||
EOF
|
||||
EOF)
|
||||
EOF
|
||||
)
|
||||
echo after here-document
|
||||
Reference in New Issue
Block a user