diff options
Diffstat (limited to 'gnu/lib/libreadline/isearch.c')
-rw-r--r-- | gnu/lib/libreadline/isearch.c | 321 |
1 files changed, 158 insertions, 163 deletions
diff --git a/gnu/lib/libreadline/isearch.c b/gnu/lib/libreadline/isearch.c index 3222311..fdeb7cb 100644 --- a/gnu/lib/libreadline/isearch.c +++ b/gnu/lib/libreadline/isearch.c @@ -27,27 +27,27 @@ #include <stdio.h> -#if defined (__GNUC__) -# define alloca __builtin_alloca -#else -# if defined (sparc) || defined (HAVE_ALLOCA_H) -# include <alloca.h> -# endif -#endif - +#include "memalloc.h" #include "readline.h" #include "history.h" +#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) +#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0)) + +/* Variables imported from other files in the readline library. */ extern Keymap _rl_keymap; extern HIST_ENTRY *saved_line_for_history; extern int rl_line_buffer_len; extern int rl_point, rl_end; -extern char *rl_prompt, *rl_line_buffer; +extern char *rl_line_buffer; -/* Remove these declarations when we have a complete libgnu.a. */ extern char *xmalloc (), *xrealloc (); -static void rl_search_history (); +static int rl_search_history (); + +/* Last line found by the current incremental search, so we don't `find' + identical lines many times in a row. */ +static char *prev_line_found; /* Search backwards through the history looking for a string which is typed interactively. Start with the current line. */ @@ -55,7 +55,7 @@ rl_reverse_search_history (sign, key) int sign; int key; { - rl_search_history (-sign, key); + return (rl_search_history (-sign, key)); } /* Search forwards through the history looking for a string which is typed @@ -64,7 +64,7 @@ rl_forward_search_history (sign, key) int sign; int key; { - rl_search_history (sign, key); + return (rl_search_history (sign, key)); } /* Display the current state of the search in the echo-area. @@ -77,11 +77,9 @@ rl_display_search (search_string, reverse_p, where) char *search_string; int reverse_p, where; { - char *message = (char *)NULL; - - message = - (char *)xmalloc (1 + (search_string ? strlen (search_string) : 0) + 30); + char *message; + message = xmalloc (1 + (search_string ? strlen (search_string) : 0) + 30); *message = '\0'; #if defined (NOTDEF) @@ -109,7 +107,7 @@ rl_display_search (search_string, reverse_p, where) This is analogous to i-search. We start the search in the current line. DIRECTION is which direction to search; >= 0 means forward, < 0 means backwards. */ -static void +static int rl_search_history (direction, invoking_key) int direction; int invoking_key; @@ -124,7 +122,7 @@ rl_search_history (direction, invoking_key) int search_string_size; /* The list of lines to search through. */ - char **lines; + char **lines, *allocated_line = (char *)NULL; /* The length of LINES. */ int hlen; @@ -136,13 +134,13 @@ rl_search_history (direction, invoking_key) int orig_point = rl_point; int orig_line = where_history (); int last_found_line = orig_line; - int c, done = 0; + int c, done = 0, found, failed, sline_len; /* The line currently being searched. */ char *sline; /* Offset in that line. */ - int index; + int line_index; /* Non-zero if we are doing a reverse search. */ int reverse = (direction < 0); @@ -154,21 +152,18 @@ rl_search_history (direction, invoking_key) /* Allocate space for this many lines, +1 for the current input line, and remember those lines. */ - lines = (char **)alloca ((1 + (hlen = i)) * sizeof (char *)); + lines = (char **)xmalloc ((1 + (hlen = i)) * sizeof (char *)); for (i = 0; i < hlen; i++) lines[i] = hlist[i]->line; if (saved_line_for_history) lines[i] = saved_line_for_history->line; else - /* So I have to type it in this way instead. */ { - char *alloced_line; - - /* Keep that MIPS alloca () happy. */ - alloced_line = (char *)alloca (1 + strlen (rl_line_buffer)); - lines[i] = alloced_line; - strcpy (lines[i], &rl_line_buffer[0]); + /* Keep track of this so we can free it. */ + allocated_line = xmalloc (1 + strlen (rl_line_buffer)); + strcpy (allocated_line, &rl_line_buffer[0]); + lines[i] = allocated_line; } hlen++; @@ -177,39 +172,37 @@ rl_search_history (direction, invoking_key) i = orig_line; /* Initialize search parameters. */ - search_string = (char *)xmalloc (search_string_size = 128); + search_string = xmalloc (search_string_size = 128); *search_string = '\0'; search_string_index = 0; /* Normalize DIRECTION into 1 or -1. */ - if (direction >= 0) - direction = 1; - else - direction = -1; + direction = (direction >= 0) ? 1 : -1; rl_display_search (search_string, reverse, -1); sline = rl_line_buffer; - index = rl_point; + sline_len = strlen (sline); + line_index = rl_point; + found = failed = 0; while (!done) { + Function *f = (Function *)NULL; + + /* Read a key and decide how to proceed. */ c = rl_read_key (); /* Hack C to Do What I Mean. */ - { - Function *f = (Function *)NULL; - - if (_rl_keymap[c].type == ISFUNC) - { - f = _rl_keymap[c].function; + if (_rl_keymap[c].type == ISFUNC) + { + f = _rl_keymap[c].function; - if (f == rl_reverse_search_history) - c = reverse ? -1 : -2; - else if (f == rl_forward_search_history) - c = !reverse ? -1 : -2; - } - } + if (f == rl_reverse_search_history) + c = reverse ? -1 : -2; + else if (f == rl_forward_search_history) + c = !reverse ? -1 : -2; + } switch (c) { @@ -217,22 +210,36 @@ rl_search_history (direction, invoking_key) done = 1; continue; - /* case invoking_key: */ case -1: - goto search_again; + if (!search_string_index) + continue; + else + { + if (reverse) + --line_index; + else + { + if (line_index != sline_len) + ++line_index; + else + ding (); + } + } + break; /* switch directions */ case -2: direction = -direction; reverse = (direction < 0); - - goto do_search; + break; case CTRL ('G'): strcpy (rl_line_buffer, lines[orig_line]); rl_point = orig_point; rl_end = strlen (rl_line_buffer); rl_clear_message (); + free (allocated_line); + free (lines); return; default: @@ -244,134 +251,122 @@ rl_search_history (direction, invoking_key) } else { + /* Add character to search string and continue search. */ if (search_string_index + 2 >= search_string_size) - search_string = (char *)xrealloc - (search_string, (search_string_size += 128)); + { + search_string_size += 128; + search_string = xrealloc (search_string, search_string_size); + } search_string[search_string_index++] = c; search_string[search_string_index] = '\0'; - goto do_search; + break; + } + } - search_again: + found = failed = 0; + while (1) + { + int limit = sline_len - search_string_index + 1; - if (!search_string_index) - continue; + /* Search the current line. */ + while (reverse ? (line_index >= 0) : (line_index < limit)) + { + if (STREQN(search_string, sline + line_index, search_string_index)) + { + found++; + break; + } else + line_index += reverse ? -1 : 1; + } + if (found) + break; + + /* Move to the next line, but skip new copies of the line + we just found and lines shorter than the string we're + searching for. */ + do + { + /* Move to the next line. */ + i += direction; + + /* At limit for direction? */ + if ((reverse && i < 0) || (!reverse && i == hlen)) { - if (reverse) - --index; - else - if (index != strlen (sline)) - ++index; - else - ding (); + failed++; + break; } - do_search: - while (1) - { - if (reverse) - { - while (index >= 0) - if (strncmp - (search_string, sline + index, search_string_index) - == 0) - goto string_found; - else - index--; - } - else - { - register int limit = - (strlen (sline) - search_string_index) + 1; - - while (index < limit) - { - if (strncmp (search_string, - sline + index, - search_string_index) == 0) - goto string_found; - index++; - } - } - - next_line: - i += direction; - - /* At limit for direction? */ - if ((reverse && i < 0) || - (!reverse && i == hlen)) - goto search_failed; - - sline = lines[i]; - if (reverse) - index = strlen (sline); - else - index = 0; + /* We will need these later. */ + sline = lines[i]; + sline_len = strlen (sline); + } + while ((prev_line_found && STREQ (prev_line_found, lines[i])) || + (search_string_index > sline_len)); - /* If the search string is longer than the current - line, no match. */ - if (search_string_index > (int)strlen (sline)) - goto next_line; + if (failed) + break; - /* Start actually searching. */ - if (reverse) - index -= search_string_index; - } + /* Now set up the line for searching... */ + if (reverse) + line_index = sline_len - search_string_index; + else + line_index = 0; + } - search_failed: - /* We cannot find the search string. Ding the bell. */ - ding (); - i = last_found_line; - break; + if (failed) + { + /* We cannot find the search string. Ding the bell. */ + ding (); + i = last_found_line; + break; + } - string_found: - /* We have found the search string. Just display it. But don't - actually move there in the history list until the user accepts - the location. */ - { - int line_len; - - line_len = strlen (lines[i]); - - if (line_len >= rl_line_buffer_len) - rl_extend_line_buffer (line_len); - - strcpy (rl_line_buffer, lines[i]); - rl_point = index; - rl_end = line_len; - last_found_line = i; - rl_display_search - (search_string, reverse, (i == orig_line) ? -1 : i); - } - } + /* We have found the search string. Just display it. But don't + actually move there in the history list until the user accepts + the location. */ + if (found) + { + int line_len; + + prev_line_found = lines[i]; + line_len = strlen (lines[i]); + + if (line_len >= rl_line_buffer_len) + rl_extend_line_buffer (line_len); + + strcpy (rl_line_buffer, lines[i]); + rl_point = line_index; + rl_end = line_len; + last_found_line = i; + rl_display_search (search_string, reverse, (i == orig_line) ? -1 : i); } } /* The searching is over. The user may have found the string that she was looking for, or else she may have exited a failing search. If - INDEX is -1, then that shows that the string searched for was not - found. We use this to determine where to place rl_point. */ - { - int now = last_found_line; - - /* First put back the original state. */ - strcpy (rl_line_buffer, lines[orig_line]); - - /* Free the search string. */ - free (search_string); - - if (now < orig_line) - rl_get_previous_history (orig_line - now); - else - rl_get_next_history (now - orig_line); - - /* If the index of the "matched" string is less than zero, then the - final search string was never matched, so put point somewhere - reasonable. */ - if (index < 0) - index = strlen (rl_line_buffer); - - rl_point = index; - rl_clear_message (); - } + LINE_INDEX is -1, then that shows that the string searched for was + not found. We use this to determine where to place rl_point. */ + + /* First put back the original state. */ + strcpy (rl_line_buffer, lines[orig_line]); + + /* Free the search string. */ + free (search_string); + + if (last_found_line < orig_line) + rl_get_previous_history (orig_line - last_found_line); + else + rl_get_next_history (last_found_line - orig_line); + + /* If the string was not found, put point at the end of the line. */ + if (line_index < 0) + line_index = strlen (rl_line_buffer); + rl_point = line_index; + rl_clear_message (); + + free (allocated_line); + free (lines); + + return 0; } |