xref: /dflybsd-src/contrib/gdb-7/readline/search.c (revision 3b2c2bfb0d670ddd42eaae9cb611af46485a31be)
16b445a62SJohn Marino /* search.c - code for non-incremental searching in emacs and vi modes. */
26b445a62SJohn Marino 
36b445a62SJohn Marino /* Copyright (C) 1992-2009 Free Software Foundation, Inc.
46b445a62SJohn Marino 
56b445a62SJohn Marino    This file is part of the GNU Readline Library (Readline), a library
66b445a62SJohn Marino    for reading lines of text with interactive input and history editing.
76b445a62SJohn Marino 
86b445a62SJohn Marino    Readline is free software: you can redistribute it and/or modify
96b445a62SJohn Marino    it under the terms of the GNU General Public License as published by
106b445a62SJohn Marino    the Free Software Foundation, either version 3 of the License, or
116b445a62SJohn Marino    (at your option) any later version.
126b445a62SJohn Marino 
136b445a62SJohn Marino    Readline is distributed in the hope that it will be useful,
146b445a62SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
156b445a62SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
166b445a62SJohn Marino    GNU General Public License for more details.
176b445a62SJohn Marino 
186b445a62SJohn Marino    You should have received a copy of the GNU General Public License
196b445a62SJohn Marino    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
206b445a62SJohn Marino */
216b445a62SJohn Marino 
226b445a62SJohn Marino #define READLINE_LIBRARY
236b445a62SJohn Marino 
246b445a62SJohn Marino #if defined (HAVE_CONFIG_H)
256b445a62SJohn Marino #  include <config.h>
266b445a62SJohn Marino #endif
276b445a62SJohn Marino 
286b445a62SJohn Marino #include <sys/types.h>
296b445a62SJohn Marino #include <stdio.h>
306b445a62SJohn Marino 
316b445a62SJohn Marino #if defined (HAVE_UNISTD_H)
326b445a62SJohn Marino #  include <unistd.h>
336b445a62SJohn Marino #endif
346b445a62SJohn Marino 
356b445a62SJohn Marino #if defined (HAVE_STDLIB_H)
366b445a62SJohn Marino #  include <stdlib.h>
376b445a62SJohn Marino #else
386b445a62SJohn Marino #  include "ansi_stdlib.h"
396b445a62SJohn Marino #endif
406b445a62SJohn Marino 
416b445a62SJohn Marino #include "rldefs.h"
426b445a62SJohn Marino #include "rlmbutil.h"
436b445a62SJohn Marino 
446b445a62SJohn Marino #include "readline.h"
456b445a62SJohn Marino #include "history.h"
466b445a62SJohn Marino 
476b445a62SJohn Marino #include "rlprivate.h"
486b445a62SJohn Marino #include "xmalloc.h"
496b445a62SJohn Marino 
506b445a62SJohn Marino #ifdef abs
516b445a62SJohn Marino #  undef abs
526b445a62SJohn Marino #endif
536b445a62SJohn Marino #define abs(x)		(((x) >= 0) ? (x) : -(x))
546b445a62SJohn Marino 
556b445a62SJohn Marino _rl_search_cxt *_rl_nscxt = 0;
566b445a62SJohn Marino 
576b445a62SJohn Marino extern HIST_ENTRY *_rl_saved_line_for_history;
586b445a62SJohn Marino 
596b445a62SJohn Marino /* Functions imported from the rest of the library. */
606b445a62SJohn Marino extern int _rl_free_history_entry PARAMS((HIST_ENTRY *));
616b445a62SJohn Marino 
626b445a62SJohn Marino static char *noninc_search_string = (char *) NULL;
636b445a62SJohn Marino static int noninc_history_pos;
646b445a62SJohn Marino 
656b445a62SJohn Marino static char *prev_line_found = (char *) NULL;
666b445a62SJohn Marino 
676b445a62SJohn Marino static int rl_history_search_len;
686b445a62SJohn Marino static int rl_history_search_pos;
696b445a62SJohn Marino static char *history_search_string;
706b445a62SJohn Marino static int history_string_size;
716b445a62SJohn Marino 
726b445a62SJohn Marino static void make_history_line_current PARAMS((HIST_ENTRY *));
736b445a62SJohn Marino static int noninc_search_from_pos PARAMS((char *, int, int));
746b445a62SJohn Marino static int noninc_dosearch PARAMS((char *, int));
756b445a62SJohn Marino static int noninc_search PARAMS((int, int));
766b445a62SJohn Marino static int rl_history_search_internal PARAMS((int, int));
776b445a62SJohn Marino static void rl_history_search_reinit PARAMS((void));
786b445a62SJohn Marino 
796b445a62SJohn Marino static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
806b445a62SJohn Marino static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
816b445a62SJohn Marino static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
826b445a62SJohn Marino static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
836b445a62SJohn Marino 
846b445a62SJohn Marino /* Make the data from the history entry ENTRY be the contents of the
856b445a62SJohn Marino    current line.  This doesn't do anything with rl_point; the caller
866b445a62SJohn Marino    must set it. */
876b445a62SJohn Marino static void
make_history_line_current(entry)886b445a62SJohn Marino make_history_line_current (entry)
896b445a62SJohn Marino      HIST_ENTRY *entry;
906b445a62SJohn Marino {
916b445a62SJohn Marino   _rl_replace_text (entry->line, 0, rl_end);
926b445a62SJohn Marino   _rl_fix_point (1);
936b445a62SJohn Marino #if defined (VI_MODE)
946b445a62SJohn Marino   if (rl_editing_mode == vi_mode)
956b445a62SJohn Marino     /* POSIX.2 says that the `U' command doesn't affect the copy of any
966b445a62SJohn Marino        command lines to the edit line.  We're going to implement that by
976b445a62SJohn Marino        making the undo list start after the matching line is copied to the
986b445a62SJohn Marino        current editing buffer. */
996b445a62SJohn Marino     rl_free_undo_list ();
1006b445a62SJohn Marino #endif
1016b445a62SJohn Marino 
1026b445a62SJohn Marino   if (_rl_saved_line_for_history)
1036b445a62SJohn Marino     _rl_free_history_entry (_rl_saved_line_for_history);
1046b445a62SJohn Marino   _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
1056b445a62SJohn Marino }
1066b445a62SJohn Marino 
1076b445a62SJohn Marino /* Search the history list for STRING starting at absolute history position
1086b445a62SJohn Marino    POS.  If STRING begins with `^', the search must match STRING at the
1096b445a62SJohn Marino    beginning of a history line, otherwise a full substring match is performed
1106b445a62SJohn Marino    for STRING.  DIR < 0 means to search backwards through the history list,
1116b445a62SJohn Marino    DIR >= 0 means to search forward. */
1126b445a62SJohn Marino static int
noninc_search_from_pos(string,pos,dir)1136b445a62SJohn Marino noninc_search_from_pos (string, pos, dir)
1146b445a62SJohn Marino      char *string;
1156b445a62SJohn Marino      int pos, dir;
1166b445a62SJohn Marino {
1176b445a62SJohn Marino   int ret, old;
1186b445a62SJohn Marino 
1196b445a62SJohn Marino   if (pos < 0)
1206b445a62SJohn Marino     return -1;
1216b445a62SJohn Marino 
1226b445a62SJohn Marino   old = where_history ();
1236b445a62SJohn Marino   if (history_set_pos (pos) == 0)
1246b445a62SJohn Marino     return -1;
1256b445a62SJohn Marino 
1266b445a62SJohn Marino   RL_SETSTATE(RL_STATE_SEARCH);
1276b445a62SJohn Marino   if (*string == '^')
1286b445a62SJohn Marino     ret = history_search_prefix (string + 1, dir);
1296b445a62SJohn Marino   else
1306b445a62SJohn Marino     ret = history_search (string, dir);
1316b445a62SJohn Marino   RL_UNSETSTATE(RL_STATE_SEARCH);
1326b445a62SJohn Marino 
1336b445a62SJohn Marino   if (ret != -1)
1346b445a62SJohn Marino     ret = where_history ();
1356b445a62SJohn Marino 
1366b445a62SJohn Marino   history_set_pos (old);
1376b445a62SJohn Marino   return (ret);
1386b445a62SJohn Marino }
1396b445a62SJohn Marino 
1406b445a62SJohn Marino /* Search for a line in the history containing STRING.  If DIR is < 0, the
1416b445a62SJohn Marino    search is backwards through previous entries, else through subsequent
1426b445a62SJohn Marino    entries.  Returns 1 if the search was successful, 0 otherwise. */
1436b445a62SJohn Marino static int
noninc_dosearch(string,dir)1446b445a62SJohn Marino noninc_dosearch (string, dir)
1456b445a62SJohn Marino      char *string;
1466b445a62SJohn Marino      int dir;
1476b445a62SJohn Marino {
1486b445a62SJohn Marino   int oldpos, pos;
1496b445a62SJohn Marino   HIST_ENTRY *entry;
1506b445a62SJohn Marino 
1516b445a62SJohn Marino   if (string == 0 || *string == '\0' || noninc_history_pos < 0)
1526b445a62SJohn Marino     {
1536b445a62SJohn Marino       rl_ding ();
1546b445a62SJohn Marino       return 0;
1556b445a62SJohn Marino     }
1566b445a62SJohn Marino 
1576b445a62SJohn Marino   pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
1586b445a62SJohn Marino   if (pos == -1)
1596b445a62SJohn Marino     {
1606b445a62SJohn Marino       /* Search failed, current history position unchanged. */
1616b445a62SJohn Marino       rl_maybe_unsave_line ();
1626b445a62SJohn Marino       rl_clear_message ();
1636b445a62SJohn Marino       rl_point = 0;
1646b445a62SJohn Marino       rl_ding ();
1656b445a62SJohn Marino       return 0;
1666b445a62SJohn Marino     }
1676b445a62SJohn Marino 
1686b445a62SJohn Marino   noninc_history_pos = pos;
1696b445a62SJohn Marino 
1706b445a62SJohn Marino   oldpos = where_history ();
1716b445a62SJohn Marino   history_set_pos (noninc_history_pos);
1726b445a62SJohn Marino   entry = current_history ();
1736b445a62SJohn Marino #if defined (VI_MODE)
1746b445a62SJohn Marino   if (rl_editing_mode != vi_mode)
1756b445a62SJohn Marino #endif
1766b445a62SJohn Marino     history_set_pos (oldpos);
1776b445a62SJohn Marino 
1786b445a62SJohn Marino   make_history_line_current (entry);
1796b445a62SJohn Marino 
1806b445a62SJohn Marino   rl_point = 0;
1816b445a62SJohn Marino   rl_mark = rl_end;
1826b445a62SJohn Marino 
1836b445a62SJohn Marino   rl_clear_message ();
1846b445a62SJohn Marino   return 1;
1856b445a62SJohn Marino }
1866b445a62SJohn Marino 
1876b445a62SJohn Marino static _rl_search_cxt *
_rl_nsearch_init(dir,pchar)1886b445a62SJohn Marino _rl_nsearch_init (dir, pchar)
1896b445a62SJohn Marino      int dir, pchar;
1906b445a62SJohn Marino {
1916b445a62SJohn Marino   _rl_search_cxt *cxt;
1926b445a62SJohn Marino   char *p;
1936b445a62SJohn Marino 
1946b445a62SJohn Marino   cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
1956b445a62SJohn Marino   if (dir < 0)
1966b445a62SJohn Marino     cxt->sflags |= SF_REVERSE;		/* not strictly needed */
1976b445a62SJohn Marino 
1986b445a62SJohn Marino   cxt->direction = dir;
1996b445a62SJohn Marino   cxt->history_pos = cxt->save_line;
2006b445a62SJohn Marino 
2016b445a62SJohn Marino   rl_maybe_save_line ();
2026b445a62SJohn Marino 
2036b445a62SJohn Marino   /* Clear the undo list, since reading the search string should create its
2046b445a62SJohn Marino      own undo list, and the whole list will end up being freed when we
2056b445a62SJohn Marino      finish reading the search string. */
2066b445a62SJohn Marino   rl_undo_list = 0;
2076b445a62SJohn Marino 
2086b445a62SJohn Marino   /* Use the line buffer to read the search string. */
2096b445a62SJohn Marino   rl_line_buffer[0] = 0;
2106b445a62SJohn Marino   rl_end = rl_point = 0;
2116b445a62SJohn Marino 
2126b445a62SJohn Marino   p = _rl_make_prompt_for_search (pchar ? pchar : ':');
213*3b2c2bfbSSascha Wildner   rl_message ("%s", p);
2146b445a62SJohn Marino   xfree (p);
2156b445a62SJohn Marino 
2166b445a62SJohn Marino   RL_SETSTATE(RL_STATE_NSEARCH);
2176b445a62SJohn Marino 
2186b445a62SJohn Marino   _rl_nscxt = cxt;
2196b445a62SJohn Marino 
2206b445a62SJohn Marino   return cxt;
2216b445a62SJohn Marino }
2226b445a62SJohn Marino 
2236b445a62SJohn Marino static int
_rl_nsearch_cleanup(cxt,r)2246b445a62SJohn Marino _rl_nsearch_cleanup (cxt, r)
2256b445a62SJohn Marino      _rl_search_cxt *cxt;
2266b445a62SJohn Marino      int r;
2276b445a62SJohn Marino {
2286b445a62SJohn Marino   _rl_scxt_dispose (cxt, 0);
2296b445a62SJohn Marino   _rl_nscxt = 0;
2306b445a62SJohn Marino 
2316b445a62SJohn Marino   RL_UNSETSTATE(RL_STATE_NSEARCH);
2326b445a62SJohn Marino 
2336b445a62SJohn Marino   return (r != 1);
2346b445a62SJohn Marino }
2356b445a62SJohn Marino 
2366b445a62SJohn Marino static void
_rl_nsearch_abort(cxt)2376b445a62SJohn Marino _rl_nsearch_abort (cxt)
2386b445a62SJohn Marino      _rl_search_cxt *cxt;
2396b445a62SJohn Marino {
2406b445a62SJohn Marino   rl_maybe_unsave_line ();
2416b445a62SJohn Marino   rl_clear_message ();
2426b445a62SJohn Marino   rl_point = cxt->save_point;
2436b445a62SJohn Marino   rl_mark = cxt->save_mark;
2446b445a62SJohn Marino   rl_restore_prompt ();
2456b445a62SJohn Marino 
2466b445a62SJohn Marino   RL_UNSETSTATE (RL_STATE_NSEARCH);
2476b445a62SJohn Marino }
2486b445a62SJohn Marino 
2496b445a62SJohn Marino /* Process just-read character C according to search context CXT.  Return -1
2506b445a62SJohn Marino    if the caller should abort the search, 0 if we should break out of the
2516b445a62SJohn Marino    loop, and 1 if we should continue to read characters. */
2526b445a62SJohn Marino static int
_rl_nsearch_dispatch(cxt,c)2536b445a62SJohn Marino _rl_nsearch_dispatch (cxt, c)
2546b445a62SJohn Marino      _rl_search_cxt *cxt;
2556b445a62SJohn Marino      int c;
2566b445a62SJohn Marino {
2576b445a62SJohn Marino   switch (c)
2586b445a62SJohn Marino     {
2596b445a62SJohn Marino     case CTRL('W'):
2606b445a62SJohn Marino       rl_unix_word_rubout (1, c);
2616b445a62SJohn Marino       break;
2626b445a62SJohn Marino 
2636b445a62SJohn Marino     case CTRL('U'):
2646b445a62SJohn Marino       rl_unix_line_discard (1, c);
2656b445a62SJohn Marino       break;
2666b445a62SJohn Marino 
2676b445a62SJohn Marino     case RETURN:
2686b445a62SJohn Marino     case NEWLINE:
2696b445a62SJohn Marino       return 0;
2706b445a62SJohn Marino 
2716b445a62SJohn Marino     case CTRL('H'):
2726b445a62SJohn Marino     case RUBOUT:
2736b445a62SJohn Marino       if (rl_point == 0)
2746b445a62SJohn Marino 	{
2756b445a62SJohn Marino 	  _rl_nsearch_abort (cxt);
2766b445a62SJohn Marino 	  return -1;
2776b445a62SJohn Marino 	}
2786b445a62SJohn Marino       _rl_rubout_char (1, c);
2796b445a62SJohn Marino       break;
2806b445a62SJohn Marino 
2816b445a62SJohn Marino     case CTRL('C'):
2826b445a62SJohn Marino     case CTRL('G'):
2836b445a62SJohn Marino       rl_ding ();
2846b445a62SJohn Marino       _rl_nsearch_abort (cxt);
2856b445a62SJohn Marino       return -1;
2866b445a62SJohn Marino 
2876b445a62SJohn Marino     default:
2886b445a62SJohn Marino #if defined (HANDLE_MULTIBYTE)
2896b445a62SJohn Marino       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
2906b445a62SJohn Marino 	rl_insert_text (cxt->mb);
2916b445a62SJohn Marino       else
2926b445a62SJohn Marino #endif
2936b445a62SJohn Marino 	_rl_insert_char (1, c);
2946b445a62SJohn Marino       break;
2956b445a62SJohn Marino     }
2966b445a62SJohn Marino 
2976b445a62SJohn Marino   (*rl_redisplay_function) ();
2986b445a62SJohn Marino   return 1;
2996b445a62SJohn Marino }
3006b445a62SJohn Marino 
3016b445a62SJohn Marino /* Perform one search according to CXT, using NONINC_SEARCH_STRING.  Return
3026b445a62SJohn Marino    -1 if the search should be aborted, any other value means to clean up
3036b445a62SJohn Marino    using _rl_nsearch_cleanup ().  Returns 1 if the search was successful,
3046b445a62SJohn Marino    0 otherwise. */
3056b445a62SJohn Marino static int
_rl_nsearch_dosearch(cxt)3066b445a62SJohn Marino _rl_nsearch_dosearch (cxt)
3076b445a62SJohn Marino      _rl_search_cxt *cxt;
3086b445a62SJohn Marino {
3096b445a62SJohn Marino   rl_mark = cxt->save_mark;
3106b445a62SJohn Marino 
3116b445a62SJohn Marino   /* If rl_point == 0, we want to re-use the previous search string and
3126b445a62SJohn Marino      start from the saved history position.  If there's no previous search
3136b445a62SJohn Marino      string, punt. */
3146b445a62SJohn Marino   if (rl_point == 0)
3156b445a62SJohn Marino     {
3166b445a62SJohn Marino       if (noninc_search_string == 0)
3176b445a62SJohn Marino 	{
3186b445a62SJohn Marino 	  rl_ding ();
3196b445a62SJohn Marino 	  rl_restore_prompt ();
3206b445a62SJohn Marino 	  RL_UNSETSTATE (RL_STATE_NSEARCH);
3216b445a62SJohn Marino 	  return -1;
3226b445a62SJohn Marino 	}
3236b445a62SJohn Marino     }
3246b445a62SJohn Marino   else
3256b445a62SJohn Marino     {
3266b445a62SJohn Marino       /* We want to start the search from the current history position. */
3276b445a62SJohn Marino       noninc_history_pos = cxt->save_line;
3286b445a62SJohn Marino       FREE (noninc_search_string);
3296b445a62SJohn Marino       noninc_search_string = savestring (rl_line_buffer);
3306b445a62SJohn Marino 
3316b445a62SJohn Marino       /* If we don't want the subsequent undo list generated by the search
3326b445a62SJohn Marino 	 matching a history line to include the contents of the search string,
3336b445a62SJohn Marino 	 we need to clear rl_line_buffer here.  For now, we just clear the
3346b445a62SJohn Marino 	 undo list generated by reading the search string.  (If the search
3356b445a62SJohn Marino 	 fails, the old undo list will be restored by rl_maybe_unsave_line.) */
3366b445a62SJohn Marino       rl_free_undo_list ();
3376b445a62SJohn Marino     }
3386b445a62SJohn Marino 
3396b445a62SJohn Marino   rl_restore_prompt ();
3406b445a62SJohn Marino   return (noninc_dosearch (noninc_search_string, cxt->direction));
3416b445a62SJohn Marino }
3426b445a62SJohn Marino 
3436b445a62SJohn Marino /* Search non-interactively through the history list.  DIR < 0 means to
3446b445a62SJohn Marino    search backwards through the history of previous commands; otherwise
3456b445a62SJohn Marino    the search is for commands subsequent to the current position in the
3466b445a62SJohn Marino    history list.  PCHAR is the character to use for prompting when reading
3476b445a62SJohn Marino    the search string; if not specified (0), it defaults to `:'. */
3486b445a62SJohn Marino static int
noninc_search(dir,pchar)3496b445a62SJohn Marino noninc_search (dir, pchar)
3506b445a62SJohn Marino      int dir;
3516b445a62SJohn Marino      int pchar;
3526b445a62SJohn Marino {
3536b445a62SJohn Marino   _rl_search_cxt *cxt;
3546b445a62SJohn Marino   int c, r;
3556b445a62SJohn Marino 
3566b445a62SJohn Marino   cxt = _rl_nsearch_init (dir, pchar);
3576b445a62SJohn Marino 
3586b445a62SJohn Marino   if (RL_ISSTATE (RL_STATE_CALLBACK))
3596b445a62SJohn Marino     return (0);
3606b445a62SJohn Marino 
3616b445a62SJohn Marino   /* Read the search string. */
3626b445a62SJohn Marino   r = 0;
3636b445a62SJohn Marino   while (1)
3646b445a62SJohn Marino     {
3656b445a62SJohn Marino       c = _rl_search_getchar (cxt);
3666b445a62SJohn Marino 
3676b445a62SJohn Marino       if (c == 0)
3686b445a62SJohn Marino 	break;
3696b445a62SJohn Marino 
3706b445a62SJohn Marino       r = _rl_nsearch_dispatch (cxt, c);
3716b445a62SJohn Marino       if (r < 0)
3726b445a62SJohn Marino         return 1;
3736b445a62SJohn Marino       else if (r == 0)
3746b445a62SJohn Marino 	break;
3756b445a62SJohn Marino     }
3766b445a62SJohn Marino 
3776b445a62SJohn Marino   r = _rl_nsearch_dosearch (cxt);
3786b445a62SJohn Marino   return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
3796b445a62SJohn Marino }
3806b445a62SJohn Marino 
3816b445a62SJohn Marino /* Search forward through the history list for a string.  If the vi-mode
3826b445a62SJohn Marino    code calls this, KEY will be `?'. */
3836b445a62SJohn Marino int
rl_noninc_forward_search(count,key)3846b445a62SJohn Marino rl_noninc_forward_search (count, key)
3856b445a62SJohn Marino      int count, key;
3866b445a62SJohn Marino {
3876b445a62SJohn Marino   return noninc_search (1, (key == '?') ? '?' : 0);
3886b445a62SJohn Marino }
3896b445a62SJohn Marino 
3906b445a62SJohn Marino /* Reverse search the history list for a string.  If the vi-mode code
3916b445a62SJohn Marino    calls this, KEY will be `/'. */
3926b445a62SJohn Marino int
rl_noninc_reverse_search(count,key)3936b445a62SJohn Marino rl_noninc_reverse_search (count, key)
3946b445a62SJohn Marino      int count, key;
3956b445a62SJohn Marino {
3966b445a62SJohn Marino   return noninc_search (-1, (key == '/') ? '/' : 0);
3976b445a62SJohn Marino }
3986b445a62SJohn Marino 
3996b445a62SJohn Marino /* Search forward through the history list for the last string searched
4006b445a62SJohn Marino    for.  If there is no saved search string, abort. */
4016b445a62SJohn Marino int
rl_noninc_forward_search_again(count,key)4026b445a62SJohn Marino rl_noninc_forward_search_again (count, key)
4036b445a62SJohn Marino      int count, key;
4046b445a62SJohn Marino {
4056b445a62SJohn Marino   int r;
4066b445a62SJohn Marino 
4076b445a62SJohn Marino   if (!noninc_search_string)
4086b445a62SJohn Marino     {
4096b445a62SJohn Marino       rl_ding ();
4106b445a62SJohn Marino       return (-1);
4116b445a62SJohn Marino     }
4126b445a62SJohn Marino   r = noninc_dosearch (noninc_search_string, 1);
4136b445a62SJohn Marino   return (r != 1);
4146b445a62SJohn Marino }
4156b445a62SJohn Marino 
4166b445a62SJohn Marino /* Reverse search in the history list for the last string searched
4176b445a62SJohn Marino    for.  If there is no saved search string, abort. */
4186b445a62SJohn Marino int
rl_noninc_reverse_search_again(count,key)4196b445a62SJohn Marino rl_noninc_reverse_search_again (count, key)
4206b445a62SJohn Marino      int count, key;
4216b445a62SJohn Marino {
4226b445a62SJohn Marino   int r;
4236b445a62SJohn Marino 
4246b445a62SJohn Marino   if (!noninc_search_string)
4256b445a62SJohn Marino     {
4266b445a62SJohn Marino       rl_ding ();
4276b445a62SJohn Marino       return (-1);
4286b445a62SJohn Marino     }
4296b445a62SJohn Marino   r = noninc_dosearch (noninc_search_string, -1);
4306b445a62SJohn Marino   return (r != 1);
4316b445a62SJohn Marino }
4326b445a62SJohn Marino 
4336b445a62SJohn Marino #if defined (READLINE_CALLBACKS)
4346b445a62SJohn Marino int
_rl_nsearch_callback(cxt)4356b445a62SJohn Marino _rl_nsearch_callback (cxt)
4366b445a62SJohn Marino      _rl_search_cxt *cxt;
4376b445a62SJohn Marino {
4386b445a62SJohn Marino   int c, r;
4396b445a62SJohn Marino 
4406b445a62SJohn Marino   c = _rl_search_getchar (cxt);
4416b445a62SJohn Marino   r = _rl_nsearch_dispatch (cxt, c);
4426b445a62SJohn Marino   if (r != 0)
4436b445a62SJohn Marino     return 1;
4446b445a62SJohn Marino 
4456b445a62SJohn Marino   r = _rl_nsearch_dosearch (cxt);
4466b445a62SJohn Marino   return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
4476b445a62SJohn Marino }
4486b445a62SJohn Marino #endif
4496b445a62SJohn Marino 
4506b445a62SJohn Marino static int
rl_history_search_internal(count,dir)4516b445a62SJohn Marino rl_history_search_internal (count, dir)
4526b445a62SJohn Marino      int count, dir;
4536b445a62SJohn Marino {
4546b445a62SJohn Marino   HIST_ENTRY *temp;
4556b445a62SJohn Marino   int ret, oldpos;
4566b445a62SJohn Marino 
4576b445a62SJohn Marino   rl_maybe_save_line ();
4586b445a62SJohn Marino   temp = (HIST_ENTRY *)NULL;
4596b445a62SJohn Marino 
4606b445a62SJohn Marino   /* Search COUNT times through the history for a line whose prefix
4616b445a62SJohn Marino      matches history_search_string.  When this loop finishes, TEMP,
4626b445a62SJohn Marino      if non-null, is the history line to copy into the line buffer. */
4636b445a62SJohn Marino   while (count)
4646b445a62SJohn Marino     {
4656b445a62SJohn Marino       ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
4666b445a62SJohn Marino       if (ret == -1)
4676b445a62SJohn Marino 	break;
4686b445a62SJohn Marino 
4696b445a62SJohn Marino       /* Get the history entry we found. */
4706b445a62SJohn Marino       rl_history_search_pos = ret;
4716b445a62SJohn Marino       oldpos = where_history ();
4726b445a62SJohn Marino       history_set_pos (rl_history_search_pos);
4736b445a62SJohn Marino       temp = current_history ();
4746b445a62SJohn Marino       history_set_pos (oldpos);
4756b445a62SJohn Marino 
4766b445a62SJohn Marino       /* Don't find multiple instances of the same line. */
4776b445a62SJohn Marino       if (prev_line_found && STREQ (prev_line_found, temp->line))
4786b445a62SJohn Marino         continue;
4796b445a62SJohn Marino       prev_line_found = temp->line;
4806b445a62SJohn Marino       count--;
4816b445a62SJohn Marino     }
4826b445a62SJohn Marino 
4836b445a62SJohn Marino   /* If we didn't find anything at all, return. */
4846b445a62SJohn Marino   if (temp == 0)
4856b445a62SJohn Marino     {
4866b445a62SJohn Marino       rl_maybe_unsave_line ();
4876b445a62SJohn Marino       rl_ding ();
4886b445a62SJohn Marino       /* If you don't want the saved history line (last match) to show up
4896b445a62SJohn Marino          in the line buffer after the search fails, change the #if 0 to
4906b445a62SJohn Marino          #if 1 */
4916b445a62SJohn Marino #if 0
4926b445a62SJohn Marino       if (rl_point > rl_history_search_len)
4936b445a62SJohn Marino         {
4946b445a62SJohn Marino           rl_point = rl_end = rl_history_search_len;
4956b445a62SJohn Marino           rl_line_buffer[rl_end] = '\0';
4966b445a62SJohn Marino           rl_mark = 0;
4976b445a62SJohn Marino         }
4986b445a62SJohn Marino #else
4996b445a62SJohn Marino       rl_point = rl_history_search_len;	/* rl_maybe_unsave_line changes it */
5006b445a62SJohn Marino       rl_mark = rl_end;
5016b445a62SJohn Marino #endif
5026b445a62SJohn Marino       return 1;
5036b445a62SJohn Marino     }
5046b445a62SJohn Marino 
5056b445a62SJohn Marino   /* Copy the line we found into the current line buffer. */
5066b445a62SJohn Marino   make_history_line_current (temp);
5076b445a62SJohn Marino 
5086b445a62SJohn Marino   rl_point = rl_history_search_len;
5096b445a62SJohn Marino   rl_mark = rl_end;
5106b445a62SJohn Marino 
5116b445a62SJohn Marino   return 0;
5126b445a62SJohn Marino }
5136b445a62SJohn Marino 
5146b445a62SJohn Marino static void
rl_history_search_reinit()5156b445a62SJohn Marino rl_history_search_reinit ()
5166b445a62SJohn Marino {
5176b445a62SJohn Marino   rl_history_search_pos = where_history ();
5186b445a62SJohn Marino   rl_history_search_len = rl_point;
5196b445a62SJohn Marino   prev_line_found = (char *)NULL;
5206b445a62SJohn Marino   if (rl_point)
5216b445a62SJohn Marino     {
5226b445a62SJohn Marino       if (rl_history_search_len >= history_string_size - 2)
5236b445a62SJohn Marino 	{
5246b445a62SJohn Marino 	  history_string_size = rl_history_search_len + 2;
5256b445a62SJohn Marino 	  history_search_string = (char *)xrealloc (history_search_string, history_string_size);
5266b445a62SJohn Marino 	}
5276b445a62SJohn Marino       history_search_string[0] = '^';
5286b445a62SJohn Marino       strncpy (history_search_string + 1, rl_line_buffer, rl_point);
5296b445a62SJohn Marino       history_search_string[rl_point + 1] = '\0';
5306b445a62SJohn Marino     }
5316b445a62SJohn Marino   _rl_free_saved_history_line ();
5326b445a62SJohn Marino }
5336b445a62SJohn Marino 
5346b445a62SJohn Marino /* Search forward in the history for the string of characters
5356b445a62SJohn Marino    from the start of the line to rl_point.  This is a non-incremental
5366b445a62SJohn Marino    search. */
5376b445a62SJohn Marino int
rl_history_search_forward(count,ignore)5386b445a62SJohn Marino rl_history_search_forward (count, ignore)
5396b445a62SJohn Marino      int count, ignore;
5406b445a62SJohn Marino {
5416b445a62SJohn Marino   if (count == 0)
5426b445a62SJohn Marino     return (0);
5436b445a62SJohn Marino 
5446b445a62SJohn Marino   if (rl_last_func != rl_history_search_forward &&
5456b445a62SJohn Marino       rl_last_func != rl_history_search_backward)
5466b445a62SJohn Marino     rl_history_search_reinit ();
5476b445a62SJohn Marino 
5486b445a62SJohn Marino   if (rl_history_search_len == 0)
5496b445a62SJohn Marino     return (rl_get_next_history (count, ignore));
5506b445a62SJohn Marino   return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
5516b445a62SJohn Marino }
5526b445a62SJohn Marino 
5536b445a62SJohn Marino /* Search backward through the history for the string of characters
5546b445a62SJohn Marino    from the start of the line to rl_point.  This is a non-incremental
5556b445a62SJohn Marino    search. */
5566b445a62SJohn Marino int
rl_history_search_backward(count,ignore)5576b445a62SJohn Marino rl_history_search_backward (count, ignore)
5586b445a62SJohn Marino      int count, ignore;
5596b445a62SJohn Marino {
5606b445a62SJohn Marino   if (count == 0)
5616b445a62SJohn Marino     return (0);
5626b445a62SJohn Marino 
5636b445a62SJohn Marino   if (rl_last_func != rl_history_search_forward &&
5646b445a62SJohn Marino       rl_last_func != rl_history_search_backward)
5656b445a62SJohn Marino     rl_history_search_reinit ();
5666b445a62SJohn Marino 
5676b445a62SJohn Marino   if (rl_history_search_len == 0)
5686b445a62SJohn Marino     return (rl_get_previous_history (count, ignore));
5696b445a62SJohn Marino   return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
5706b445a62SJohn Marino }
571