takes a length parameter; otherwise equivalent to rl_function_of_keyseq.
lib/readline/readline.h
- - rl_function_of_keyseq_len: add extern declration for new function
+ - rl_function_of_keyseq_len: add extern declaration for new function
lib/readline/doc/rltech.texi
- rl_function_of_keyseq_len: document new function interface
function) without enabling debugging mode and not having initialized
the variable previously (using a simple semaphore), create the
variables
+
+ 6/25
+ ----
+configure.ac
+ - opt_bash_malloc: bash malloc no longer disabled for systems that
+ require eight-bit alignment; the bash malloc has had this for a
+ long time
+
+ 7/4
+ ---
+bashline.c
+ - pre_process_line: if command-oriented history is enabled, and the
+ line being expanded is the second or later in a multi-line command,
+ and we know the command is being saved as the current history entry,
+ decrease history_length before calling history_expand so references
+ like !! refer to the previous history entry as usual
+
+lib/readline/histexpand.c
+ - history_quoting_state: new variable, can be set by calling
+ application before calling history_expand to note that the string
+ being expanded is part of a quoted string. Can be set to a single
+ quote, a double quote, or 0 (no quoting)
+ - history_expand: look at history_quoting_state and honor the
+ single-quote setting by not expanding any initial portion of the
+ line before the closing single quote. This allows history expansions
+ to be performed on a line containing a closing single quote if they
+ appear after the single quote
+
+lib/readline/history.h
+ - history_quoting_state: extern declaration
+
+bashhist.c
+ - bash_history_inhibit_expansion: if history_quoting_state indicates
+ that this string is single-quoted, skip over the single-quoted
+ portion and determine whether or not the portion after the
+ quoted string needs to be inhibited from history expansion
+
+parse.y
+ - shell_getc: set history_quoting_state based on the contents of the
+ current delimiter before calling pre_process_line
+
+ 7/6
+ ---
+lib/readline/doc/hsuser.texi
+ - describe the default behavior of backslash and single and double
+ quotes
+
+lib/readline/doc/hstech.texi
+ - history_quoting_state: describe effect of setting this variable
+ - history_quotes_inihibit_expansion: expand the description to include
+ the default quoting behavior that setting this variable enables
tests/histexp3.sub f
tests/histexp4.sub f
tests/histexp5.sub f
+tests/histexp6.sub f
tests/histexp.right f
tests/history.tests f
tests/history.right f
char *string;
int i;
{
- int t;
+ int t, si;
char hx[2];
hx[0] = history_expansion_char;
return (1);
#endif
+ si = 0;
+ /* If we're supposed to be in single-quoted string, skip over the
+ single-quoted part and then look at what's left. */
+ if (history_quoting_state == '\'')
+ {
+ si = skip_to_delim (string, 0, "'", SD_NOJMP|SD_HISTEXP);
+ if (string[si] == 0 || si >= i)
+ return (1);
+ si++;
+ }
+
/* Make sure the history expansion should not be skipped by quoting or
command/process substitution. */
- else if ((t = skip_to_histexp (string, 0, hx, SD_NOJMP|SD_HISTEXP)) > 0)
+ if ((t = skip_to_histexp (string, si, hx, SD_NOJMP|SD_HISTEXP)) > 0)
{
/* Skip instances of history expansion appearing on the line before
this one. */
add that line to the history if ADDIT is non-zero. */
if (!history_expansion_inhibited && history_expansion && history_expansion_p (line))
{
+ /* If we are expanding the second or later line of a multi-line
+ command, decrease history_length so references to history expansions
+ in these lines refer to the previous history entry and not the
+ current command. */
+ if (history_length > 0 && command_oriented_history && current_command_first_line_saved && current_command_line_count > 1)
+ history_length--;
expanded = history_expand (line, &history_value);
+ if (history_length >= 0 && command_oriented_history && current_command_first_line_saved && current_command_line_count > 1)
+ history_length++;
if (expanded)
{
#! /bin/sh
-# From configure.ac for Bash 5.0, version 4.092.
+# From configure.ac for Bash 5.0, version 4.094.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for bash 5.0-alpha.
#
#htmldir=
case "${host_cpu}-${host_os}" in
+# mostly obsolete platforms
alpha*-*) opt_bash_malloc=no ;; # alpha running osf/1 or linux
*[Cc]ray*-*) opt_bash_malloc=no ;; # Crays
*-osf1*) opt_bash_malloc=no ;; # other osf/1 machines
+*-dgux*) opt_bash_malloc=no ;; # DG/UX machines
sparc-svr4*) opt_bash_malloc=no ;; # sparc SVR4, SVR4.2
-sparc-netbsd*) opt_bash_malloc=no ;; # needs 8-byte alignment
-mips-irix6*) opt_bash_malloc=no ;; # needs 8-byte alignment
m68k-sysv) opt_bash_malloc=no ;; # fixes file descriptor leak in closedir
+*-bsdi2.1|*-bsdi3.?) opt_bash_malloc=no ; : ${CC:=shlicc2} ;; # for loadable builtins
+*-opennt*|*-interix*) opt_bash_malloc=no ;; # Interix, now owned by Microsoft
+*-beos*) opt_bash_malloc=no ;; # they say it's suitable
+# These need additional investigation
sparc-linux*) opt_bash_malloc=no ;; # sparc running linux; requires ELF
-#*-freebsd*-gnu) opt_bash_malloc=no ;; # there's some undetermined problem here
-#*-freebsd*) opt_bash_malloc=no ;; # they claim it's better; I disagree
-*-openbsd*) opt_bash_malloc=no ;; # they claim it needs eight-bit alignment
-*-mirbsd*) opt_bash_malloc=no ;; # they claim it needs eight-bit alignment
*-aix*) opt_bash_malloc=no ;; # AIX machines
+*-cygwin*) opt_bash_malloc=no ;; # Cygnus's CYGWIN environment
+# Mach-derived systems have a ton of extra malloc functions and lack sbrk(2)
*-nextstep*) opt_bash_malloc=no ;; # NeXT machines running NeXTstep
*-openstep*) opt_bash_malloc=no ;; # i386/Sparc/HP machines running Openstep
*-macos*) opt_bash_malloc=no ;; # Apple MacOS X
*-rhapsody*) opt_bash_malloc=no ;; # Apple Rhapsody (MacOS X)
*-darwin*) opt_bash_malloc=no ;; # Apple Darwin (MacOS X)
-*-dgux*) opt_bash_malloc=no ;; # DG/UX machines
-*-qnx*) opt_bash_malloc=no ;; # QNX 4.2, QNX [67].x
*-machten4) opt_bash_malloc=no ;; # MachTen 4.x
-*-bsdi2.1|*-bsdi3.?) opt_bash_malloc=no ; : ${CC:=shlicc2} ;; # for loadable builtins
-*-beos*) opt_bash_malloc=no ;; # they say it's suitable
-*-cygwin*) opt_bash_malloc=no ;; # Cygnus's CYGWIN environment
-*-opennt*|*-interix*) opt_bash_malloc=no ;; # Interix, now owned by Microsoft
+# Niche or non-mainstream-shell-user systems
+*-qnx*) opt_bash_malloc=no ;; # QNX 4.2, QNX [67].x
*-nsk*) opt_bash_malloc=no ;; # HP NonStop
*-haiku*) opt_bash_malloc=no ;; # Haiku OS
+# Deprecated -- bash malloc is suitable
+#sparc-netbsd*) opt_bash_malloc=no ;; # needs 8-byte alignment
+#mips-irix6*) opt_bash_malloc=no ;; # needs 8-byte alignment
+#*-freebsd*-gnu) opt_bash_malloc=no ;; # there's some undetermined problem here
+#*-freebsd*) opt_bash_malloc=no ;; # they claim it's better; I disagree
+#*-openbsd*) opt_bash_malloc=no ;; # they claim it needs eight-bit alignment
+#*-mirbsd*) opt_bash_malloc=no ;; # they claim it needs eight-bit alignment
esac
# memory scrambling on free()
dnl
dnl Process this file with autoconf to produce a configure script.
-# Copyright (C) 1987-2016 Free Software Foundation, Inc.
+# Copyright (C) 1987-2018 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-AC_REVISION([for Bash 5.0, version 4.092])dnl
+AC_REVISION([for Bash 5.0, version 4.094])dnl
define(bashvers, 5.0)
define(relstatus, alpha)
dnl and some need a special compiler or loader
dnl look in the NOTES file for more
case "${host_cpu}-${host_os}" in
+# mostly obsolete platforms
alpha*-*) opt_bash_malloc=no ;; # alpha running osf/1 or linux
*[[Cc]]ray*-*) opt_bash_malloc=no ;; # Crays
*-osf1*) opt_bash_malloc=no ;; # other osf/1 machines
+*-dgux*) opt_bash_malloc=no ;; # DG/UX machines
sparc-svr4*) opt_bash_malloc=no ;; # sparc SVR4, SVR4.2
-sparc-netbsd*) opt_bash_malloc=no ;; # needs 8-byte alignment
-mips-irix6*) opt_bash_malloc=no ;; # needs 8-byte alignment
m68k-sysv) opt_bash_malloc=no ;; # fixes file descriptor leak in closedir
+*-bsdi2.1|*-bsdi3.?) opt_bash_malloc=no ; : ${CC:=shlicc2} ;; # for loadable builtins
+*-opennt*|*-interix*) opt_bash_malloc=no ;; # Interix, now owned by Microsoft
+*-beos*) opt_bash_malloc=no ;; # they say it's suitable
+# These need additional investigation
sparc-linux*) opt_bash_malloc=no ;; # sparc running linux; requires ELF
-#*-freebsd*-gnu) opt_bash_malloc=no ;; # there's some undetermined problem here
-#*-freebsd*) opt_bash_malloc=no ;; # they claim it's better; I disagree
-*-openbsd*) opt_bash_malloc=no ;; # they claim it needs eight-bit alignment
-*-mirbsd*) opt_bash_malloc=no ;; # they claim it needs eight-bit alignment
*-aix*) opt_bash_malloc=no ;; # AIX machines
+*-cygwin*) opt_bash_malloc=no ;; # Cygnus's CYGWIN environment
+# Mach-derived systems have a ton of extra malloc functions and lack sbrk(2)
*-nextstep*) opt_bash_malloc=no ;; # NeXT machines running NeXTstep
*-openstep*) opt_bash_malloc=no ;; # i386/Sparc/HP machines running Openstep
*-macos*) opt_bash_malloc=no ;; # Apple MacOS X
*-rhapsody*) opt_bash_malloc=no ;; # Apple Rhapsody (MacOS X)
*-darwin*) opt_bash_malloc=no ;; # Apple Darwin (MacOS X)
-*-dgux*) opt_bash_malloc=no ;; # DG/UX machines
-*-qnx*) opt_bash_malloc=no ;; # QNX 4.2, QNX [67].x
*-machten4) opt_bash_malloc=no ;; # MachTen 4.x
-*-bsdi2.1|*-bsdi3.?) opt_bash_malloc=no ; : ${CC:=shlicc2} ;; # for loadable builtins
-*-beos*) opt_bash_malloc=no ;; # they say it's suitable
-*-cygwin*) opt_bash_malloc=no ;; # Cygnus's CYGWIN environment
-*-opennt*|*-interix*) opt_bash_malloc=no ;; # Interix, now owned by Microsoft
+# Niche or non-mainstream-shell-user systems
+*-qnx*) opt_bash_malloc=no ;; # QNX 4.2, QNX [67].x
*-nsk*) opt_bash_malloc=no ;; # HP NonStop
*-haiku*) opt_bash_malloc=no ;; # Haiku OS
+# Deprecated -- bash malloc is suitable
+#sparc-netbsd*) opt_bash_malloc=no ;; # needs 8-byte alignment
+#mips-irix6*) opt_bash_malloc=no ;; # needs 8-byte alignment
+#*-freebsd*-gnu) opt_bash_malloc=no ;; # there's some undetermined problem here
+#*-freebsd*) opt_bash_malloc=no ;; # they claim it's better; I disagree
+#*-openbsd*) opt_bash_malloc=no ;; # they claim it needs eight-bit alignment
+#*-mirbsd*) opt_bash_malloc=no ;; # they claim it needs eight-bit alignment
esac
# memory scrambling on free()
((TYPE_WIDTH (t) - TYPE_SIGNED (t)) * 302 / 1000 \
+ 1 + TYPE_SIGNED (t))
+/* Updated version adapted from gnulib/intprops.h, not used right now.
+ Changes the approximation of log10(2) from 302/1000 to 146/485. */
+#if 0
+#define INT_STRLEN_BOUND(t) \
+ (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - TYPE_SIGNED (t)) + TYPE_SIGNED(t))
+#endif
+
/* Bound on buffer size needed to represent an integer type or expression T,
including the terminating null. */
#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
Return an array of tokens parsed out of @var{string}, much as the
shell might. The tokens are split on the characters in the
@var{history_word_delimiters} variable,
-and shell quoting conventions are obeyed.
+and shell quoting conventions are obeyed as described below.
@end deftypefun
@deftypefun {char *} history_arg_extract (int first, int last, const char *string)
@end deftypevar
@deftypevar int history_quotes_inhibit_expansion
-If non-zero, double-quoted words are not scanned for the history expansion
-character or the history comment character. The default value is 0.
+If non-zero, the history expansion code implements shell-like quoting:
+single-quoted words are not scanned for the history expansion
+character or the history comment character, and double-quoted words may
+have history expansion performed, since single quotes are not special
+within double quotes.
+The default value is 0.
+@end deftypevar
+
+@deftypevar int history_quoting_state
+An application may set this variable to indicate that the current line
+being expanded is subject to existing quoting. If set to @samp{'}, the
+history expansion function will assume that the line is single-quoted and
+inhibit expansion until it reads an unquoted closing single quote; if set
+to @samp{"}, history expansion will assume the line is double quoted until
+it reads an unquoted closing double quote. If set to zero, the default,
+the history expansion function will assume the line is not quoted and
+treat quote characters within the line as described above.
+This is only effective if @var{history_quotes_inhibit_expansion} is set.
@end deftypevar
@deftypevar {rl_linebuf_func_t *} history_inhibit_expansion_function
@ifset BashFeatures
History expansion is performed immediately after a complete line
is read, before the shell breaks it into words, and is performed
-on each line individually without taking quoting on previous lines into
-account.
+on each line individually. Bash attempts to inform the history
+expansion functions about quoting still in effect from previous lines.
@end ifset
History expansion takes place in two parts. The first is to determine
surrounded by quotes are considered one word.
History expansions are introduced by the appearance of the
history expansion character, which is @samp{!} by default.
+
+History expansion implements shell-like quoting conventions:
+a backslash can be used to remove the special handling for the next character;
+single quotes enclose verbatim sequences of characters, and can be used to
+inhibit history expansion;
+and characters enclosed within double quotes may be subject to history
+expansion, since backslash can escape the history expansion character,
+but single quotes may not, since they are not treated specially within
+double quotes.
+
@ifset BashFeatures
-Only @samp{\} and @samp{'} may be used to escape the history expansion
-character, but the history expansion character is
+When using the shell, only @samp{\} and @samp{'} may be used to escape the
+history expansion character, but the history expansion character is
also treated as quoted if it immediately precedes the closing double quote
in a double-quoted string.
@end ifset
@ignore
-Copyright (C) 1988-2017 Free Software Foundation, Inc.
+Copyright (C) 1988-2018 Free Software Foundation, Inc.
@end ignore
-@set EDITION 7.0
-@set VERSION 7.0
-@set UPDATED 28 December 2017
-@set UPDATED-MONTH December 2017
+@set EDITION 8.0
+@set VERSION 8.0
+@set UPDATED 6 July 2018
+@set UPDATED-MONTH July 2018
-@set LASTCHANGE Thu Dec 28 14:44:16 EST 2017
+@set LASTCHANGE Fri Jul 6 16:25:22 MDT 2018
/* histexpand.c -- history expansion. */
-/* Copyright (C) 1989-2017 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2018 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
particular history expansion should be performed. */
rl_linebuf_func_t *history_inhibit_expansion_function;
+int history_quoting_state = 0;
+
/* **************************************************************** */
/* */
/* History Expansion */
/* `!' followed by one of the characters in history_no_expand_chars
is NOT an expansion. */
- for (i = dquote = squote = 0; string[i]; i++)
+ dquote = history_quoting_state == '"';
+ squote = history_quoting_state == '\'';
+
+ /* If the calling application tells us we are already reading a
+ single-quoted string, consume the rest of the string right now
+ and then go on. */
+ i = 0;
+ if (squote && history_quotes_inhibit_expansion)
+ {
+ hist_string_extract_single_quoted (string, &i, 0);
+ squote = 0;
+ if (string[i])
+ i++;
+ }
+
+ for ( ; string[i]; i++)
{
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
}
/* Extract and perform the substitution. */
- for (passc = dquote = squote = i = j = 0; i < l; i++)
+ dquote = history_quoting_state == '"';
+ squote = history_quoting_state == '\'';
+
+ /* If the calling application tells us we are already reading a
+ single-quoted string, consume the rest of the string right now
+ and then go on. */
+ i = j = 0;
+ if (squote && history_quotes_inhibit_expansion)
+ {
+ int c;
+
+ hist_string_extract_single_quoted (string, &i, 0);
+ squote = 0;
+ for (c = 0; c < i; c++)
+ ADD_CHAR (string[c]);
+ if (string[i])
+ {
+ ADD_CHAR (string[i]);
+ i++;
+ }
+ }
+
+ for (passc = 0; i < l; i++)
{
int qc, tchar = string[i];
extern char history_comment_char;
extern char *history_no_expand_chars;
extern char *history_search_delimiter_chars;
+
extern int history_quotes_inhibit_expansion;
+extern int history_quoting_state;
extern int history_write_timestamps;
{
char *expansions;
# if defined (BANG_HISTORY)
- int old_hist;
-
/* If the current delimiter is a single quote, we should not be
performing history expansion, even if we're on a different
line from the original single quote. */
- old_hist = history_expansion_inhibited;
if (current_delimiter (dstack) == '\'')
- history_expansion_inhibited = 1;
+ history_quoting_state = '\'';
+ else if (current_delimiter (dstack) == '"')
+ history_quoting_state = '"';
+ else
+ history_quoting_state = 0;
# endif
/* Calling with a third argument of 1 allows remember_on_history to
determine whether or not the line is saved to the history list */
expansions = pre_process_line (shell_input_line, 1, 1);
# if defined (BANG_HISTORY)
- history_expansion_inhibited = old_hist;
+ history_quoting_state = 0;
# endif
if (expansions != shell_input_line)
{
*(/tmp|/dev|/usr)/Step1
echo *(/tmp|/dev|/usr)/Step1
*(/tmp|/dev|/usr)/Step1
+one
+ echo echo one
+echo one
+echo one
+echo one
+ 1 set -o histexpand
+ 2 echo one
+ 3 for f in a b c; do echo echo one; done
+two
+ echo echo two
+echo two
+echo two
+echo two
+ 1 echo two
+ 2 for f in a b c; do echo echo two; done
${THIS_SH} ./histexp3.sub
${THIS_SH} ./histexp4.sub
${THIS_SH} ./histexp5.sub
+${THIS_SH} ./histexp6.sub
--- /dev/null
+HISTFILE=$TMPDIR/bashhist-$$
+
+set -o history
+set -o histexpand
+
+echo one
+
+for f in a b c; do
+ echo !!
+done
+
+history
+history -c
+
+echo two
+for f in a b c; do
+ echo !-1
+done
+
+history
+
+set +o history
+rm -f $HISTFILE