From: Chet Ramey Date: Thu, 3 Mar 2022 16:11:47 +0000 (-0500) Subject: add rl_eof_found to public API; fix pointer aliasing problems with history-search... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=002d31aa5f5929eb32d0e0e2e8b8d35d99e59961;p=thirdparty%2Freadline.git add rl_eof_found to public API; fix pointer aliasing problems with history-search-backward; fix a display problem with runs of invisible characters at the end of a physical screen line --- diff --git a/.gitignore~ b/.gitignore~ deleted file mode 100644 index be107bb..0000000 --- a/.gitignore~ +++ /dev/null @@ -1,37 +0,0 @@ -Makefile - -*.o -*.a -*.so -*.sl -*.dll - -config.cache -config.h -config.log -config.status - -doc/Makefile -examples/Makefile -shlib/Makefile - -examples/fileman -examples/hist_erasedups -examples/hist_purgecmd -examples/histexamp -examples/rl -examples/rl-callbacktest -examples/rlbasic -examples/rlcat -examples/rlevent -examples/rltest -examples/rlversion - -libhistory.so.* -libreadline.so.* - -*.dylib - -readline.pc - -stamp-h diff --git a/CHANGES-8.0 b/CHANGES-8.0 deleted file mode 100644 index 1edf7ef..0000000 --- a/CHANGES-8.0 +++ /dev/null @@ -1,122 +0,0 @@ -This document details the changes between this version, readline-8.0, and the -previous version, readline-7.0. - -1. Changes to Readline - -a. Added a guard to prevent nested macros from causing an infinite expansion - loop. - -b. Instead of allocating enough history list entries to hold the maximum list - size, cap the number allocated initially. - -c. Added a strategy to avoid allocating huge amounts of memory if a block of - history entries without timestamps occurs after a block with timestamps. - -d. Added support for keyboard timeouts when an ESC character is the last - character in a macro. - -e. There are several performance improvements when in a UTF-8 locale. - -f. Readline does a better job of preserving the original set of blocked - signals when using pselect() to wait for input. - -g. Fixed a bug that caused multibyte characters in macros to be mishandled. - -h. Fixed several bugs in the code that calculates line breaks when expanding - prompts that span several lines, contain multibyte characters, and contain - invisible character seqeuences. - -i. Fixed several bugs in cursor positioning when displaying lines with prompts - containing invisible characters and multibyte characters. - -j. When performing case-insensitive completion, Readline no longer sorts the - list of matches unless directed to do so. - -k. Fixed a problem with key sequences ending with a backslash. - -l. Fixed out-of-bounds and free memory read errors found via fuzzing. - -m. Fixed several cases where the mark was set to an invalid value. - -n. Fixed a problem with the case-changing operators in the case where the - lower and upper case versions of a character do not have the same number - of bytes. - -o. Handle incremental and non-incremental search character reads returning EOF. - -p. Handle the case where a failing readline command at the end of a multi-key - sequence could be misinterpreted. - -q. The history library now prints a meaningful error message if the history - file isn't a regular file. - -r. Fixed a problem with vi-mode redo (`.') on a command when trying to replace - a multibyte character. - -s. The key binding code now attempts to remove a keymap if a key unbinding - leaves it empty. - -t. Fixed a line-wrapping issue that caused problems for some terminal - emulators. - -u. If there is a key bound to the tty's VDISCARD special character, readline - disables VDISCARD while it is active. - -v. Fixed a problem with exiting bracketed paste mode on terminals that assume - the bracketed paste mode character sequence contains visible characters. - -w. Fixed a bug that could cause a key binding command to refer to an - uninitialized variable. - -x. Added more UTF-8-specific versions of multibyte functions, and optimized - existing functions if the current locale uses UTF-8 encoding. - -y. Fixed a problem with bracketed-paste inserting more than one character and - interacting with other readline functions. - -z. Fixed a bug that caused the history library to attempt to append a history - line to a non-existent history entry. - -aa. If using bracketed paste mode, output a newline after the \r that is the - last character of the mode disable string to avoid overwriting output. - -bb. Fixes to the vi-mode `b', `B', `w', `W', `e', and `E' commands to better - handle multibyte characters. - -cc. Fixed a redisplay problem that caused an extra newline to be generated on - accept-line when the line length is exactly the screenwidth. - -2. New Features in Readline - -a. Non-incremental vi-mode search (`N', `n') can search for a shell pattern, as - Posix specifies (uses fnmatch(3) if available). - -b. There are new `next-screen-line' and `previous-screen-line' bindable - commands, which move the cursor to the same column in the next, or previous, - physical line, respectively. - -c. There are default key bindings for control-arrow-key key combinations. - -d. A negative argument (-N) to `quoted-insert' means to insert the next N - characters using quoted-insert. - -e. New public function: rl_check_signals(), which allows applications to - respond to signals that readline catches while waiting for input using - a custom read function. - -f. There is new support for conditionally testing the readline version in an - inputrc file, with a full set of arithmetic comparison operators available. - -g. There is a simple variable comparison facility available for use within an - inputrc file. Allowable operators are equality and inequality; string - variables may be compared to a value; boolean variables must be compared to - either `on' or `off'; variable names are separated from the operator by - whitespace. - -h. The history expansion library now understands command and process - substitution and extended globbing and allows them to appear anywhere in a - word. - -i. The history library has a new variable that allows applications to set the - initial quoting state, so quoting state can be inherited from a previous - line. diff --git a/CHANGES-8.2 b/CHANGES-8.2 new file mode 100644 index 0000000..97b42d2 --- /dev/null +++ b/CHANGES-8.2 @@ -0,0 +1,85 @@ +This document details the changes between this version, readline-8.2, and +the previous version, readline-8.1. + +1. Changes to Readline + +a. Fixed a problem with cleaning up active marks when using callback mode. + +b. Fixed a problem with arithmetic comparison operators checking the version. + +c. Fixed a problem that could cause readline not to build on systems without + POSIX signal functions. + +d. Fixed a bug that could cause readline to crash if the application removed + the callback line handler before readline read all typeahead. + +e. Added additional checks for read errors in the middle of readline commands. + +f. Fixed a redisplay problem that occurred when switching from the digit- + argument prompt `(arg: N)' back to the regular prompt and the regular + prompt contained invisible characters. + +g. Fixed a problem with restoring the prompt when aborting an incremental + search. + +h. Fix a problem with characters > 128 not being displayed correctly in certain + single-byte encodings. + +i. Fixed a problem with unix-filename-rubout that caused it to delete too much + when applied to a pathname consisting only of one or more slashes. + +j. Fixed a display problem that caused the prompt to be wrapped incorrectly if + the screen changed dimensions during a call to readline() and the prompt + became longer than the screen width. + +k. Fixed a problem that caused the \r output by turning off bracketed paste + to overwrite the line if terminal echo was disabled. + +l. Fixed a bug that could cause colored-completion-prefix to not display if + completion-prefix-display-length was set. + +m. Fixed a problem with line wrapping prompts when a group of invisible + characters runs to the right edge of the screen and the prompt extends + longer then the screen width. + +n. Fixed a couple problems that could cause rl_end to be set incorrectly by + transpose-words. + +2. New Features in Readline + +a. There is now an HS_HISTORY_VERSION containing the version number of the + history library for applications to use. + +b. History expansion better understands multiple history expansions that may + contain strings that would ordinarily inhibit history expansion (e.g., + `abc!$!$'). + +c. There is a new framework for readline timeouts, including new public + functions to set timeouts and query how much time is remaining before a + timeout hits, and a hook function that can trigger when readline times + out. There is a new state value to indicate a timeout. + +d. Automatically bind termcap key sequences for page-up and page-down to + history-search-backward and history-search-forward, respectively. + +e. There is a new `fetch-history' bindable command that retrieves the history + entry corresponding to its numeric argument. Negative arguments count back + from the end of the history. + +f. `vi-undo' is now a bindable command. + +g. There is a new option: `enable-active-region'. This separates control of + the active region and bracketed-paste. It has the same default value as + bracketed-paste, and enabling bracketed paste enables the active region. + Users can now turn off the active region while leaving bracketed paste + enabled. + +h. rl_completer_word_break_characters is now `const char *' like + rl_basic_word_break_characters. + +i. The non-incremental history searches now leave the current history offset + at the position of the last matching history entry, like incremental search. + +j. Readline looks in $LS_COLORS for a custom filename extension + (*.readline-colored-completion-prefix) and uses that as the default color + for the common prefix displayed when `colored-completion-prefix' is set. diff --git a/NEWS-8.0 b/NEWS-8.0 deleted file mode 100644 index 9318d1a..0000000 --- a/NEWS-8.0 +++ /dev/null @@ -1,37 +0,0 @@ -This is a terse description of the new features added to readline-8.0 since -the release of readline-7.0. - -New Features in Readline - -a. Non-incremental vi-mode search (`N', `n') can search for a shell pattern, as - Posix specifies (uses fnmatch(3) if available). - -b. There are new `next-screen-line' and `previous-screen-line' bindable - commands, which move the cursor to the same column in the next, or previous, - physical line, respectively. - -c. There are default key bindings for control-arrow-key key combinations. - -d. A negative argument (-N) to `quoted-insert' means to insert the next N - characters using quoted-insert. - -e. New public function: rl_check_signals(), which allows applications to - respond to signals that readline catches while waiting for input using - a custom read function. - -f. There is new support for conditionally testing the readline version in an - inputrc file, with a full set of arithmetic comparison operators available. - -g. There is a simple variable comparison facility available for use within an - inputrc file. Allowable operators are equality and inequality; string - variables may be compared to a value; boolean variables must be compared to - either `on' or `off'; variable names are separated from the operator by - whitespace. - -h. The history expansion library now understands command and process - substitution and extended globbing and allows them to appear anywhere in a - word. - -i. The history library has a new variable that allows applications to set the - initial quoting state, so quoting state can be inherited from a previous - line. diff --git a/NEWS-8.2 b/NEWS-8.2 new file mode 100644 index 0000000..58753a6 --- /dev/null +++ b/NEWS-8.2 @@ -0,0 +1,41 @@ +This is a terse description of the new features added to readline-8.2 since +the release of readline-8.1. + +New Features in Readline + +a. There is now an HS_HISTORY_VERSION containing the version number of the + history library for applications to use. + +b. History expansion better understands multiple history expansions that may + contain strings that would ordinarily inhibit history expansion (e.g., + `abc!$!$'). + +c. There is a new framework for readline timeouts, including new public + functions to set timeouts and query how much time is remaining before a + timeout hits, and a hook function that can trigger when readline times + out. There is a new state value to indicate a timeout. + +d. Automatically bind termcap key sequences for page-up and page-down to + history-search-backward and history-search-forward, respectively. + +e. There is a new `fetch-history' bindable command that retrieves the history + entry corresponding to its numeric argument. Negative arguments count back + from the end of the history. + +f. `vi-undo' is now a bindable command. + +g. There is a new option: `enable-active-region'. This separates control of + the active region and bracketed-paste. It has the same default value as + bracketed-paste, and enabling bracketed paste enables the active region. + Users can now turn off the active region while leaving bracketed paste + enabled. + +h. rl_completer_word_break_characters is now `const char *' like + rl_basic_word_break_characters. + +i. The non-incremental history searches now leave the current history offset + at the position of the last matching history entry, like incremental search. + +j. Readline looks in $LS_COLORS for a custom filename extension + (*.readline-colored-completion-prefix) and uses that as the default color + for the common prefix displayed when `colored-completion-prefix' is set. diff --git a/callback.c b/callback.c index cfff650..1a3235f 100644 --- a/callback.c +++ b/callback.c @@ -1,6 +1,6 @@ /* callback.c -- functions to use readline as an X `callback' mechanism. */ -/* Copyright (C) 1987-2017 Free Software Foundation, Inc. +/* Copyright (C) 1987-2022 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. @@ -136,6 +136,8 @@ rl_callback_read_char (void) abort (); } + eof = 0; + memcpy ((void *)olevel, (void *)_rl_top_level, sizeof (procenv_t)); #if defined (HAVE_POSIX_SIGSETJMP) jcode = sigsetjmp (_rl_top_level, 0); @@ -276,6 +278,10 @@ rl_callback_read_char (void) _rl_want_redisplay = 0; } + /* Make sure application hooks can see whether we saw EOF. */ + if (rl_eof_found = eof) + RL_SETSTATE(RL_STATE_EOF); + if (rl_done) { line = readline_internal_teardown (eof); diff --git a/display.c b/display.c index fe1e4cc..3ac09c7 100644 --- a/display.c +++ b/display.c @@ -439,7 +439,15 @@ expand_prompt (char *pmt, int flags, int *lp, int *lip, int *niflp, int *vlp) to add them, since update_line expects them to be counted before wrapping the line. */ if (can_add_invis) - local_prompt_newlines[newlines] = r - ret; + { + local_prompt_newlines[newlines] = r - ret; + /* If we're adding to the number of invisible characters on the + first line of the prompt, but we've already set the number of + invisible characters on that line, we need to adjust the + counter. */ + if (invflset && newlines == 1) + invfl = ninvis; + } if (p != (igstart + 1)) last = r - ret - 1; continue; diff --git a/doc/readline.3 b/doc/readline.3 index a3d2622..b61d542 100644 --- a/doc/readline.3 +++ b/doc/readline.3 @@ -492,8 +492,10 @@ matching text found by incremental and non-incremental history searches. When set to \fBOn\fP, readline will configure the terminal in a way that will enable it to insert each paste into the editing buffer as a single string of characters, instead of treating each character as if -it had been read from the keyboard. This can prevent pasted characters -from being interpreted as editing commands. +it had been read from the keyboard +and executing any editing commands +bound to key sequences appearing in the pasted text. +This will prevent pasted characters from being interpreted as editing commands. .TP .B enable\-keypad (Off) When set to \fBOn\fP, readline will try to enable the application diff --git a/doc/rltech.texi b/doc/rltech.texi index 01343ed..6f7ffb9 100644 --- a/doc/rltech.texi +++ b/doc/rltech.texi @@ -323,6 +323,14 @@ and point define a @emph{region}. @deftypevar int rl_done Setting this to a non-zero value causes Readline to return the current line immediately. +Readline will set this variable when it has read a key sequence bound +to @code{accept-line} and is about to return the line to the caller. +@end deftypevar + +@deftypevar int rl_eof_found +Readline will set this variable when it has read an EOF character (e.g., the +stty @samp{EOF} character) on an empty line or encountered a read error and +is about to return a NULL line to the caller. @end deftypevar @deftypevar int rl_num_chars_to_read @@ -597,6 +605,9 @@ and is about to return the line to the caller. Readline has timed out (it did not receive a line or specified number of characters before the timeout duration specified by @code{rl_set_timeout} elapsed) and is returning that status to the caller. +@item RL_STATE_EOF +Readline has read an EOF character (e.g., the stty @samp{EOF} character) +or encountered a read error and is about to return a NULL line to the caller. @end table @end deftypevar diff --git a/doc/rluser.texi b/doc/rluser.texi index 63e2c75..deaff14 100644 --- a/doc/rluser.texi +++ b/doc/rluser.texi @@ -591,8 +591,11 @@ The default is @samp{On}. When set to @samp{On}, Readline will configure the terminal in a way that will enable it to insert each paste into the editing buffer as a single string of characters, instead of treating each character as if -it had been read from the keyboard. This can prevent pasted characters -from being interpreted as editing commands. The default is @samp{On}. +it had been read from the keyboard +and executing any editing commands +bound to key sequences appearing in the pasted text. +This will prevent pasted characters from being interpreted as editing commands. +The default is @samp{On}. @item enable-keypad @vindex enable-keypad diff --git a/doc/version.texi b/doc/version.texi index 46c88bd..42ead15 100644 --- a/doc/version.texi +++ b/doc/version.texi @@ -5,7 +5,7 @@ Copyright (C) 1988-2022 Free Software Foundation, Inc. @set EDITION 8.2 @set VERSION 8.2 -@set UPDATED Thu Feb 10 10:56:04 EST 2022 +@set UPDATED 18 February 2022 @set UPDATED-MONTH February 2022 -@set LASTCHANGE Thu Feb 10 10:56:20 EST 2022 +@set LASTCHANGE Fri Feb 18 11:12:48 EST 2022 diff --git a/history.h b/history.h index ad2ce70..5208f9a 100644 --- a/history.h +++ b/history.h @@ -1,6 +1,6 @@ /* history.h -- the names of functions that you can call in history. */ -/* Copyright (C) 1989-2021 Free Software Foundation, Inc. +/* Copyright (C) 1989-2022 Free Software Foundation, Inc. This file contains the GNU History Library (History), a set of routines for managing the text of previously typed lines. diff --git a/misc.c b/misc.c index 5670cda..96d37b8 100644 --- a/misc.c +++ b/misc.c @@ -1,6 +1,6 @@ /* misc.c -- miscellaneous bindable readline functions. */ -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. +/* Copyright (C) 1987-2022 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. @@ -50,6 +50,7 @@ #include "history.h" #include "rlprivate.h" +#include "histlib.h" #include "rlshell.h" #include "xmalloc.h" @@ -308,6 +309,7 @@ _rl_start_using_history (void) if (_rl_saved_line_for_history) _rl_free_saved_history_line (); _rl_saved_line_for_history = (HIST_ENTRY *)NULL; + _rl_history_search_pos = -99; /* some random invalid history position */ } /* Free the contents (and containing structure) of a HIST_ENTRY. */ @@ -380,6 +382,8 @@ rl_maybe_save_line (void) int _rl_free_saved_history_line (void) { + UNDO_LIST *orig; + if (_rl_saved_line_for_history) { if (rl_undo_list && rl_undo_list == (UNDO_LIST *)_rl_saved_line_for_history->data) @@ -389,7 +393,12 @@ _rl_free_saved_history_line (void) callers that know this is _rl_saved_line_for_history can know that it's an undo list. */ if (_rl_saved_line_for_history->data) - _rl_free_undo_list ((UNDO_LIST *)_rl_saved_line_for_history->data); + { + orig = rl_undo_list; + rl_undo_list = _rl_saved_line_for_history->data; + rl_free_undo_list (); + rl_undo_list = orig; + } _rl_free_history_entry (_rl_saved_line_for_history); _rl_saved_line_for_history = (HIST_ENTRY *)NULL; } diff --git a/readline.c b/readline.c index 371e1fb..888612c 100644 --- a/readline.c +++ b/readline.c @@ -1,7 +1,7 @@ /* readline.c -- a general facility for reading lines of input with emacs style editing and completion. */ -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. +/* Copyright (C) 1987-2022 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. @@ -164,6 +164,9 @@ int rl_end; /* Make this non-zero to return the current input_line. */ int rl_done; +/* If non-zero when readline_internal returns, it means we found EOF */ +int rl_eof_found = 0; + /* The last function executed by readline. */ rl_command_func_t *rl_last_func = (rl_command_func_t *)NULL; @@ -217,9 +220,6 @@ int _rl_eof_char = CTRL ('D'); /* Non-zero makes this the next keystroke to read. */ int rl_pending_input = 0; -/* If non-zero when readline_internal returns, it means we found EOF */ -int _rl_eof_found = 0; - /* Pointer to a useful terminal name. */ const char *rl_terminal_name = (const char *)NULL; @@ -479,11 +479,17 @@ readline_internal_teardown (int eof) RL_CHECK_SIGNALS (); + if (eof) + RL_SETSTATE (RL_STATE_EOF); /* XXX */ + /* Restore the original of this history line, iff the line that we are editing was originally in the history, AND the line has changed. */ entry = current_history (); - if (entry && rl_undo_list) + /* We don't want to do this if we executed functions that call + history_set_pos to set the history offset to the line containing the + non-incremental search string. */ + if (entry && rl_undo_list && _rl_history_search_pos != where_history ()) { temp = savestring (the_line); rl_revert_line (1, 0); @@ -615,6 +621,7 @@ readline_internal_charloop (void) RL_SETSTATE(RL_STATE_DONE); return (rl_done = 1); #else + RL_SETSTATE(RL_STATE_EOF); eof_found = 1; break; #endif @@ -655,6 +662,7 @@ readline_internal_charloop (void) RL_SETSTATE(RL_STATE_DONE); return (rl_done = 1); #else + RL_SETSTATE(RL_STATE_EOF); eof_found = 1; break; #endif @@ -717,8 +725,8 @@ static char * readline_internal (void) { readline_internal_setup (); - _rl_eof_found = readline_internal_charloop (); - return (readline_internal_teardown (_rl_eof_found)); + rl_eof_found = readline_internal_charloop (); + return (readline_internal_teardown (rl_eof_found)); } void @@ -1178,7 +1186,7 @@ rl_initialize (void) /* We aren't done yet. We haven't even gotten started yet! */ rl_done = 0; - RL_UNSETSTATE(RL_STATE_DONE); + RL_UNSETSTATE(RL_STATE_DONE|RL_STATE_TIMEOUT|RL_STATE_EOF); /* Tell the history routines what is going on. */ _rl_start_using_history (); diff --git a/readline.h b/readline.h index 7cf1fcf..cac269f 100644 --- a/readline.h +++ b/readline.h @@ -1,6 +1,6 @@ /* Readline.h -- the names of functions callable from within readline. */ -/* Copyright (C) 1987-2021 Free Software Foundation, Inc. +/* Copyright (C) 1987-2022 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. @@ -562,6 +562,10 @@ extern int rl_mark; line and should return it. */ extern int rl_done; +/* Flag to indicate that readline has read an EOF character or read has + returned 0 or error, and is returning a NULL line as a result. */ +extern int rl_eof_found; + /* If set to a character value, that will be the next keystroke read. */ extern int rl_pending_input; @@ -917,7 +921,8 @@ extern int rl_persistent_signal_handlers; #define RL_STATE_REDISPLAYING 0x1000000 /* updating terminal display */ #define RL_STATE_DONE 0x2000000 /* done; accepted line */ -#define RL_STATE_TIMEOUT 0x4000000 +#define RL_STATE_TIMEOUT 0x4000000 /* done; timed out */ +#define RL_STATE_EOF 0x8000000 /* done; got eof on read */ #define RL_SETSTATE(x) (rl_readline_state |= (x)) #define RL_UNSETSTATE(x) (rl_readline_state &= ~(x)) diff --git a/rlprivate.h b/rlprivate.h index db20b92..70ff01c 100644 --- a/rlprivate.h +++ b/rlprivate.h @@ -563,7 +563,6 @@ extern FILE *_rl_in_stream; extern FILE *_rl_out_stream; extern int _rl_last_command_was_kill; extern int _rl_eof_char; -extern int _rl_eof_found; extern procenv_t _rl_top_level; extern _rl_keyseq_cxt *_rl_kscxt; extern int _rl_keyseq_timeout; @@ -574,6 +573,7 @@ extern rl_hook_func_t *_rl_internal_startup_hook; /* search.c */ extern _rl_search_cxt *_rl_nscxt; +extern int _rl_history_search_pos; /* signals.c */ extern int volatile _rl_caught_signal; diff --git a/rltty.c b/rltty.c index b34de2a..882a3d4 100644 --- a/rltty.c +++ b/rltty.c @@ -1,7 +1,7 @@ /* rltty.c -- functions to prepare and restore the terminal for readline's use. */ -/* Copyright (C) 1992-2021 Free Software Foundation, Inc. +/* Copyright (C) 1992-2022 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. @@ -694,7 +694,7 @@ rl_deprep_terminal (void) fprintf (rl_outstream, BRACK_PASTE_FINI); /* Since the last character in BRACK_PASTE_FINI is \r */ _rl_last_c_pos = 0; - if (_rl_eof_found && (RL_ISSTATE (RL_STATE_TIMEOUT) == 0)) + if (rl_eof_found && (RL_ISSTATE (RL_STATE_TIMEOUT) == 0)) fprintf (rl_outstream, "\n"); else if (_rl_echoing_p == 0) fprintf (rl_outstream, "\n"); diff --git a/search.c b/search.c index 325d51e..2245166 100644 --- a/search.c +++ b/search.c @@ -1,6 +1,6 @@ /* search.c - code for non-incremental searching in emacs and vi modes. */ -/* Copyright (C) 1992-2021 Free Software Foundation, Inc. +/* Copyright (C) 1992-2022 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. @@ -60,9 +60,9 @@ static int noninc_history_pos; static char *prev_line_found = (char *) NULL; -static int rl_history_search_len; -static int rl_history_search_pos; -static int rl_history_search_flags; +static int _rl_history_search_len; +/*static*/ int _rl_history_search_pos; +static int _rl_history_search_flags; static char *history_search_string; static int history_string_size; @@ -88,6 +88,13 @@ make_history_line_current (HIST_ENTRY *entry) if (rl_undo_list && rl_undo_list != (UNDO_LIST *)entry->data) rl_free_undo_list (); + /* This will need to free the saved undo list associated with the original + (pre-search) line buffer. */ + if (_rl_saved_line_for_history) + _rl_free_saved_history_line (); + + rl_maybe_save_line (); + /* Now we create a new undo list with a single insert for this text. WE DON'T CHANGE THE ORIGINAL HISTORY ENTRY UNDO LIST */ _rl_replace_text (entry->line, 0, rl_end); @@ -100,11 +107,6 @@ make_history_line_current (HIST_ENTRY *entry) current editing buffer. */ rl_free_undo_list (); #endif - - /* This will need to free the saved undo list associated with the original - (pre-search) line buffer. */ - if (_rl_saved_line_for_history) - _rl_free_saved_history_line (); } /* Search the history list for STRING starting at absolute history position @@ -193,6 +195,7 @@ noninc_dosearch (char *string, int dir, int flags) history_set_pos (oldpos); make_history_line_current (entry); + _rl_free_saved_history_line (); if (_rl_enable_active_region && ((flags & SF_PATTERN) == 0) && ind > 0 && ind < rl_end) { @@ -539,14 +542,14 @@ rl_history_search_internal (int count, int dir) while (count) { RL_CHECK_SIGNALS (); - ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir, 0, &newcol); + ret = noninc_search_from_pos (history_search_string, _rl_history_search_pos + dir, dir, 0, &newcol); if (ret == -1) break; /* Get the history entry we found. */ - rl_history_search_pos = ret; + _rl_history_search_pos = ret; oldpos = where_history (); - history_set_pos (rl_history_search_pos); + history_set_pos (_rl_history_search_pos); temp = current_history (); /* will never be NULL after successful search */ history_set_pos (oldpos); @@ -566,14 +569,14 @@ rl_history_search_internal (int count, int dir) in the line buffer after the search fails, change the #if 0 to #if 1 */ #if 0 - if (rl_point > rl_history_search_len) + if (rl_point > _rl_history_search_len) { - rl_point = rl_end = rl_history_search_len; + rl_point = rl_end = _rl_history_search_len; rl_line_buffer[rl_end] = '\0'; rl_mark = 0; } #else - rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */ + rl_point = _rl_history_search_len; /* rl_maybe_unsave_line changes it */ rl_mark = rl_end; #endif return 1; @@ -585,16 +588,17 @@ rl_history_search_internal (int count, int dir) /* Make sure we set the current history position to the last line found so we can do things like operate-and-get-next from here. This is similar to how incremental search behaves. */ - history_set_pos (rl_history_search_pos); /* XXX */ + rl_maybe_replace_line (); + history_set_pos (_rl_history_search_pos); /* XXX */ /* decide where to put rl_point -- need to change this for pattern search */ - if (rl_history_search_flags & ANCHORED_SEARCH) - rl_point = rl_history_search_len; /* easy case */ + if (_rl_history_search_flags & ANCHORED_SEARCH) + rl_point = _rl_history_search_len; /* easy case */ else { #if 0 t = strstr (rl_line_buffer, history_search_string); /* XXX */ - rl_point = t ? (int)(t - rl_line_buffer) + rl_history_search_len : rl_end; + rl_point = t ? (int)(t - rl_line_buffer) + _rl_history_search_len : rl_end; #else rl_point = (newcol >= 0) ? newcol : rl_end; #endif @@ -609,17 +613,17 @@ rl_history_search_reinit (int flags) { int sind; - rl_history_search_pos = where_history (); - rl_history_search_len = rl_point; - rl_history_search_flags = flags; + _rl_history_search_pos = where_history (); + _rl_history_search_len = rl_point; + _rl_history_search_flags = flags; prev_line_found = (char *)NULL; if (rl_point) { /* Allocate enough space for anchored and non-anchored searches */ - if (rl_history_search_len >= history_string_size - 2) + if (_rl_history_search_len >= history_string_size - 2) { - history_string_size = rl_history_search_len + 2; + history_string_size = _rl_history_search_len + 2; history_search_string = (char *)xrealloc (history_search_string, history_string_size); } sind = 0; @@ -644,7 +648,7 @@ rl_history_search_forward (int count, int ignore) rl_last_func != rl_history_search_backward) rl_history_search_reinit (ANCHORED_SEARCH); - if (rl_history_search_len == 0) + if (_rl_history_search_len == 0) return (rl_get_next_history (count, ignore)); return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1)); } @@ -662,7 +666,7 @@ rl_history_search_backward (int count, int ignore) rl_last_func != rl_history_search_backward) rl_history_search_reinit (ANCHORED_SEARCH); - if (rl_history_search_len == 0) + if (_rl_history_search_len == 0) return (rl_get_previous_history (count, ignore)); return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1)); } @@ -681,7 +685,7 @@ rl_history_substr_search_forward (int count, int ignore) rl_last_func != rl_history_substr_search_backward) rl_history_search_reinit (NON_ANCHORED_SEARCH); - if (rl_history_search_len == 0) + if (_rl_history_search_len == 0) return (rl_get_next_history (count, ignore)); return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1)); } @@ -699,7 +703,7 @@ rl_history_substr_search_backward (int count, int ignore) rl_last_func != rl_history_substr_search_backward) rl_history_search_reinit (NON_ANCHORED_SEARCH); - if (rl_history_search_len == 0) + if (_rl_history_search_len == 0) return (rl_get_previous_history (count, ignore)); return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1)); }