changes to non-incremental search implementation for consistency with incremental search; fix for readline unsetting rl_eof_found; minor man page updates

This commit is contained in:
Chet Ramey
2024-11-04 17:51:50 -05:00
parent bf093e31ae
commit 0075715b29
7 changed files with 109 additions and 101 deletions
+31
View File
@@ -10566,3 +10566,34 @@ builtins/exec.def
Makefile.in
- LIBRARY_SOURCE: add back in to tags targets, add definition
Suggestion from Mike Jonkmans <bashbug@jonkmans.nl>
10/31
-----
lib/readline/search.c
- make_history_line_current: change to use the same strategy to move
to a history line as incremental search: one or more calls to
rl_get_{next,previous}_history
- dispose_saved_search_line: remove
- noninc_dosearch: no longer need to call _rl_unsave_saved_search_line
or dispose_saved_search_line; use new calling convention for
make_history_line_current
- _rl_nsearch_init: don't need to call _rl_maybe_replace_line, wait
until we move to the history line
- _rl_nsearch_dosearch: free the undo list unconditionally, since we
are committed to using the contents of rl_line_buffer as the search
string
- _rl_nsearch_dosearch: if we abort because of no search string, call
_rl_unsave_saved_search_line and let the caller clean up
- _rl_nsearch_dosearch: if the search fails, reset rl_point to the
saved point, since we will be restoring the old line
- rl_history_search_internal: don't bother to save and restore the
search line, since we don't use rl_line_buffer for anything
- rl_history_search_internal: use new calling convention for
make_history_line_current
- all these changes unify the incremental and non-incremental search
implementations
lib/readline/readline.c
- rl_initialize: reset rl_eof_found to 0 at the same time we reset
the EOF state
Report and fix from Andrew Burgess <aburgess@redhat.com> (GDB)
+3 -2
View File
@@ -2274,7 +2274,8 @@ is not used to search for the resultant filename.
If set to an integer corresponding to a valid file descriptor, \fBbash\fP
will write the trace output generated when
.Q "set \-x"
is enabled to that file descriptor.
is enabled to that file descriptor,
instead of the standard error.
The file descriptor is closed when
.SM
.B BASH_XTRACEFD
@@ -2587,7 +2588,7 @@ for word splitting after expansion and to
split lines into words with the
.B read
builtin command.
Word splitting is described above under
Word splitting is described below under
.SM
.BR EXPANSION .
The default value is
+3 -2
View File
@@ -5964,7 +5964,7 @@ An error message will be written to the standard error, and a non-interactive
shell will exit.
@item -v
Print shell input lines as they are read.
Print shell input lines to standard error as they are read.
@item -x
Print a trace of simple commands, @code{for} commands, @code{case}
@@ -6815,7 +6815,8 @@ Bash (e.g., 5.2.37(3)-release).
@item BASH_XTRACEFD
If set to an integer corresponding to a valid file descriptor, Bash
will write the trace output generated when @samp{set -x}
is enabled to that file descriptor.
is enabled to that file descriptor
instead of the standard error.
This allows tracing output to be separated from diagnostic and error
messages.
The file descriptor is closed when @code{BASH_XTRACEFD} is unset or assigned
+1 -3
View File
@@ -188,9 +188,7 @@ distclean: clean
mostlyclean: clean
maintainer-clean: clean
$(RM) $(CREATED_DOCS)
$(RM) $(INTERMEDIATE_OBJ)
maintainer-clean: distclean
install:
@echo "This documentation should not be installed."
+1 -3
View File
@@ -188,9 +188,7 @@ distclean: clean
mostlyclean: clean
maintainer-clean: clean
$(RM) $(CREATED_DOCS)
$(RM) $(INTERMEDIATE_OBJ)
maintainer-clean: distclean
$(RM) Makefile
install:
+1
View File
@@ -1222,6 +1222,7 @@ rl_initialize (void)
/* We aren't done yet. We haven't even gotten started yet! */
rl_done = 0;
rl_eof_found = 0;
RL_UNSETSTATE(RL_STATE_DONE|RL_STATE_TIMEOUT|RL_STATE_EOF);
/* Tell the history routines what is going on. */
+69 -91
View File
@@ -69,7 +69,7 @@ static int _rl_history_search_flags;
static char *history_search_string;
static size_t history_string_size;
static void make_history_line_current (HIST_ENTRY *);
static void make_history_line_current (int, int);
static int noninc_search_from_pos (char *, int, int, int, int *);
static int noninc_dosearch (char *, int, int);
static int noninc_search (int, int);
@@ -96,43 +96,21 @@ _rl_unsave_saved_search_line (void)
_rl_saved_line_for_search = (HIST_ENTRY *)NULL;
}
/* We're going to replace the undo list with the one created by inserting
the matching line we found, so we want to free rl_undo_list if it's not
from a history entry. We assume the undo list does not come from a
history entry if we are at the end of the history, entering a new line.
The call to _rl_maybe_replace_line() has already ensured that any undo
list pointing to a history entry has already been saved back to the
history and set rl_undo_list to NULL. */
/* Make the data from the history entry at offset NEWPOS be the contents of
the current line, which is at offset CURPOS. We use the same strategy
as incremental search.
This doesn't do anything with rl_point beyond bounds checking; the caller
must set it to any desired value. */
static void
dispose_saved_search_line (void)
make_history_line_current (int curpos, int newpos)
{
UNDO_LIST *xlist;
if (newpos < curpos)
rl_get_previous_history (curpos - newpos, 0);
else
rl_get_next_history (newpos - curpos, 0);
if (_hs_at_end_of_history () == 0)
_rl_unsave_saved_search_line ();
else if (_rl_saved_line_for_search)
{
xlist = _rl_saved_line_for_search ? (UNDO_LIST *)_rl_saved_line_for_search->data : 0;
if (xlist)
_rl_free_undo_list (xlist);
_rl_saved_line_for_search->data = 0;
_rl_free_saved_search_line ();
}
}
/* Make the data from the history entry ENTRY be the contents of the
current line. This doesn't do anything with rl_point; the caller
must set it. */
static void
make_history_line_current (HIST_ENTRY *entry)
{
/* 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_undo_list = 0; /* XXX */
_rl_replace_text (entry->line, 0, rl_end);
_rl_fix_point (1);
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
/* POSIX.2 says that the `U' command doesn't affect the copy of any
@@ -195,12 +173,12 @@ noninc_search_from_pos (char *string, int pos, int dir, int flags, int *ncp)
/* Search for a line in the history containing STRING. If DIR is < 0, the
search is backwards through previous entries, else through subsequent
entries. Returns 1 if the search was successful, 0 otherwise. */
entries. Leaves noninc_history_pos set to the offset of the found history
entry, if successful. Returns 1 if the search was successful, 0 otherwise. */
static int
noninc_dosearch (char *string, int dir, int flags)
{
int oldpos, pos, ind;
HIST_ENTRY *entry;
if (string == 0 || *string == '\0' || noninc_history_pos < 0)
{
@@ -212,29 +190,20 @@ noninc_dosearch (char *string, int dir, int flags)
if (pos == -1)
{
/* Search failed, current history position unchanged. */
_rl_unsave_saved_search_line ();
rl_clear_message ();
rl_point = 0;
rl_point = 0; /* caller will fix it up if needed */
rl_ding ();
return 0;
}
noninc_history_pos = pos;
/* We're committed to making the line we found the current contents of
rl_line_buffer. We can dispose of _rl_saved_line_for_search. */
dispose_saved_search_line ();
oldpos = where_history ();
history_set_pos (noninc_history_pos);
entry = current_history (); /* will never be NULL after successful search */
#if defined (VI_MODE)
if (rl_editing_mode != vi_mode)
#endif
history_set_pos (oldpos);
noninc_history_pos = pos;
make_history_line_current (oldpos, noninc_history_pos);
make_history_line_current (entry);
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
history_set_pos (noninc_history_pos); /* XXX */
#endif
if (_rl_enable_active_region && ((flags & SF_PATTERN) == 0) && ind >= 0 && ind < rl_end)
{
@@ -271,10 +240,6 @@ _rl_nsearch_init (int dir, int pchar)
cxt->direction = dir;
cxt->history_pos = cxt->save_line;
/* If the current line has changed, put it back into the history if necessary
and clear the undo list. */
_rl_maybe_replace_line (1);
_rl_saved_line_for_search = _rl_alloc_saved_line ();
/* Clear the undo list, since reading the search string should create its
@@ -405,7 +370,7 @@ _rl_nsearch_dispatch (_rl_search_cxt *cxt, int c)
}
else
_rl_insert_char (1, c);
break;
break;
default:
#if defined (HANDLE_MULTIBYTE)
@@ -422,15 +387,26 @@ _rl_nsearch_dispatch (_rl_search_cxt *cxt, int c)
return 1;
}
/* Perform one search according to CXT, using NONINC_SEARCH_STRING. Return
-1 if the search should be aborted, any other value means to clean up
using _rl_nsearch_cleanup (). Returns 1 if the search was successful,
0 otherwise. */
/* Perform one search according to CXT, using NONINC_SEARCH_STRING, which
we determine, via a call to noninc_dosearch().
Return -1 if the search should be aborted, any other value means to clean
up using _rl_nsearch_cleanup ().
If the search is not successful, we will restore the original line, so
make sure we restore rl_point.
Returns 1 if the search was successful, 0 otherwise. */
static int
_rl_nsearch_dosearch (_rl_search_cxt *cxt)
{
int r;
rl_mark = cxt->save_mark;
/* We're committed to using the contents of rl_line_buffer as the search
string, whatever they are. We no longer need the undo list generated
by reading the search string. The old undo list will be restored
by _rl_unsave_saved_search_line(). */
rl_free_undo_list ();
/* If rl_point == 0, we want to re-use the previous search string and
start from the saved history position. If there's no previous search
string, punt. */
@@ -438,7 +414,7 @@ _rl_nsearch_dosearch (_rl_search_cxt *cxt)
{
if (noninc_search_string == 0)
{
_rl_free_saved_search_line ();
_rl_unsave_saved_search_line (); /* XXX */
rl_ding ();
if (cxt->sflags & SF_FREEPMT)
rl_restore_prompt ();
@@ -457,11 +433,7 @@ _rl_nsearch_dosearch (_rl_search_cxt *cxt)
/* We don't want the subsequent undo list generated by the search
matching a history line to include the contents of the search string,
so we need to clear rl_line_buffer here. If we don't want that,
change the #if 1 to an #if 0 below. We clear the undo list
generated by reading the search string. (If the search fails, the
old undo list will be restored by _rl_unsave_line.) */
rl_free_undo_list ();
change the #if 1 to an #if 0 below. */
#if 1
rl_line_buffer[rl_point = rl_end = 0] = '\0';
#endif
@@ -470,7 +442,15 @@ _rl_nsearch_dosearch (_rl_search_cxt *cxt)
if (cxt->sflags & SF_FREEPMT)
rl_restore_prompt ();
cxt->sflags &= ~SF_FREEPMT;
return (noninc_dosearch (noninc_search_string, cxt->direction, cxt->sflags&SF_PATTERN));
/* We are finished using the line buffer to read the search string, restore
the original contents without doing a redisplay. */
_rl_unsave_saved_search_line (); /* XXX */
r = noninc_dosearch (noninc_search_string, cxt->direction, cxt->sflags&SF_PATTERN);
if (r == 0) /* search failed, we will restore the original line */
rl_point = cxt->save_point;
return r;
}
/* Search non-interactively through the history list. DIR < 0 means to
@@ -537,19 +517,21 @@ rl_noninc_reverse_search (int count, int key)
int
rl_noninc_forward_search_again (int count, int key)
{
int r;
int r, flags;
if (!noninc_search_string)
{
rl_ding ();
return (1);
}
flags = 0;
#if defined (VI_MODE)
if (VI_COMMAND_MODE() && key == 'N')
r = noninc_dosearch (noninc_search_string, 1, SF_PATTERN);
else
flags = SF_PATTERN;
#endif
r = noninc_dosearch (noninc_search_string, 1, 0);
r = noninc_dosearch (noninc_search_string, 1, flags);
return (r != 1);
}
@@ -559,19 +541,21 @@ rl_noninc_forward_search_again (int count, int key)
int
rl_noninc_reverse_search_again (int count, int key)
{
int r;
int r, flags;
if (!noninc_search_string)
{
rl_ding ();
return (1);
}
flags = 0;
#if defined (VI_MODE)
if (VI_COMMAND_MODE() && key == 'n')
r = noninc_dosearch (noninc_search_string, -1, SF_PATTERN);
else
flags = SF_PATTERN;
#endif
r = noninc_dosearch (noninc_search_string, -1, 0);
r = noninc_dosearch (noninc_search_string, -1, flags);
return (r != 1);
}
@@ -596,7 +580,11 @@ _rl_nsearch_callback (_rl_search_cxt *cxt)
return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
}
#endif
/* The strategy is to find the line to move to (COUNT occurrences of
HISTORY_SEARCH_STRING in direction DIR), then use the same mechanism that
incremental search uses to move to it. That's wrapped up in
make_history_line_current(). */
static int
rl_history_search_internal (int count, int dir)
{
@@ -604,15 +592,9 @@ rl_history_search_internal (int count, int dir)
int ret, oldpos, newcol;
char *t;
/* If the current line has changed, put it back into the history if necessary
and clear the undo list. */
_rl_maybe_replace_line (1);
_rl_saved_line_for_search = _rl_alloc_saved_line ();
oldpos = where_history (); /* where are we now? */
temp = (HIST_ENTRY *)NULL;
oldpos = where_history ();
/* Search COUNT times through the history for a line matching
history_search_string. If history_search_string[0] == '^', the
line must match from the start; otherwise any substring can match.
@@ -629,6 +611,7 @@ rl_history_search_internal (int count, int dir)
_rl_history_search_pos = ret;
history_set_pos (_rl_history_search_pos);
temp = current_history (); /* will never be NULL after successful search */
history_set_pos (oldpos);
/* Don't find multiple instances of the same line. */
if (prev_line_found && STREQ (prev_line_found, temp->line))
@@ -640,7 +623,6 @@ rl_history_search_internal (int count, int dir)
/* If we didn't find anything at all, return without changing history offset */
if (temp == 0)
{
_rl_unsave_saved_search_line ();
rl_ding ();
/* If you don't want the saved history line (last match) to show up
in the line buffer after the search fails, change the #if 0 to
@@ -654,17 +636,13 @@ rl_history_search_internal (int count, int dir)
}
#else
rl_point = _rl_history_search_len; /* _rl_unsave_line changes it */
rl_mark = rl_end;
rl_mark = rl_end; /* XXX */
#endif
return 1;
}
/* We're committed to making the line we found the current contents of
rl_line_buffer. We can dispose of _rl_saved_line_for_search. */
dispose_saved_search_line ();
/* Copy the line we found into the current line buffer. */
make_history_line_current (temp);
make_history_line_current (oldpos, _rl_history_search_pos);
/* decide where to put rl_point -- need to change this for pattern search */
if (_rl_history_search_flags & ANCHORED_SEARCH)