From 1b17e766659d93d1e7bd6633bf78132e1abb3568 Mon Sep 17 00:00:00 2001 From: Elena Zannoni Date: Sun, 9 Jul 2000 17:20:00 +0000 Subject: readline: 2000-07-09 Elena Zannoni * Import of readline 4.1. Locally modified files: Makefile.in, configure.in, configure (regenerated), config.h.in (regenerated), readline.h, rltty.c, shell.c signals.c. Locally added files: acconfig.h, config/*, config.h.bot, cross-build/*, doc/inc-hit.texinfo. New files: USAGE, rlprivate.h, rlshell.h, xmalloc.h. examples: 2000-07-09 Elena Zannoni * Import of readline 4.1. New files: excallback.c, rlfe.c. doc: 2000-07-09 Elena Zannoni * Import of readline 4.1. Regenerated inc-hist.texinfo as copy of hsuser.texinfo, for inclusion in the gdb manual. New file: rluserman.texinfo --- readline/search.c | 182 ++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 114 insertions(+), 68 deletions(-) (limited to 'readline/search.c') diff --git a/readline/search.c b/readline/search.c index 6c76e1a..112f807 100644 --- a/readline/search.c +++ b/readline/search.c @@ -8,7 +8,7 @@ The Library 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 1, or (at your option) + the Free Software Foundation; either version 2, or (at your option) any later version. The Library is distributed in the hope that it will be useful, but @@ -19,7 +19,7 @@ The GNU General Public License is often shipped with GNU software, and is generally kept in a file called COPYING or LICENSE. If you do not have a copy of the license, write to the Free Software Foundation, - 675 Mass Ave, Cambridge, MA 02139, USA. */ + 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY #if defined (HAVE_CONFIG_H) @@ -43,30 +43,51 @@ #include "readline.h" #include "history.h" +#include "rlprivate.h" +#include "xmalloc.h" + #ifdef abs # undef abs #endif #define abs(x) (((x) >= 0) ? (x) : -(x)) -extern char *xmalloc (), *xrealloc (); - -/* Variables imported from readline.c */ -extern int rl_point, rl_end, rl_line_buffer_len; -extern int rl_editing_mode; -extern char *rl_prompt; -extern char *rl_line_buffer; extern HIST_ENTRY *saved_line_for_history; -extern Function *rl_last_func; /* Functions imported from the rest of the library. */ -extern int _rl_free_history_entry (); -extern char *_rl_make_prompt_for_search (); -extern void rl_extend_line_buffer (); +extern int _rl_free_history_entry __P((HIST_ENTRY *)); static char *noninc_search_string = (char *) NULL; 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 char *history_search_string; +static int history_string_size; + +/* 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 (entry) + HIST_ENTRY *entry; +{ + int line_len; + + line_len = strlen (entry->line); + if (line_len >= rl_line_buffer_len) + rl_extend_line_buffer (line_len); + strcpy (rl_line_buffer, entry->line); + + rl_undo_list = (UNDO_LIST *)entry->data; + rl_end = line_len; + + if (saved_line_for_history) + _rl_free_history_entry (saved_line_for_history); + saved_line_for_history = (HIST_ENTRY *)NULL; +} + /* Search the history list for STRING starting at absolute history position POS. If STRING begins with `^', the search must match STRING at the beginning of a history line, otherwise a full substring match is performed @@ -102,7 +123,7 @@ noninc_dosearch (string, dir) char *string; int dir; { - int oldpos, pos, line_len; + int oldpos, pos; HIST_ENTRY *entry; if (string == 0 || *string == '\0' || noninc_history_pos < 0) @@ -132,19 +153,10 @@ noninc_dosearch (string, dir) #endif history_set_pos (oldpos); - line_len = strlen (entry->line); - if (line_len >= rl_line_buffer_len) - rl_extend_line_buffer (line_len); - strcpy (rl_line_buffer, entry->line); + make_history_line_current (entry); - rl_undo_list = (UNDO_LIST *)entry->data; - rl_end = strlen (rl_line_buffer); rl_point = 0; rl_clear_message (); - - if (saved_line_for_history) - _rl_free_history_entry (saved_line_for_history); - saved_line_for_history = (HIST_ENTRY *)NULL; } /* Search non-interactively through the history list. DIR < 0 means to @@ -235,8 +247,7 @@ noninc_search (dir, pchar) { /* We want to start the search from the current history position. */ noninc_history_pos = where_history (); - if (noninc_search_string) - free (noninc_search_string); + FREE (noninc_search_string); noninc_search_string = savestring (rl_line_buffer); } @@ -295,59 +306,84 @@ rl_noninc_reverse_search_again (count, key) } static int -rl_history_search_internal (count, direction) - int count, direction; +rl_history_search_internal (count, dir) + int count, dir; { - HIST_ENTRY *temp, *old_temp; - int line_len; + HIST_ENTRY *temp; + int ret, oldpos; maybe_save_line (); + temp = (HIST_ENTRY *)NULL; - temp = old_temp = (HIST_ENTRY *)NULL; + /* Search COUNT times through the history for a line whose prefix + matches history_search_string. When this loop finishes, TEMP, + if non-null, is the history line to copy into the line buffer. */ while (count) { - temp = (direction < 0) ? previous_history () : next_history (); - if (temp == 0) - break; - /* On an empty prefix, make this the same as previous-history. */ - if (rl_point == 0) - { - count--; - continue; - } - if (STREQN (rl_line_buffer, temp->line, rl_point)) - { - /* Don't find multiple instances of the same line. */ - if (prev_line_found && STREQ (prev_line_found, temp->line)) - continue; - if (direction < 0) - old_temp = temp; - prev_line_found = temp->line; - count--; - } + ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir); + if (ret == -1) + break; + + /* Get the history entry we found. */ + rl_history_search_pos = ret; + oldpos = where_history (); + history_set_pos (rl_history_search_pos); + temp = current_history (); + history_set_pos (oldpos); + + /* Don't find multiple instances of the same line. */ + if (prev_line_found && STREQ (prev_line_found, temp->line)) + continue; + prev_line_found = temp->line; + count--; } + /* If we didn't find anything at all, return. */ if (temp == 0) { - if (direction < 0 && old_temp) - temp = old_temp; - else - { - maybe_unsave_line (); - ding (); - return 1; - } + maybe_unsave_line (); + 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 + #if 1 */ +#if 0 + if (rl_point > rl_history_search_len) + { + rl_point = rl_end = rl_history_search_len; + rl_line_buffer[rl_end] = '\0'; + } +#else + rl_point = rl_history_search_len; /* maybe_unsave_line changes it */ +#endif + return 1; } - line_len = strlen (temp->line); - if (line_len >= rl_line_buffer_len) - rl_extend_line_buffer (line_len); - strcpy (rl_line_buffer, temp->line); - rl_undo_list = (UNDO_LIST *)temp->data; - rl_end = line_len; + /* Copy the line we found into the current line buffer. */ + make_history_line_current (temp); + + rl_point = rl_history_search_len; return 0; } +static void +rl_history_search_reinit () +{ + rl_history_search_pos = where_history (); + rl_history_search_len = rl_point; + prev_line_found = (char *)NULL; + if (rl_point) + { + if (rl_history_search_len >= history_string_size - 2) + { + history_string_size = rl_history_search_len + 2; + history_search_string = xrealloc (history_search_string, history_string_size); + } + history_search_string[0] = '^'; + strncpy (history_search_string + 1, rl_line_buffer, rl_point); + history_search_string[rl_point + 1] = '\0'; + } +} + /* Search forward in the history for the string of characters from the start of the line to rl_point. This is a non-incremental search. */ @@ -357,8 +393,13 @@ rl_history_search_forward (count, ignore) { if (count == 0) return (0); - if (rl_last_func != rl_history_search_forward) - prev_line_found = (char *)NULL; + + if (rl_last_func != rl_history_search_forward && + rl_last_func != rl_history_search_backward) + rl_history_search_reinit (); + + if (rl_history_search_len == 0) + return (rl_get_next_history (count, ignore)); return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1)); } @@ -371,7 +412,12 @@ rl_history_search_backward (count, ignore) { if (count == 0) return (0); - if (rl_last_func != rl_history_search_backward) - prev_line_found = (char *)NULL; + + if (rl_last_func != rl_history_search_forward && + rl_last_func != rl_history_search_backward) + rl_history_search_reinit (); + + if (rl_history_search_len == 0) + return (rl_get_previous_history (count, ignore)); return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1)); } -- cgit v1.1