readline fix for do-lowercase-version; fix for reading here-documents from aliases

This commit is contained in:
Chet Ramey
2023-12-05 11:54:24 -05:00
parent d5ab50bc02
commit ba57a3e752
15 changed files with 171 additions and 12 deletions
+32
View File
@@ -8109,3 +8109,35 @@ builtins/set.def
doc/bashref.texi
- update posix mode section with change to unset for interp 1009
12/1
----
lib/readline/readline.c
- _rl_subseq_result: add check before _rl_do_lowercase_version that
_rl_to_lower actually results in a different key sequence
Report and patch from Grisha Levit <grishalevit@gmail.com>
lib/readline/isearch.c
- _rl_isearch_dispatch: if the function bound to a key and the function
bound to the result of _rl_to_lower for that key are both
rl_do_lowercase_version, just insert the key into the search string
12/5
----
parse.y,parser.h
- heredoc_string: new variable to indicate whether or not we're reading
a here-document from an alias (a pushed string). Set in
gather_here_documents individually for each call to
make_here_document.
parse.y
- read_a_line: if heredoc_string is non-zero, use shell_getc instead
of yy_getc to get the right alias processing
- shell_getc: if heredoc_string is non-zero, don't add a space to the
end of the alias -- it can mess up the here-document delimiter if
the next character is a newline
Report and sample patch from gldrk <me@rarity.fan>
parse.y,make_cmd.c
- read_a_line,make_here_document: if we're using shell_getc to read
the body of a here-document, let it manage line_number
+1
View File
@@ -1246,6 +1246,7 @@ tests/heredoc6.sub f
tests/heredoc7.sub f
tests/heredoc8.sub f
tests/heredoc9.sub f
tests/heredoc10.sub f
tests/herestr.tests f
tests/herestr.right f
tests/herestr1.sub f
+5 -1
View File
@@ -430,7 +430,11 @@ add_character:
{
f = cxt->keymap[c].function;
if (f == rl_do_lowercase_version)
f = cxt->keymap[_rl_to_lower (c)].function;
{
f = cxt->keymap[_rl_to_lower (c)].function;
if (f == rl_do_lowercase_version)
f = rl_insert;
}
}
if (f == rl_reverse_search_history)
+5 -1
View File
@@ -1124,7 +1124,11 @@ _rl_subseq_result (int r, Keymap map, int key, int got_subseq)
type = m[ANYOTHERKEY].type;
func = m[ANYOTHERKEY].function;
if (type == ISFUNC && func == rl_do_lowercase_version)
r = _rl_dispatch (_rl_to_lower ((unsigned char)key), map);
{
int newkey = _rl_to_lower ((unsigned char)key);
/* check that there is actually a lowercase version to avoid infinite recursion */
r = (newkey != key) ? _rl_dispatch (newkey, map) : 1;
}
else if (type == ISFUNC)
{
/* If we shadowed a function, whatever it is, we somehow need a
+5 -1
View File
@@ -573,7 +573,11 @@ make_here_document (REDIRECT *temp, int lineno)
here_doc_first_line = 0;
line = full_line;
line_number++;
/* if read_secondary_line uses shell_getc, that handles incrementing
line_number where necessary. */
if (heredoc_string == 0)
line_number++;
/* If set -v is in effect, echo the line read. read_secondary_line/
read_a_line leaves the newline at the end, so don't print another. */
+24 -6
View File
@@ -295,6 +295,9 @@ int parser_state;
static REDIRECT *redir_stack[HEREDOC_MAX];
int need_here_doc;
/* Are we reading a here-document from a string? (alias) */
int heredoc_string;
/* Where shell input comes from. History expansion is performed on each
line when the shell is interactive. */
static char *shell_input_line = (char *)NULL;
@@ -2143,7 +2146,8 @@ read_a_line (int remove_quoted_newline)
/* Allow immediate exit if interrupted during input. */
QUIT;
c = yy_getc ();
/* If we're reading the here-document from an alias, use shell_getc */
c = heredoc_string ? shell_getc (0) : yy_getc ();
/* Ignore null bytes in input. */
if (c == 0)
@@ -2155,7 +2159,13 @@ read_a_line (int remove_quoted_newline)
if (interactive && bash_input.type == st_stream)
clearerr (stdin);
if (indx == 0)
return ((char *)NULL);
{
/* if we use shell_getc, that increments line_number on eof */
if (heredoc_string)
line_number--;
return ((char *)NULL);
}
c = '\n';
}
@@ -2177,10 +2187,12 @@ read_a_line (int remove_quoted_newline)
else if (c == '\\' && remove_quoted_newline)
{
QUIT;
peekc = yy_getc ();
/* If we're reading the here-document from an alias, use shell_getc */
peekc = heredoc_string ? shell_getc (0) : yy_getc ();
if (peekc == '\n')
{
line_number++;
if (heredoc_string == 0)
line_number++;
continue; /* Make the unquoted \<newline> pair disappear. */
}
else if (peekc == EOF)
@@ -2200,7 +2212,11 @@ read_a_line (int remove_quoted_newline)
}
else
{
yy_ungetc (peekc);
if (heredoc_string)
shell_ungetc (peekc);
else
yy_ungetc (peekc);
pass_next = 1;
line_buffer[indx++] = c; /* Preserve the backslash. */
}
@@ -2691,12 +2707,13 @@ next_alias_char:
return the space that will delimit the token and postpone the pop_string.
This set of conditions duplicates what used to be in mk_alexpansion ()
below, with the addition that we don't add a space if we're currently
reading a quoted string or in a shell comment. */
reading a quoted string or in a shell comment or here-document. */
#ifndef OLD_ALIAS_HACK
if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE &&
pushed_string_list->flags != PSH_DPAREN &&
(parser_state & PST_COMMENT) == 0 &&
(parser_state & PST_ENDALIAS) == 0 && /* only once */
heredoc_string == 0 &&
shell_input_line_index > 0 &&
shellblank (shell_input_line[shell_input_line_index-1]) == 0 &&
shell_input_line[shell_input_line_index-1] != '\n' &&
@@ -3027,6 +3044,7 @@ gather_here_documents (void)
while (need_here_doc > 0)
{
parser_state |= PST_HEREDOC;
heredoc_string = expanding_alias () && (shell_input_line_index < shell_input_line_len);
make_here_document (redir_stack[r++], line_number);
parser_state &= ~PST_HEREDOC;
need_here_doc--;
+1
View File
@@ -103,6 +103,7 @@ extern int shell_eof_token;
extern int current_token;
extern int parser_state;
extern int need_here_doc;
extern int heredoc_string;
extern int ignoreeof;
extern int eof_encountered;
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -9,7 +9,7 @@ msgstr ""
"Project-Id-Version: bash 5.2-rc1\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-01-11 14:50-0500\n"
"PO-Revision-Date: 2023-01-12 14:27-0300\n"
"PO-Revision-Date: 2023-12-04 14:27-0300\n"
"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
"Language-Team: Brazilian Portuguese <ldpbr-translation@lists.sourceforge.net>\n"
"Language: pt_BR\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
"X-Generator: Gtranslator 42.0\n"
"X-Generator: Gtranslator 45.2\n"
"X-Bugs: Report translation errors to the Language-Team address.\n"
#: arrayfunc.c:66
+7 -1
View File
@@ -153,8 +153,14 @@ HERE
echo 3 4;
done
}
hello
world
hello
world
here-document
here-document
comsub here-string
./heredoc.tests: line 181: warning: here-document at line 178 delimited by end-of-file (wanted `')
./heredoc.tests: line 184: warning: here-document at line 181 delimited by end-of-file (wanted `')
hi
there
''
+3
View File
@@ -168,6 +168,9 @@ ${THIS_SH} ./heredoc8.sub
# various tests for printing here-documents in function bodies
${THIS_SH} ./heredoc9.sub
# test various combinations of here-documents and aliases
${THIS_SH} ./heredoc10.sub
echo $(
cat <<< "comsub here-string"
)
+45
View File
@@ -0,0 +1,45 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# test various forms of reading here-documents from an alias
shopt -s expand_aliases
# single alias definition contains entire here-document
alias 'foo=cat <<EOF
hello
world
EOF'
foo
# here-document body continues after alias definition
alias 'foo=cat <<EOF
hello'
foo
world
EOF
# here-document delimiter in one alias, body in another
shopt -s expand_aliases
alias c='cat <<\END' d='c
here-document
END'
d
# make sure delimiter is recognized whether the alias ends with a newline or not
shopt -s expand_aliases
alias c='cat <<\END' d='c
here-document
END
'
d
+5
View File
@@ -38,6 +38,9 @@ abcde
30
40
50
declare -x var="60"
outside
assignment
|0|10|
10
|0|10|
@@ -159,6 +162,8 @@ inside func: var=two
outside 2.1: var=global
inside func1: var=value
outside 3.0: var=value
inside func1: var=func
outside 3.5: var=outside
inside func2: var=global
outside 4.0: var=outside
foo: hello world
+23
View File
@@ -39,3 +39,26 @@ var=40 func
echo expect 50
var=50 command printenv var
# this behaves the same in bash and posix mode
export -n var # make sure it's not exported
echo expect 60
var=60 export var
declare -p var
# this behaves differently in bash and posix mode: `.' is a special builtin
unset -v var
var=outside
echo 'var=assignment' >$TMPFILE
echo expect outside
var=temp . $TMPFILE
echo $var
set -o posix
echo expect assignment
var=temp . $TMPFILE
echo $var
rm -f $TMPFILE
unset -v var
+13
View File
@@ -134,6 +134,19 @@ echo -n 'outside 3.0: ' ; echo "var=${var-<unset>}"
unset -v var
unset -f func1
# operations inside a function on temporary variables do not propagate
func1()
{
export var
echo -n 'inside func1: ' ; echo "var=${var-<unset>}"
}
var=outside
var=func func1
echo -n 'outside 3.5: ' ; echo "var=${var-<unset>}"
unset -v var
unset -f func1
func2()
{
local var=local