Blame readline/search.c

Packit Service 706eca
/* search.c - code for non-incremental searching in emacs and vi modes. */
Packit Service 706eca
Packit Service 706eca
/* Copyright (C) 1992-2009 Free Software Foundation, Inc.
Packit Service 706eca
Packit Service 706eca
   This file is part of the GNU Readline Library (Readline), a library
Packit Service 706eca
   for reading lines of text with interactive input and history editing.      
Packit Service 706eca
Packit Service 706eca
   Readline is free software: you can redistribute it and/or modify
Packit Service 706eca
   it under the terms of the GNU General Public License as published by
Packit Service 706eca
   the Free Software Foundation, either version 3 of the License, or
Packit Service 706eca
   (at your option) any later version.
Packit Service 706eca
Packit Service 706eca
   Readline is distributed in the hope that it will be useful,
Packit Service 706eca
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 706eca
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 706eca
   GNU General Public License for more details.
Packit Service 706eca
Packit Service 706eca
   You should have received a copy of the GNU General Public License
Packit Service 706eca
   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
Packit Service 706eca
*/
Packit Service 706eca
Packit Service 706eca
#define READLINE_LIBRARY
Packit Service 706eca
Packit Service 706eca
#if defined (HAVE_CONFIG_H)
Packit Service 706eca
#  include <config.h>
Packit Service 706eca
#endif
Packit Service 706eca
Packit Service 706eca
#include <sys/types.h>
Packit Service 706eca
#include <stdio.h>
Packit Service 706eca
Packit Service 706eca
#if defined (HAVE_UNISTD_H)
Packit Service 706eca
#  include <unistd.h>
Packit Service 706eca
#endif
Packit Service 706eca
Packit Service 706eca
#if defined (HAVE_STDLIB_H)
Packit Service 706eca
#  include <stdlib.h>
Packit Service 706eca
#else
Packit Service 706eca
#  include "ansi_stdlib.h"
Packit Service 706eca
#endif
Packit Service 706eca
Packit Service 706eca
#include "rldefs.h"
Packit Service 706eca
#include "rlmbutil.h"
Packit Service 706eca
Packit Service 706eca
#include "readline.h"
Packit Service 706eca
#include "history.h"
Packit Service 706eca
Packit Service 706eca
#include "rlprivate.h"
Packit Service 706eca
#include "xmalloc.h"
Packit Service 706eca
Packit Service 706eca
#ifdef abs
Packit Service 706eca
#  undef abs
Packit Service 706eca
#endif
Packit Service 706eca
#define abs(x)		(((x) >= 0) ? (x) : -(x))
Packit Service 706eca
Packit Service 706eca
_rl_search_cxt *_rl_nscxt = 0;
Packit Service 706eca
Packit Service 706eca
extern HIST_ENTRY *_rl_saved_line_for_history;
Packit Service 706eca
Packit Service 706eca
/* Functions imported from the rest of the library. */
Packit Service 706eca
extern int _rl_free_history_entry PARAMS((HIST_ENTRY *));
Packit Service 706eca
Packit Service 706eca
static char *noninc_search_string = (char *) NULL;
Packit Service 706eca
static int noninc_history_pos;
Packit Service 706eca
Packit Service 706eca
static char *prev_line_found = (char *) NULL;
Packit Service 706eca
Packit Service 706eca
static int rl_history_search_len;
Packit Service 706eca
static int rl_history_search_pos;
Packit Service 706eca
static char *history_search_string;
Packit Service 706eca
static int history_string_size;
Packit Service 706eca
Packit Service 706eca
static void make_history_line_current PARAMS((HIST_ENTRY *));
Packit Service 706eca
static int noninc_search_from_pos PARAMS((char *, int, int));
Packit Service 706eca
static int noninc_dosearch PARAMS((char *, int));
Packit Service 706eca
static int noninc_search PARAMS((int, int));
Packit Service 706eca
static int rl_history_search_internal PARAMS((int, int));
Packit Service 706eca
static void rl_history_search_reinit PARAMS((void));
Packit Service 706eca
Packit Service 706eca
static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
Packit Service 706eca
static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
Packit Service 706eca
static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
Packit Service 706eca
static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
Packit Service 706eca
Packit Service 706eca
/* Make the data from the history entry ENTRY be the contents of the
Packit Service 706eca
   current line.  This doesn't do anything with rl_point; the caller
Packit Service 706eca
   must set it. */
