/* **************************************************************** */
/*								    */
/*			I-Search and Searching			    */
/*								    */
/* **************************************************************** */

/* Copyright (C) 1987-2002 Free Software Foundation, Inc.

   This file contains the Readline Library (the Library), a set of
   routines for providing Emacs style line input to programs that ask
   for it.

   The Library is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   The Library is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   The GNU General Public License is often shipped with GNU software, and
   is generally kept in a file called COPYING or LICENSE.  If you do not
   have a copy of the license, write to the Free Software Foundation,
   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY

#if defined (HAVE_CONFIG_H)
#  include <config.h>
#endif

#include <sys/types.h>

#include <stdio.h>

#if defined (HAVE_UNISTD_H)
#  include <unistd.h>
#endif

#if defined (HAVE_STDLIB_H)
#  include <stdlib.h>
#else
#  include "ansi_stdlib.h"
#endif

#include "rldefs.h"
#include "rlmbutil.h"

#include "readline.h"
#include "history.h"

#include "rlprivate.h"
#include "xmalloc.h"

/* Variables exported to other files in the readline library. */
char *_rl_isearch_terminators = (char *)NULL;

/* Variables imported from other files in the readline library. */
extern HIST_ENTRY *_rl_saved_line_for_history;

/* Forward declarations */
static int rl_search_history PARAMS((int, int));

/* 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;

/* Last search string and its length. */
static char *last_isearch_string;
static int last_isearch_string_len;

static char *default_isearch_terminators = "\033\012";

/* Search backwards through the history looking for a string which is typed
   interactively.  Start with the current line. */
int
rl_reverse_search_history (sign, key)
     int sign, key;
{
  return (rl_search_history (-sign, key));
}

/* Search forwards through the history looking for a string which is typed
   interactively.  Start with the current line. */
int
rl_forward_search_history (sign, key)
     int sign, key;
{
  return (rl_search_history (sign, key));
}

/* Display the current state of the search in the echo-area.
   SEARCH_STRING contains the string that is being searched for,
   DIRECTION is zero for forward, or 1 for reverse,
   WHERE is the history list number of the current line.  If it is
   -1, then this line is the starting one. */
static void
rl_display_search (search_string, reverse_p, where)
     char *search_string;
     int reverse_p, where;
{
  char *message;
  int msglen, searchlen;

  searchlen = (search_string && *search_string) ? strlen (search_string) : 0;

  message = (char *)xmalloc (searchlen + 33);
  msglen = 0;

#if defined (NOTDEF)
  if (where != -1)
    {
      sprintf (message, "[%d]", where + history_base);
      msglen = strlen (message);
    }
#endif /* NOTDEF */

  message[msglen++] = '(';

  if (reverse_p)
    {
      strcpy (message + msglen, "reverse-");
      msglen += 8;
    }

  strcpy (message + msglen, "i-search)`");
  msglen += 10;

  if (search_string)
    {
      strcpy (message + msglen, search_string);
      msglen += searchlen;
    }

  strcpy (message + msglen, "': ");

  rl_message ("%s", message);
  free (message);
  (*rl_redisplay_function) ();
}

/* Search through the history looking for an interactively typed string.
   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 int
rl_search_history (direction, invoking_key)
     int direction, invoking_key;
{
  /* The string that the user types in to search for. */
  char *search_string;

  /* The current length of SEARCH_STRING. */
  int search_string_index;

  /* The amount of space that SEARCH_STRING has allocated to it. */
  int search_string_size;

  /* The list of lines to search through. */
  char **lines, *allocated_line;

  /* The length of LINES. */
  int hlen;

  /* Where we get LINES from. */
  HIST_ENTRY **hlist;

  register int i;
  int orig_point, orig_mark, orig_line, last_found_line;
  int c, found, failed, sline_len;
  int n, wstart, wlen;
#if defined (HANDLE_MULTIBYTE)
  char mb[MB_LEN_MAX];
