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