mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-10 05:30:49 +02:00
fix to preserve blank lines when reading multiline entries from a history file; fix for completion with quoted command delimiters; updated translations
This commit is contained in:
@@ -11124,3 +11124,21 @@ doc/bash.1,doc/bashref.texi
|
||||
builtins/history.def
|
||||
- add history -d start-end to the long doc
|
||||
From a report from Duncan Roe <duncan_roe@optusnet.com.au>
|
||||
|
||||
4/9
|
||||
---
|
||||
lib/readline/histfile.c
|
||||
- read_history_range: changes to not skip blank lines if we are
|
||||
reading a history file with multiline history entries.
|
||||
From a report by Jens Schmidt <farblos@vodafonemail.de>
|
||||
|
||||
4/11
|
||||
----
|
||||
bashline.c
|
||||
- attempt_shell_completion: move the check for char_is_quoted from
|
||||
check_redir to the caller, set in_command_position to 0 if the
|
||||
command separator is quoted
|
||||
From https://savannah.gnu.org/support/?111224 david@mandelberg.org
|
||||
- check_extglob: break check for extended glob out into separate
|
||||
function, call from attempted_shell_completion, set in_command_position
|
||||
to -1 if it returns 1, as with the old call to check_redir
|
||||
|
||||
@@ -1294,6 +1294,7 @@ tests/history5.sub f
|
||||
tests/history6.sub f
|
||||
tests/history7.sub f
|
||||
tests/history8.sub f
|
||||
tests/history9.sub f
|
||||
tests/ifs.tests f
|
||||
tests/ifs.right f
|
||||
tests/ifs1.sub f
|
||||
|
||||
+23
-19
@@ -1422,6 +1422,22 @@ bash_spell_correct_shellword (int count, int key)
|
||||
#define COMMAND_SEPARATORS_PLUS_WS ";|&{(` \t"
|
||||
/* )} */
|
||||
|
||||
static inline int
|
||||
check_extglob (int ti)
|
||||
{
|
||||
#if defined (EXTENDED_GLOB)
|
||||
int this_char, prev_char;
|
||||
|
||||
this_char = rl_line_buffer[ti];
|
||||
prev_char = (ti > 0) ? rl_line_buffer[ti - 1] : 0;
|
||||
|
||||
if (extended_glob && ti > 0 && this_char == '(' && /*)*/
|
||||
member (prev_char, "?*+@!") && char_is_quoted (rl_line_buffer, ti - 1) == 0)
|
||||
return (1);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* check for redirections and other character combinations that are not
|
||||
command separators */
|
||||
static inline int
|
||||
@@ -1440,27 +1456,11 @@ check_redir (int ti)
|
||||
return (1);
|
||||
else if (this_char == '{' && prev_char == '$' && FUNSUB_CHAR (next_char) == 0) /*}*/
|
||||
return (1);
|
||||
#if 0 /* Not yet */
|
||||
else if (this_char == '(' && prev_char == '$') /*)*/
|
||||
return (1);
|
||||
else if (this_char == '(' && prev_char == '<') /*)*/
|
||||
return (1);
|
||||
#if defined (EXTENDED_GLOB)
|
||||
else if (extended_glob && this_char == '(' && prev_char == '!') /*)*/
|
||||
return (1);
|
||||
#endif
|
||||
#endif
|
||||
else if (char_is_quoted (rl_line_buffer, ti))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined (PROGRAMMABLE_COMPLETION)
|
||||
/*
|
||||
* XXX - because of the <= start test, and setting os = s+1, this can
|
||||
* potentially return os > start. This is probably not what we want to
|
||||
* happen, but fix later after 2.05a-release.
|
||||
*/
|
||||
static int
|
||||
find_cmd_start (int start)
|
||||
{
|
||||
@@ -1638,9 +1638,13 @@ attempt_shell_completion (const char *text, int start, int end)
|
||||
}
|
||||
else if (member (rl_line_buffer[ti], command_separator_chars))
|
||||
{
|
||||
in_command_position++;
|
||||
if (char_is_quoted (rl_line_buffer, ti) == 0)
|
||||
in_command_position++;
|
||||
|
||||
if (check_redir (ti) == 1)
|
||||
if (in_command_position && rl_line_buffer[ti] == '(' && check_extglob (ti) == 1) /*)*/
|
||||
in_command_position = -1;
|
||||
|
||||
if (in_command_position && check_redir (ti) == 1)
|
||||
in_command_position = -1; /* sentinel that we're not the first word on the line */
|
||||
}
|
||||
else
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
# The first cut of this was by Bill Trost, trost@reed.bitnet.
|
||||
# The second cut came from Chet Ramey, chet@ins.CWRU.Edu
|
||||
# The third cut came from Mark Kennedy, mtk@ny.ubs.com. 1998/08/25
|
||||
# The third cut came from Mark Kennedy, now mtk@acm.org. 1998/08/25
|
||||
|
||||
unset _AUTOLOADS
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
# The first cut of this was by Bill Trost, trost@reed.bitnet.
|
||||
# The second cut came from Chet Ramey, chet@ins.CWRU.Edu
|
||||
# The third cut came from Mark Kennedy, mtk@ny.ubs.com. 1998/08/25
|
||||
# The third cut came from Mark Kennedy, now mtk@acm.org. 1998/08/25
|
||||
# The fourth cut came from Matthew Persico, matthew.persico@gmail.com 2017/August
|
||||
|
||||
autoload_calc_shimsize ()
|
||||
|
||||
@@ -215,6 +215,20 @@ static sh_float_t xjn(sh_float_t d1, sh_float_t d2) { int x = d1; return (jn (x,
|
||||
static sh_float_t xyn(sh_float_t d1, sh_float_t d2) { int x = d1; return (yn (x, d2)); }
|
||||
static sh_float_t xldexp(sh_float_t d1, sh_float_t d2) { int x = d2; return (ldexp (d1, x)); }
|
||||
|
||||
/* Some additional math functions that aren't in libm */
|
||||
static sh_float_t xcot(sh_float_t d) { return (1.0 / tan(d)); }
|
||||
static sh_float_t xcoth(sh_float_t d) { return (cosh(d) / sinh(d)); }
|
||||
|
||||
static sh_float_t xroundp(sh_float_t d1, sh_float_t d2)
|
||||
{
|
||||
sh_float_t m, r;
|
||||
int prec = d2;
|
||||
|
||||
m = pow(10.0, prec);
|
||||
r = round(d1 * m) / m;
|
||||
return r;
|
||||
}
|
||||
|
||||
typedef int imathfunc1(sh_float_t);
|
||||
typedef int imathfunc2(sh_float_t, sh_float_t);
|
||||
typedef sh_float_t mathfunc1(sh_float_t);
|
||||
@@ -250,6 +264,8 @@ FLTEXPR_MATHFUN mathfuncs[] =
|
||||
{ "ceil", 1, { .func1 = ceil } },
|
||||
{ "cos", 1, { .func1 = cos } },
|
||||
{ "cosh", 1, { .func1 = cosh } },
|
||||
{ "cot", 1, { .func1 = xcot } },
|
||||
{ "coth", 1, { .func1 = xcoth } },
|
||||
{ "erf", 1, { .func1 = erf } },
|
||||
{ "erfc", 1, { .func1 = erfc } },
|
||||
{ "exp", 1, { .func1 = exp } },
|
||||
@@ -288,6 +304,7 @@ FLTEXPR_MATHFUN mathfuncs[] =
|
||||
{ "nextafter",2, { .func2 = nextafter } },
|
||||
{ "pow", 2, { .func2 = pow } },
|
||||
{ "remainder",2, { .func2 = remainder } },
|
||||
{ "roundp", 2, { .func2 = xroundp } },
|
||||
{ "ldexp", 2, { .func2 = xldexp } },
|
||||
{ "jn", 2, { .func2 = xjn } },
|
||||
{ "scalbn", 2, { .func2 = xscalbn } },
|
||||
|
||||
+16
-1
@@ -267,6 +267,7 @@ read_history_range (const char *filename, int from, int to)
|
||||
register char *line_start, *line_end, *p;
|
||||
char *input, *buffer, *bufend, *last_ts;
|
||||
int file, current_line, chars_read, has_timestamps, reset_comment_char;
|
||||
int skipblanks, default_skipblanks;
|
||||
struct stat finfo;
|
||||
size_t file_size;
|
||||
#if defined (EFBIG)
|
||||
@@ -380,6 +381,9 @@ read_history_range (const char *filename, int from, int to)
|
||||
has_timestamps = HIST_TIMESTAMP_START (buffer);
|
||||
history_multiline_entries += has_timestamps && history_write_timestamps;
|
||||
|
||||
/* default is to skip blank lines unless history entries are multiline */
|
||||
default_skipblanks = history_multiline_entries == 0;
|
||||
|
||||
/* Skip lines until we are at FROM. */
|
||||
if (has_timestamps)
|
||||
last_ts = buffer;
|
||||
@@ -405,6 +409,8 @@ read_history_range (const char *filename, int from, int to)
|
||||
}
|
||||
}
|
||||
|
||||
skipblanks = default_skipblanks;
|
||||
|
||||
/* If there are lines left to gobble, then gobble them now. */
|
||||
for (line_end = line_start; line_end < bufend; line_end++)
|
||||
if (*line_end == '\n')
|
||||
@@ -415,10 +421,16 @@ read_history_range (const char *filename, int from, int to)
|
||||
else
|
||||
*line_end = '\0';
|
||||
|
||||
if (*line_start)
|
||||
if (*line_start || skipblanks == 0)
|
||||
{
|
||||
if (HIST_TIMESTAMP_START(line_start) == 0)
|
||||
{
|
||||
/* If we have multiline entries (default_skipblanks == 0), we
|
||||
don't want to skip blanks here, since we turned that on at
|
||||
the last timestamp line. Consider doing this even if
|
||||
default_skipblanks == 1 in order not to lose blank lines in
|
||||
commands. */
|
||||
skipblanks = default_skipblanks;
|
||||
if (last_ts == NULL && history_length > 0 && history_multiline_entries)
|
||||
_hs_append_history_line (history_length - 1, line_start);
|
||||
else
|
||||
@@ -433,6 +445,9 @@ read_history_range (const char *filename, int from, int to)
|
||||
{
|
||||
last_ts = line_start;
|
||||
current_line--;
|
||||
/* Even if we're not skipping blank lines by default, we want
|
||||
to skip leading blank lines after a timestamp. */
|
||||
skipblanks = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -372,3 +372,25 @@ d
|
||||
5 history
|
||||
./history8.sub: line 15: history: 72: history position out of range
|
||||
./history8.sub: line 16: history: -72: history position out of range
|
||||
1 echo below zero
|
||||
2 cat <<EOF
|
||||
|
||||
|
||||
|
||||
a
|
||||
|
||||
b
|
||||
|
||||
c
|
||||
set -o vi
|
||||
a
|
||||
bbb
|
||||
|
||||
|
||||
exit
|
||||
EOF
|
||||
3 echo one # leading blank lines get removed
|
||||
4 echo two # blank lines after a non-blank are preserved
|
||||
|
||||
|
||||
5 echo three
|
||||
|
||||
@@ -134,3 +134,4 @@ ${THIS_SH} ./history5.sub
|
||||
${THIS_SH} ./history6.sub
|
||||
${THIS_SH} ./history7.sub
|
||||
${THIS_SH} ./history8.sub
|
||||
${THIS_SH} ./history9.sub
|
||||
|
||||
@@ -14,3 +14,5 @@ history
|
||||
|
||||
history -d 72
|
||||
history -d -72
|
||||
|
||||
unset HISTFILE
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# 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/>.
|
||||
#
|
||||
: ${TMPDIR:=/tmp}
|
||||
HFNAME=$TMPDIR/histfile-$$
|
||||
trap 'rm -f "$HFNAME"' 0 1 2 3 6 15
|
||||
|
||||
cat <<EOFILE >$HFNAME
|
||||
#1
|
||||
echo below zero
|
||||
#12302430
|
||||
cat <<EOF
|
||||
|
||||
|
||||
|
||||
a
|
||||
|
||||
b
|
||||
|
||||
c
|
||||
set -o vi
|
||||
a
|
||||
bbb
|
||||
|
||||
|
||||
exit
|
||||
EOF
|
||||
#2
|
||||
|
||||
|
||||
echo one # leading blank lines get removed
|
||||
#2811
|
||||
echo two # blank lines after a non-blank are preserved
|
||||
|
||||
|
||||
#2814
|
||||
echo three
|
||||
EOFILE
|
||||
shopt -s cmdhist
|
||||
HISTTIMEFORMAT=
|
||||
HISTFILE=$HFNAME
|
||||
|
||||
history -c
|
||||
history -r
|
||||
history
|
||||
|
||||
unset HISTFILE
|
||||
Reference in New Issue
Block a user