#endif

  /* The line currently being searched. */
  char *sline;

  /* Offset in that line. */
  int line_index;

  /* Non-zero if we are doing a reverse search. */
  int reverse;

  /* The list of characters which terminate the search, but are not
     subsequently executed.  If the variable isearch-terminators has
     been set, we use that value, otherwise we use ESC and C-J. */
  char *isearch_terminators;

  RL_SETSTATE(RL_STATE_ISEARCH);
  orig_point = rl_point;
  orig_mark = rl_mark;
  last_found_line = orig_line = where_history ();
  reverse = direction < 0;
  hlist = history_list ();
  allocated_line = (char *)NULL;

  isearch_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
						: default_isearch_terminators;

  /* Create an arrary of pointers to the lines that we want to search. */
  rl_maybe_replace_line ();
  i = 0;
  if (hlist)
    for (i = 0; hlist[i]; i++);

  /* Allocate space for this many lines, +1 for the current input line,
     and remember those lines. */
  lines = (char **)xmalloc ((1 + (hlen = i)) * sizeof (char *));
  for (i = 0; i < hlen; i++)
    lines[i] = hlist[i]->line;

  if (_rl_saved_line_for_history)
    lines[i] = _rl_saved_line_for_history->line;
  else
    {
      /* Keep track of this so we can free it. */
      allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
      strcpy (allocated_line, &rl_line_buffer[0]);
      lines[i] = allocated_line;
    }

  hlen++;

  /* The line where we start the search. */
  i = orig_line;

  rl_save_prompt ();

  /* Initialize search parameters. */
  search_string = (char *)xmalloc (search_string_size = 128);
  *search_string = '\0';
  search_string_index = 0;
  prev_line_found = (char *)0;		/* XXX */

  /* Normalize DIRECTION into 1 or -1. */
  direction = (direction >= 0) ? 1 : -1;

  rl_display_search (search_string, reverse, -1);

  sline = rl_line_buffer;
  sline_len = strlen (sline);
  line_index = rl_point;

  found = failed = 0;
  for (;;)
    {
      rl_command_func_t *f = (rl_command_func_t *)NULL;

      /* Read a key and decide how to proceed. */
      RL_SETSTATE(RL_STATE_MOREINPUT);
      c = rl_read_key ();
      RL_UNSETSTATE(RL_STATE_MOREINPUT);

#if defined (HANDLE_MULTIBYTE)
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
	c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
#endif

      /* Translate the keys we do something with to opcodes. */
      if (c >= 0 && _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;
	  else if (f == rl_rubout)
	    c = -3;
	  else if (c == CTRL ('G'))
	    c = -4;
	  else if (c == CTRL ('W'))	/* XXX */
	    c = -5;
	  else if (c == CTRL ('Y'))	/* XXX */
	    c = -6;
	}

      /* The characters in isearch_terminators (set from the user-settable
	 variable isearch-terminators) are used to terminate the search but
	 not subsequently execute the character as a command.  The default
	 value is "\033\012" (ESC and C-J). */
      if (strchr (isearch_terminators, c))
	{
	  /* ESC still terminates the search, but if there is pending
	     input or if input arrives within 0.1 seconds (on systems
	     with select(2)) it is used as a prefix character
	     with rl_execute_next.  WATCH OUT FOR THIS!  This is intended
	     to allow the arrow keys to be used like ^F and ^B are used
	     to terminate the search and execute the movement command.
	     XXX - since _rl_input_available depends on the application-
	     settable keyboard timeout value, this could alternatively
	     use _rl_input_queued(100000) */
	  if (c == ESC && _rl_input_available ())
	    rl_execute_next (ESC);
	  break;
	}

#define ENDSRCH_CHAR(c) \
  ((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))

#if defined (HANDLE_MULTIBYTE)
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
	{
	  if (c >= 0 && strlen (mb) == 1 && ENDSRCH_CHAR (c))
	    {
	      /* This sets rl_pending_input to c; it will be picked up the next
		 time rl_read_key is called. */
	      rl_execute_next (c);
	      break;
	    }
	}
      else
#endif
      if (c >= 0 && ENDSRCH_CHAR (c))
	{
	  /* This sets rl_pending_input to c; it will be picked up the next
	     time rl_read_key is called. */
	  rl_execute_next (c);
	  break;
	}

      switch (c)
	{
	case -1:
	  if (search_string_index == 0)
	    {
	      if (last_isearch_string)
		{
		  search_string_size = 64 + last_isearch_string_len;
		  search_string = (char *)xrealloc (search_string, search_string_size);
		  strcpy (search_string, last_isearch_string);
		  search_string_index = last_isearch_string_len;
		  rl_display_search (search_string, reverse, -1);
		  break;
		}
	      continue;
	    }
	  else if (reverse)
	    --line_index;
	  else if (line_index != sline_len)
	    ++line_index;
	  else
	    rl_ding ();
	  break;

	  /* switch directions */
	case -2:
	  direction = -direction;
	  reverse = direction < 0;
	  break;

	/* delete character from search string. */
	case -3:	/* C-H, DEL */
	  /* This is tricky.  To do this right, we need to keep a
	     stack of search positions for the current search, with
	     sentinels marking the beginning and end.  But this will
	     do until we have a real isearch-undo. */
	  if (search_string_index == 0)
	    rl_ding ();
	  else
	    search_string[--search_string_index] = '\0';

	  break;

	case -4:	/* C-G */
	  rl_replace_line (lines[orig_line], 0);
	  rl_point = orig_point;
	  rl_mark = orig_mark;
	  rl_restore_prompt();
	  rl_clear_message ();
	  if (allocated_line)
	    free (allocated_line);
	  free (lines);
	  RL_UNSETSTATE(RL_STATE_ISEARCH);
	  return 0;

	case -5:	/* C-W */
	  /* skip over portion of line we already matched */
	  wstart = rl_point + search_string_index;
	  if (wstart >= rl_end)
	    {
	      rl_ding ();
	      break;
	    }

	  /* if not in a word, move to one. */
	  if (rl_alphabetic(rl_line_buffer[wstart]) == 0)
	    {
	      rl_ding ();
	      break;
	    }
	  n = wstart;
	  while (n < rl_end && rl_alphabetic(rl_line_buffer[n]))
	    n++;
	  wlen = n - wstart + 1;
	  if (search_string_index + wlen + 1 >= search_string_size)
	    {
	      search_string_size += wlen + 1;
	      search_string = (char *)xrealloc (search_string, search_string_size);
	    }
	  for (; wstart < n; wstart++)
	    search_string[search_string_index++] = rl_line_buffer[wstart];
	  search_string[search_string_index] = '\0';
	  break;

	case -6:	/* C-Y */
	  /* skip over portion of line we already matched */
	  wstart = rl_point + search_string_index;
	  if (wstart >= rl_end)
	    {
	      rl_ding ();
	      break;
	    }
	  n = rl_end - wstart + 1;
	  if (search_string_index + n + 1 >= search_string_size)
	    {
	      search_string_size += n + 1;
	      search_string = (char *)xrealloc (search_string, search_string_size);
	    }
	  for (n = wstart; n < rl_end; n++)
	    search_string[search_string_index++] = rl_line_buffer[n];
	  search_string[search_string_index] = '\0';
	  break;

	default:
	  /* Add character to search string and continue search. */
	  if (search_string_index + 2 >= search_string_size)
	    {
	      search_string_size += 128;
	      search_string = (char *)xrealloc (search_string, search_string_size);
	    }
#if defined (HANDLE_MULTIBYTE)
	  if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
	    {
	      int j, l;
	      for (j = 0, l = strlen (mb); j < l; )
		search_string[search_string_index++] = mb[j++];
	    }
	  else
#endif
	    search_string[search_string_index++] = c;
	  search_string[search_string_index] = '\0';
	  break;
	}

      for (found = failed = 0;;)
	{
	  int limit = sline_len - search_string_index + 1;

	  /* 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 += direction;
	    }
	  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) : (i == hlen))
		{
		  failed++;
		  break;
		}

	      /* 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 (failed)
	    break;

	  /* Now set up the line for searching... */
	  line_index = reverse ? sline_len - search_string_index : 0;
	}

      if (failed)
	{
	  /* We cannot find the search string.  Ding the bell. */
	  rl_ding ();
	  i = last_found_line;
	  continue; 		/* XXX - was break */
	}

      /* 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)
	{
	  prev_line_found = lines[i];
	  rl_replace_line (lines[i], 0);
	  rl_point = line_index;
	  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
     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]);

  rl_restore_prompt ();

  /* Save the search string for possible later use. */
  FREE (last_isearch_string);
  last_isearch_string = search_string;
  last_isearch_string_len = search_string_index;

  if (last_found_line < orig_line)
    rl_get_previous_history (orig_line - last_found_line, 0);
  else
    rl_get_next_history (last_found_line - orig_line, 0);

  /* If the string was not found, put point at the end of the last matching
     line.  If last_found_line == orig_line, we didn't find any matching
     history lines at all, so put point back in its original position. */
  if (line_index < 0)
    {
      if (last_found_line == orig_line)
	line_index = orig_point;
      else
	line_index = strlen (rl_line_buffer);
      rl_mark = orig_mark;
    }

  rl_point = line_index;
  /* Don't worry about where to put the mark here; rl_get_previous_history
     and rl_get_next_history take care of it. */

  rl_clear_message ();

  FREE (allocated_line);
  free (lines);

  RL_UNSETSTATE(RL_STATE_ISEARCH);

  return 0;
}