Packit Service 706eca
static void
Packit Service 706eca
make_history_line_current (entry)
Packit Service 706eca
     HIST_ENTRY *entry;
Packit Service 706eca
{
Packit Service 706eca
  _rl_replace_text (entry->line, 0, rl_end);
Packit Service 706eca
  _rl_fix_point (1);
Packit Service 706eca
#if defined (VI_MODE)
Packit Service 706eca
  if (rl_editing_mode == vi_mode)
Packit Service 706eca
    /* POSIX.2 says that the `U' command doesn't affect the copy of any
Packit Service 706eca
       command lines to the edit line.  We're going to implement that by
Packit Service 706eca
       making the undo list start after the matching line is copied to the
Packit Service 706eca
       current editing buffer. */
Packit Service 706eca
    rl_free_undo_list ();
Packit Service 706eca
#endif
Packit Service 706eca
Packit Service 706eca
  if (_rl_saved_line_for_history)
Packit Service 706eca
    _rl_free_history_entry (_rl_saved_line_for_history);
Packit Service 706eca
  _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Search the history list for STRING starting at absolute history position
Packit Service 706eca
   POS.  If STRING begins with `^', the search must match STRING at the
Packit Service 706eca
   beginning of a history line, otherwise a full substring match is performed
Packit Service 706eca
   for STRING.  DIR < 0 means to search backwards through the history list,
Packit Service 706eca
   DIR >= 0 means to search forward. */
Packit Service 706eca
static int
Packit Service 706eca
noninc_search_from_pos (string, pos, dir)
Packit Service 706eca
     char *string;
Packit Service 706eca
     int pos, dir;
Packit Service 706eca
{
Packit Service 706eca
  int ret, old;
Packit Service 706eca
Packit Service 706eca
  if (pos < 0)
Packit Service 706eca
    return -1;
Packit Service 706eca
Packit Service 706eca
  old = where_history ();
Packit Service 706eca
  if (history_set_pos (pos) == 0)
Packit Service 706eca
    return -1;
Packit Service 706eca
Packit Service 706eca
  RL_SETSTATE(RL_STATE_SEARCH);
Packit Service 706eca
  if (*string == '^')
Packit Service 706eca
    ret = history_search_prefix (string + 1, dir);
Packit Service 706eca
  else
Packit Service 706eca
    ret = history_search (string, dir);
Packit Service 706eca
  RL_UNSETSTATE(RL_STATE_SEARCH);
Packit Service 706eca
Packit Service 706eca
  if (ret != -1)
Packit Service 706eca
    ret = where_history ();
Packit Service 706eca
Packit Service 706eca
  history_set_pos (old);
Packit Service 706eca
  return (ret);
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Search for a line in the history containing STRING.  If DIR is < 0, the
Packit Service 706eca
   search is backwards through previous entries, else through subsequent
Packit Service 706eca
   entries.  Returns 1 if the search was successful, 0 otherwise. */
Packit Service 706eca
static int
Packit Service 706eca
noninc_dosearch (string, dir)
Packit Service 706eca
     char *string;
Packit Service 706eca
     int dir;
Packit Service 706eca
{
Packit Service 706eca
  int oldpos, pos;
Packit Service 706eca
  HIST_ENTRY *entry;
Packit Service 706eca
Packit Service 706eca
  if (string == 0 || *string == '\0' || noninc_history_pos < 0)
Packit Service 706eca
    {
Packit Service 706eca
      rl_ding ();
Packit Service 706eca
      return 0;
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
Packit Service 706eca
  if (pos == -1)
Packit Service 706eca
    {
Packit Service 706eca
      /* Search failed, current history position unchanged. */
Packit Service 706eca
      rl_maybe_unsave_line ();
Packit Service 706eca
      rl_clear_message ();
Packit Service 706eca
      rl_point = 0;
Packit Service 706eca
      rl_ding ();
Packit Service 706eca
      return 0;
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  noninc_history_pos = pos;
Packit Service 706eca
Packit Service 706eca
  oldpos = where_history ();
Packit Service 706eca
  history_set_pos (noninc_history_pos);
Packit Service 706eca
  entry = current_history ();
Packit Service 706eca
#if defined (VI_MODE)
Packit Service 706eca
  if (rl_editing_mode != vi_mode)
Packit Service 706eca
#endif
Packit Service 706eca
    history_set_pos (oldpos);
Packit Service 706eca
Packit Service 706eca
  make_history_line_current (entry);
Packit Service 706eca
Packit Service 706eca
  rl_point = 0;
Packit Service 706eca
  rl_mark = rl_end;
Packit Service 706eca
Packit Service 706eca
  rl_clear_message ();
Packit Service 706eca
  return 1;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
static _rl_search_cxt *
Packit Service 706eca
_rl_nsearch_init (dir, pchar)
Packit Service 706eca
     int dir, pchar;
Packit Service 706eca
{
Packit Service 706eca
  _rl_search_cxt *cxt;
Packit Service 706eca
  char *p;
Packit Service 706eca
Packit Service 706eca
  cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
Packit Service 706eca
  if (dir < 0)
Packit Service 706eca
    cxt->sflags |= SF_REVERSE;		/* not strictly needed */
Packit Service 706eca
Packit Service 706eca
  cxt->direction = dir;
Packit Service 706eca
  cxt->history_pos = cxt->save_line;
Packit Service 706eca
Packit Service 706eca
  rl_maybe_save_line ();
Packit Service 706eca
Packit Service 706eca
  /* Clear the undo list, since reading the search string should create its
Packit Service 706eca
     own undo list, and the whole list will end up being freed when we
Packit Service 706eca
     finish reading the search string. */
Packit Service 706eca
  rl_undo_list = 0;
Packit Service 706eca
Packit Service 706eca
  /* Use the line buffer to read the search string. */
Packit Service 706eca
  rl_line_buffer[0] = 0;
Packit Service 706eca
  rl_end = rl_point = 0;
Packit Service 706eca
Packit Service 706eca
  p = _rl_make_prompt_for_search (pchar ? pchar : ':');
Packit Service 706eca
  rl_message ("%s", p);
Packit Service 706eca
  xfree (p);
Packit Service 706eca
Packit Service 706eca
  RL_SETSTATE(RL_STATE_NSEARCH);
Packit Service 706eca
Packit Service 706eca
  _rl_nscxt = cxt;
Packit Service 706eca
Packit Service 706eca
  return cxt;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
static int
Packit Service 706eca
_rl_nsearch_cleanup (cxt, r)
Packit Service 706eca
     _rl_search_cxt *cxt;
Packit Service 706eca
     int r;
Packit Service 706eca
{
Packit Service 706eca
  _rl_scxt_dispose (cxt, 0);
Packit Service 706eca
  _rl_nscxt = 0;
Packit Service 706eca
Packit Service 706eca
  RL_UNSETSTATE(RL_STATE_NSEARCH);
Packit Service 706eca
Packit Service 706eca
  return (r != 1);
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
_rl_nsearch_abort (cxt)
Packit Service 706eca
     _rl_search_cxt *cxt;
Packit Service 706eca
{
Packit Service 706eca
  rl_maybe_unsave_line ();
Packit Service 706eca
  rl_clear_message ();
Packit Service 706eca
  rl_point = cxt->save_point;
Packit Service 706eca
  rl_mark = cxt->save_mark;
Packit Service 706eca
  rl_restore_prompt ();
Packit Service 706eca
Packit Service 706eca
  RL_UNSETSTATE (RL_STATE_NSEARCH);
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Process just-read character C according to search context CXT.  Return -1
Packit Service 706eca
   if the caller should abort the search, 0 if we should break out of the
Packit Service 706eca
   loop, and 1 if we should continue to read characters. */
Packit Service 706eca
static int
Packit Service 706eca
_rl_nsearch_dispatch (cxt, c)
Packit Service 706eca
     _rl_search_cxt *cxt;
Packit Service 706eca
     int c;
Packit Service 706eca
{
Packit Service 706eca
  switch (c)
Packit Service 706eca
    {
Packit Service 706eca
    case CTRL('W'):
Packit Service 706eca
      rl_unix_word_rubout (1, c);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    case CTRL('U'):
Packit Service 706eca
      rl_unix_line_discard (1, c);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    case RETURN:
Packit Service 706eca
    case NEWLINE:
Packit Service 706eca
      return 0;
Packit Service 706eca
Packit Service 706eca
    case CTRL('H'):
Packit Service 706eca
    case RUBOUT:
Packit Service 706eca
      if (rl_point == 0)
Packit Service 706eca
	{
Packit Service 706eca
	  _rl_nsearch_abort (cxt);
Packit Service 706eca
	  return -1;
Packit Service 706eca
	}
Packit Service 706eca
      _rl_rubout_char (1, c);
Packit Service 706eca
      break;
Packit Service 706eca
Packit Service 706eca
    case CTRL('C'):
Packit Service 706eca
    case CTRL('G'):
Packit Service 706eca
      rl_ding ();
Packit Service 706eca
      _rl_nsearch_abort (cxt);
Packit Service 706eca
      return -1;
Packit Service 706eca
Packit Service 706eca
    default:
Packit Service 706eca
#if defined (HANDLE_MULTIBYTE)
Packit Service 706eca
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
Packit Service 706eca
	rl_insert_text (cxt->mb);
Packit Service 706eca
      else
Packit Service 706eca
#endif
Packit Service 706eca
	_rl_insert_char (1, c);
Packit Service 706eca
      break;
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  (*rl_redisplay_function) ();
Packit Service 706eca
  return 1;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Perform one search according to CXT, using NONINC_SEARCH_STRING.  Return
Packit Service 706eca
   -1 if the search should be aborted, any other value means to clean up
Packit Service 706eca
   using _rl_nsearch_cleanup ().  Returns 1 if the search was successful,
Packit Service 706eca
   0 otherwise. */
Packit Service 706eca
static int
Packit Service 706eca
_rl_nsearch_dosearch (cxt)
Packit Service 706eca
     _rl_search_cxt *cxt;
Packit Service 706eca
{
Packit Service 706eca
  rl_mark = cxt->save_mark;
Packit Service 706eca
Packit Service 706eca
  /* If rl_point == 0, we want to re-use the previous search string and
Packit Service 706eca
     start from the saved history position.  If there's no previous search
Packit Service 706eca
     string, punt. */
Packit Service 706eca
  if (rl_point == 0)
Packit Service 706eca
    {
Packit Service 706eca
      if (noninc_search_string == 0)
Packit Service 706eca
	{
Packit Service 706eca
	  rl_ding ();
Packit Service 706eca
	  rl_restore_prompt ();
Packit Service 706eca
	  RL_UNSETSTATE (RL_STATE_NSEARCH);
Packit Service 706eca
	  return -1;
Packit Service 706eca
	}
Packit Service 706eca
    }
Packit Service 706eca
  else
Packit Service 706eca
    {
Packit Service 706eca
      /* We want to start the search from the current history position. */
Packit Service 706eca
      noninc_history_pos = cxt->save_line;
Packit Service 706eca
      FREE (noninc_search_string);
Packit Service 706eca
      noninc_search_string = savestring (rl_line_buffer);
Packit Service 706eca
Packit Service 706eca
      /* If we don't want the subsequent undo list generated by the search
Packit Service 706eca
	 matching a history line to include the contents of the search string,
Packit Service 706eca
	 we need to clear rl_line_buffer here.  For now, we just clear the
Packit Service 706eca
	 undo list generated by reading the search string.  (If the search
Packit Service 706eca
	 fails, the old undo list will be restored by rl_maybe_unsave_line.) */
Packit Service 706eca
      rl_free_undo_list ();
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  rl_restore_prompt ();
Packit Service 706eca
  return (noninc_dosearch (noninc_search_string, cxt->direction));
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Search non-interactively through the history list.  DIR < 0 means to
Packit Service 706eca
   search backwards through the history of previous commands; otherwise
Packit Service 706eca
   the search is for commands subsequent to the current position in the
Packit Service 706eca
   history list.  PCHAR is the character to use for prompting when reading
Packit Service 706eca
   the search string; if not specified (0), it defaults to `:'. */
Packit Service 706eca
static int
Packit Service 706eca
noninc_search (dir, pchar)
Packit Service 706eca
     int dir;
Packit Service 706eca
     int pchar;
Packit Service 706eca
{
Packit Service 706eca
  _rl_search_cxt *cxt;
Packit Service 706eca
  int c, r;
Packit Service 706eca
Packit Service 706eca
  cxt = _rl_nsearch_init (dir, pchar);
Packit Service 706eca
Packit Service 706eca
  if (RL_ISSTATE (RL_STATE_CALLBACK))
Packit Service 706eca
    return (0);
Packit Service 706eca
Packit Service 706eca
  /* Read the search string. */
Packit Service 706eca
  r = 0;
Packit Service 706eca
  while (1)
Packit Service 706eca
    {
Packit Service 706eca
      c = _rl_search_getchar (cxt);
Packit Service 706eca
Packit Service 706eca
      if (c == 0)
Packit Service 706eca
	break;
Packit Service 706eca
Packit Service 706eca
      r = _rl_nsearch_dispatch (cxt, c);
Packit Service 706eca
      if (r < 0)
Packit Service 706eca
        return 1;
Packit Service 706eca
      else if (r == 0)
Packit Service 706eca
	break;        
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  r = _rl_nsearch_dosearch (cxt);
Packit Service 706eca
  return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Search forward through the history list for a string.  If the vi-mode
Packit Service 706eca
   code calls this, KEY will be `?'. */
Packit Service 706eca
int
Packit Service 706eca
rl_noninc_forward_search (count, key)
Packit Service 706eca
     int count, key;
Packit Service 706eca
{
Packit Service 706eca
  return noninc_search (1, (key == '?') ? '?' : 0);
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Reverse search the history list for a string.  If the vi-mode code
Packit Service 706eca
   calls this, KEY will be `/'. */
Packit Service 706eca
int
Packit Service 706eca
rl_noninc_reverse_search (count, key)
Packit Service 706eca
     int count, key;
Packit Service 706eca
{
Packit Service 706eca
  return noninc_search (-1, (key == '/') ? '/' : 0);
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Search forward through the history list for the last string searched
Packit Service 706eca
   for.  If there is no saved search string, abort. */
Packit Service 706eca
int
Packit Service 706eca
rl_noninc_forward_search_again (count, key)
Packit Service 706eca
     int count, key;
Packit Service 706eca
{
Packit Service 706eca
  int r;
Packit Service 706eca
Packit Service 706eca
  if (!noninc_search_string)
Packit Service 706eca
    {
Packit Service 706eca
      rl_ding ();
Packit Service 706eca
      return (-1);
Packit Service 706eca
    }
Packit Service 706eca
  r = noninc_dosearch (noninc_search_string, 1);
Packit Service 706eca
  return (r != 1);
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Reverse search in the history list for the last string searched
Packit Service 706eca
   for.  If there is no saved search string, abort. */
Packit Service 706eca
int
Packit Service 706eca
rl_noninc_reverse_search_again (count, key)
Packit Service 706eca
     int count, key;
Packit Service 706eca
{
Packit Service 706eca
  int r;
Packit Service 706eca
Packit Service 706eca
  if (!noninc_search_string)
Packit Service 706eca
    {
Packit Service 706eca
      rl_ding ();
Packit Service 706eca
      return (-1);
Packit Service 706eca
    }
Packit Service 706eca
  r = noninc_dosearch (noninc_search_string, -1);
Packit Service 706eca
  return (r != 1);
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
#if defined (READLINE_CALLBACKS)
Packit Service 706eca
int
Packit Service 706eca
_rl_nsearch_callback (cxt)
Packit Service 706eca
     _rl_search_cxt *cxt;
Packit Service 706eca
{
Packit Service 706eca
  int c, r;
Packit Service 706eca
Packit Service 706eca
  c = _rl_search_getchar (cxt);
Packit Service 706eca
  r = _rl_nsearch_dispatch (cxt, c);
Packit Service 706eca
  if (r != 0)
Packit Service 706eca
    return 1;
Packit Service 706eca
Packit Service 706eca
  r = _rl_nsearch_dosearch (cxt);
Packit Service 706eca
  return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
Packit Service 706eca
}
Packit Service 706eca
#endif
Packit Service 706eca
  
Packit Service 706eca
static int
Packit Service 706eca
rl_history_search_internal (count, dir)
Packit Service 706eca
     int count, dir;
Packit Service 706eca
{
Packit Service 706eca
  HIST_ENTRY *temp;
Packit Service 706eca
  int ret, oldpos;
Packit Service 706eca
Packit Service 706eca
  rl_maybe_save_line ();
Packit Service 706eca
  temp = (HIST_ENTRY *)NULL;
Packit Service 706eca
Packit Service 706eca
  /* Search COUNT times through the history for a line whose prefix
Packit Service 706eca
     matches history_search_string.  When this loop finishes, TEMP,
Packit Service 706eca
     if non-null, is the history line to copy into the line buffer. */
Packit Service 706eca
  while (count)
Packit Service 706eca
    {
Packit Service 706eca
      ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
Packit Service 706eca
      if (ret == -1)
Packit Service 706eca
	break;
Packit Service 706eca
Packit Service 706eca
      /* Get the history entry we found. */
Packit Service 706eca
      rl_history_search_pos = ret;
Packit Service 706eca
      oldpos = where_history ();
Packit Service 706eca
      history_set_pos (rl_history_search_pos);
Packit Service 706eca
      temp = current_history ();
Packit Service 706eca
      history_set_pos (oldpos);
Packit Service 706eca
Packit Service 706eca
      /* Don't find multiple instances of the same line. */
Packit Service 706eca
      if (prev_line_found && STREQ (prev_line_found, temp->line))
Packit Service 706eca
        continue;
Packit Service 706eca
      prev_line_found = temp->line;
Packit Service 706eca
      count--;
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  /* If we didn't find anything at all, return. */
Packit Service 706eca
  if (temp == 0)
Packit Service 706eca
    {
Packit Service 706eca
      rl_maybe_unsave_line ();
Packit Service 706eca
      rl_ding ();
Packit Service 706eca
      /* If you don't want the saved history line (last match) to show up
Packit Service 706eca
         in the line buffer after the search fails, change the #if 0 to
Packit Service 706eca
         #if 1 */
Packit Service 706eca
#if 0
Packit Service 706eca
      if (rl_point > rl_history_search_len)
Packit Service 706eca
        {
Packit Service 706eca
          rl_point = rl_end = rl_history_search_len;
Packit Service 706eca
          rl_line_buffer[rl_end] = '\0';
Packit Service 706eca
          rl_mark = 0;
Packit Service 706eca
        }
Packit Service 706eca
#else
Packit Service 706eca
      rl_point = rl_history_search_len;	/* rl_maybe_unsave_line changes it */
Packit Service 706eca
      rl_mark = rl_end;
Packit Service 706eca
#endif
Packit Service 706eca
      return 1;
Packit Service 706eca
    }
Packit Service 706eca
Packit Service 706eca
  /* Copy the line we found into the current line buffer. */
Packit Service 706eca
  make_history_line_current (temp);
Packit Service 706eca
Packit Service 706eca
  rl_point = rl_history_search_len;
Packit Service 706eca
  rl_mark = rl_end;
Packit Service 706eca
Packit Service 706eca
  return 0;
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
static void
Packit Service 706eca
rl_history_search_reinit ()
Packit Service 706eca
{
Packit Service 706eca
  rl_history_search_pos = where_history ();
Packit Service 706eca
  rl_history_search_len = rl_point;
Packit Service 706eca
  prev_line_found = (char *)NULL;
Packit Service 706eca
  if (rl_point)
Packit Service 706eca
    {
Packit Service 706eca
      if (rl_history_search_len >= history_string_size - 2)
Packit Service 706eca
	{
Packit Service 706eca
	  history_string_size = rl_history_search_len + 2;
Packit Service 706eca
	  history_search_string = (char *)xrealloc (history_search_string, history_string_size);
Packit Service 706eca
	}
Packit Service 706eca
      history_search_string[0] = '^';
Packit Service 706eca
      strncpy (history_search_string + 1, rl_line_buffer, rl_point);
Packit Service 706eca
      history_search_string[rl_point + 1] = '\0';
Packit Service 706eca
    }
Packit Service 706eca
  _rl_free_saved_history_line ();
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Search forward in the history for the string of characters
Packit Service 706eca
   from the start of the line to rl_point.  This is a non-incremental
Packit Service 706eca
   search. */
Packit Service 706eca
int
Packit Service 706eca
rl_history_search_forward (count, ignore)
Packit Service 706eca
     int count, ignore;
Packit Service 706eca
{
Packit Service 706eca
  if (count == 0)
Packit Service 706eca
    return (0);
Packit Service 706eca
Packit Service 706eca
  if (rl_last_func != rl_history_search_forward &&
Packit Service 706eca
      rl_last_func != rl_history_search_backward)
Packit Service 706eca
    rl_history_search_reinit ();
Packit Service 706eca
Packit Service 706eca
  if (rl_history_search_len == 0)
Packit Service 706eca
    return (rl_get_next_history (count, ignore));
Packit Service 706eca
  return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
Packit Service 706eca
}
Packit Service 706eca
Packit Service 706eca
/* Search backward through the history for the string of characters
Packit Service 706eca
   from the start of the line to rl_point.  This is a non-incremental
Packit Service 706eca
   search. */
Packit Service 706eca
int
Packit Service 706eca
rl_history_search_backward (count, ignore)
Packit Service 706eca
     int count, ignore;
Packit Service 706eca
{
Packit Service 706eca
  if (count == 0)
Packit Service 706eca
    return (0);
Packit Service 706eca
Packit Service 706eca
  if (rl_last_func != rl_history_search_forward &&
Packit Service 706eca
      rl_last_func != rl_history_search_backward)
Packit Service 706eca
    rl_history_search_reinit ();
Packit Service 706eca
Packit Service 706eca
  if (rl_history_search_len == 0)
Packit Service 706eca
    return (rl_get_previous_history (count, ignore));
Packit Service 706eca
  return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
Packit Service 706eca
}