/* misc.c -- miscellaneous bindable readline functions. */

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

   This file is part of the GNU Readline Library (Readline), a library
   for reading lines of text with interactive input and history editing.      

   Readline 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 3 of the License, or
   (at your option) any later version.

   Readline 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.

   You should have received a copy of the GNU General Public License
   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
*/

#define READLINE_LIBRARY

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

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

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

#if defined (HAVE_LOCALE_H)
#  include <locale.h>
#endif

#include <stdio.h>

/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"

/* Some standard library routines. */
#include "readline.h"
#include "history.h"

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

static int rl_digit_loop PARAMS((void));
static void _rl_history_set_point PARAMS((void));

/* Forward declarations used in this file */
void _rl_free_history_entry PARAMS((HIST_ENTRY *));

/* If non-zero, rl_get_previous_history and rl_get_next_history attempt
   to preserve the value of rl_point from line to line. */
int _rl_history_preserve_point = 0;

_rl_arg_cxt _rl_argcxt;

/* Saved target point for when _rl_history_preserve_point is set.  Special
   value of -1 means that point is at the end of the line. */
int _rl_history_saved_point = -1;

/* **************************************************************** */
/*								    */
/*			Numeric Arguments			    */
/*								    */
/* **************************************************************** */

int
_rl_arg_overflow ()
{
  if (rl_numeric_arg > 1000000)
    {
      _rl_argcxt = 0;
      rl_explicit_arg = rl_numeric_arg = 0;
      rl_ding ();
      rl_restore_prompt ();
      rl_clear_message ();
      RL_UNSETSTATE(RL_STATE_NUMERICARG);
      return 1;
    }
  return 0;
}

void
_rl_arg_init ()
{
  rl_save_prompt ();
  _rl_argcxt = 0;
  RL_SETSTATE(RL_STATE_NUMERICARG);
}

int
_rl_arg_getchar ()
{
  int c;

  rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
  RL_SETSTATE(RL_STATE_MOREINPUT);
  c = rl_read_key ();
  RL_UNSETSTATE(RL_STATE_MOREINPUT);

  return c;
}

/* Process C as part of the current numeric argument.  Return -1 if the
   argument should be aborted, 0 if we should not read any more chars, and
   1 if we should continue to read chars. */
int
_rl_arg_dispatch (cxt, c)
     _rl_arg_cxt cxt;
     int c;
{
  int key, r;

  key = c;

  /* If we see a key bound to `universal-argument' after seeing digits,
      it ends the argument but is otherwise ignored. */
  if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
    {
      if ((cxt & NUM_SAWDIGITS) == 0)
	{
	  rl_numeric_arg *= 4;
	  return 1;
	}
      else if (RL_ISSTATE (RL_STATE_CALLBACK))
        {
          _rl_argcxt |= NUM_READONE;
          return 0;	/* XXX */
        }
      else
	{
	  RL_SETSTATE(RL_STATE_MOREINPUT);
	  key = rl_read_key ();
	  RL_UNSETSTATE(RL_STATE_MOREINPUT);
	  rl_restore_prompt ();
	  rl_clear_message ();
	  RL_UNSETSTATE(RL_STATE_NUMERICARG);
	  if (key < 0)
	    return -1;
	  return (_rl_dispatch (key, _rl_keymap));
	}
    }

  c = UNMETA (c);

  if (_rl_digit_p (c))
    {
      r = _rl_digit_value (c);    	
      rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) +  r : r;
      rl_explicit_arg = 1;
      _rl_argcxt |= NUM_SAWDIGITS;
    }
  else if (c == '-' && rl_explicit_arg == 0)
    {
      rl_numeric_arg = 1;
      _rl_argcxt |= NUM_SAWMINUS;
      rl_arg_sign = -1;
    }
  else
    {
      /* Make M-- command equivalent to M--1 command. */
      if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
	rl_explicit_arg = 1;
      rl_restore_prompt ();
      rl_clear_message ();
      RL_UNSETSTATE(RL_STATE_NUMERICARG);

      r = _rl_dispatch (key, _rl_keymap);
      if (RL_ISSTATE (RL_STATE_CALLBACK))
	{
	  /* At worst, this will cause an extra redisplay.  Otherwise,
	     we have to wait until the next character comes in. */
	  if (rl_done == 0)
	    (*rl_redisplay_function) ();
	  r = 0;
	}
      return r;
    }

  return 1;
}

/* Handle C-u style numeric args, as well as M--, and M-digits. */
static int
rl_digit_loop ()
{
  int c, r;

  while (1)
    {
      if (_rl_arg_overflow ())
	return 1;

      c = _rl_arg_getchar ();

      if (c < 0)
	{
	  _rl_abort_internal ();
	  return -1;
	}

      r = _rl_arg_dispatch (_rl_argcxt, c);
      if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
        break;
    }

  return r;
}

/* Create a default argument. */
void
_rl_reset_argument ()
{
  rl_numeric_arg = rl_arg_sign = 1;
  rl_explicit_arg = 0;
  _rl_argcxt = 0;
}

/* Start a numeric argument with initial value KEY */
int
rl_digit_argument (ignore, key)
     int ignore, key;
{
  _rl_arg_init ();
  if (RL_ISSTATE (RL_STATE_CALLBACK))
    {
      _rl_arg_dispatch (_rl_argcxt, key);
      rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
      return 0;
    }
  else
    {
      rl_execute_next (key);
      return (rl_digit_loop ());
    }
}

/* C-u, universal argument.  Multiply the current argument by 4.
   Read a key.  If the key has nothing to do with arguments, then
   dispatch on it.  If the key is the abort character then abort. */
int
rl_universal_argument (count, key)
     int count, key;
{
  _rl_arg_init ();
  rl_numeric_arg *= 4;

  return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
}

int
_rl_arg_callback (cxt)
     _rl_arg_cxt cxt;
{
  int c, r;

  c = _rl_arg_getchar ();

  if (_rl_argcxt & NUM_READONE)
    {
      _rl_argcxt &= ~NUM_READONE;
      rl_restore_prompt ();
      rl_clear_message ();
      RL_UNSETSTATE(RL_STATE_NUMERICARG);
      rl_execute_next (c);
      return 0;
    }

  r = _rl_arg_dispatch (cxt, c);
  return (r != 1);
}

/* What to do when you abort reading an argument. */
int
rl_discard_argument ()
{
  rl_ding ();
  rl_clear_message ();
  _rl_reset_argument ();

  return 0;
}

/* **************************************************************** */
/*								    */
/*			History Utilities			    */
/*								    */
/* **************************************************************** */

/* We already have a history library, and that is what we use to control
   the history features of readline.  This is our local interface to
   the history mechanism. */

/* While we are editing the history, this is the saved
   version of the original line. */
HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;

/* Set the history pointer back to the last entry in the history. */
void
_rl_start_using_history ()
{
  using_history ();
  if (_rl_saved_line_for_history)
    _rl_free_history_entry (_rl_saved_line_for_history);

  _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}

/* Free the contents (and containing structure) of a HIST_ENTRY. */
void
_rl_free_history_entry (entry)
     HIST_ENTRY *entry;
{
  if (entry == 0)
    return;

  FREE (entry->line);
  FREE (entry->timestamp);

  xfree (entry);
}

/* Perhaps put back the current line if it has changed. */
int
rl_maybe_replace_line ()
{
  HIST_ENTRY *temp;

  temp = current_history ();
  /* If the current line has changed, save the changes. */
  if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
    {
      temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
      xfree (temp->line);
      FREE (temp->timestamp);
      xfree (temp);
    }
  return 0;
}

/* Restore the _rl_saved_line_for_history if there is one. */
int
rl_maybe_unsave_line ()
{
  if (_rl_saved_line_for_history)
    {
      /* Can't call with `1' because rl_undo_list might point to an undo
	 list from a history entry, as in rl_replace_from_history() below. */
      rl_replace_line (_rl_saved_line_for_history->line, 0);
      rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
      _rl_free_history_entry (_rl_saved_line_for_history);
      _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
      rl_point = rl_end;	/* rl_replace_line sets rl_end */
    }
  else
    rl_ding ();
  return 0;
}

/* Save the current line in _rl_saved_line_for_history. */
int
rl_maybe_save_line ()
{
  if (_rl_saved_line_for_history == 0)
    {
      _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
      _rl_saved_line_for_history->line = savestring (rl_line_buffer);
      _rl_saved_line_for_history->timestamp = (char *)NULL;
      _rl_saved_line_for_history->data = (char *)rl_undo_list;
    }

  return 0;
}

int
_rl_free_saved_history_line ()
{
  if (_rl_saved_line_for_history)
    {
      _rl_free_history_entry (_rl_saved_line_for_history);
      _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
    }
  return 0;
}

static void
_rl_history_set_point ()
{
  rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
		? _rl_history_saved_point
		: rl_end;
  if (rl_point > rl_end)
    rl_point = rl_end;

#if defined (VI_MODE)
  if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
    rl_point = 0;
#endif /* VI_MODE */

  if (rl_editing_mode == emacs_mode)
    rl_mark = (rl_point == rl_end ? 0 : rl_end);
}

void
rl_replace_from_history (entry, flags)
     HIST_ENTRY *entry;
     int flags;			/* currently unused */
{
  /* Can't call with `1' because rl_undo_list might point to an undo list
     from a history entry, just like we're setting up here. */
  rl_replace_line (entry->line, 0);
  rl_undo_list = (UNDO_LIST *)entry->data;
  rl_point = rl_end;
  rl_mark = 0;

#if defined (VI_MODE)
  if (rl_editing_mode == vi_mode)
    {
      rl_point = 0;
      rl_mark = rl_end;
    }
#endif
}

/* Process and free undo lists attached to each history entry prior to the
   current entry, inclusive, reverting each line to its saved state.  This 
   is destructive, and state about the current line is lost.  This is not
   intended to be called while actively editing, and the current line is
   not assumed to have been added to the history list. */
void
_rl_revert_all_lines ()
{
  int hpos;
  HIST_ENTRY *entry;
  UNDO_LIST *ul, *saved_undo_list;
  char *lbuf;

  lbuf = savestring (rl_line_buffer);
  saved_undo_list = rl_undo_list;
  hpos = where_history ();

  entry = (hpos == history_length) ? previous_history () : current_history ();
  while (entry)
    {
      if (ul = (UNDO_LIST *)entry->data)
	{
	  if (ul == saved_undo_list)
	    saved_undo_list = 0;
	  /* Set up rl_line_buffer and other variables from history entry */
	  rl_replace_from_history (entry, 0);	/* entry->line is now current */
	  /* Undo all changes to this history entry */
	  while (rl_undo_list)
	    rl_do_undo ();
	  /* And copy the reverted line back to the history entry, preserving
	     the timestamp. */
	  FREE (entry->line);
	  entry->line = savestring (rl_line_buffer);
	  entry->data = 0;
	}
      entry = previous_history ();
    }

  /* Restore history state */
  rl_undo_list = saved_undo_list;	/* may have been set to null */
  history_set_pos (hpos);
  
  /* reset the line buffer */
  rl_replace_line (lbuf, 0);
  _rl_set_the_line ();

  /* and clean up */
  xfree (lbuf);
}  

/* **************************************************************** */
/*								    */
/*			History Commands			    */
/*								    */
/* **************************************************************** */

/* Meta-< goes to the start of the history. */
int
rl_beginning_of_history (count, key)
     int count, key;
{
  return (rl_get_previous_history (1 + where_history (), key));
}

/* Meta-> goes to the end of the history.  (The current line). */
int
rl_end_of_history (count, key)
     int count, key;
{
  rl_maybe_replace_line ();
  using_history ();
  rl_maybe_unsave_line ();
  return 0;
}

/* Move down to the next history line. */
int
rl_get_next_history (count, key)
     int count, key;
{
  HIST_ENTRY *temp;

  if (count < 0)
    return (rl_get_previous_history (-count, key));

  if (count == 0)
    return 0;

  rl_maybe_replace_line ();

  /* either not saved by rl_newline or at end of line, so set appropriately. */
  if (_rl_history_saved_point == -1 && (rl_point || rl_end))
    _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;

  temp = (HIST_ENTRY *)NULL;
  while (count)
    {
      temp = next_history ();
      if (!temp)
	break;
      --count;
    }

  if (temp == 0)
    rl_maybe_unsave_line ();
  else
    {
      rl_replace_from_history (temp, 0);
      _rl_history_set_point ();
    }
  return 0;
}

/* Get the previous item out of our interactive history, making it the current
   line.  If there is no previous history, just ding. */
int
rl_get_previous_history (count, key)
     int count, key;
{
  HIST_ENTRY *old_temp, *temp;

  if (count < 0)
    return (rl_get_next_history (-count, key));

  if (count == 0)
    return 0;

  /* either not saved by rl_newline or at end of line, so set appropriately. */
  if (_rl_history_saved_point == -1 && (rl_point || rl_end))
    _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;

  /* If we don't have a line saved, then save this one. */
  rl_maybe_save_line ();

  /* If the current line has changed, save the changes. */
  rl_maybe_replace_line ();

  temp = old_temp = (HIST_ENTRY *)NULL;
  while (count)
    {
      temp = previous_history ();
      if (temp == 0)
	break;

      old_temp = temp;
      --count;
    }

  /* If there was a large argument, and we moved back to the start of the
     history, that is not an error.  So use the last value found. */
  if (!temp && old_temp)
    temp = old_temp;

  if (temp == 0)
    rl_ding ();
  else
    {
      rl_replace_from_history (temp, 0);
      _rl_history_set_point ();
    }

  return 0;
}

/* **************************************************************** */
/*								    */
/*			    Editing Modes			    */
/*								    */
/* **************************************************************** */
/* How to toggle back and forth between editing modes. */
int
rl_vi_editing_mode (count, key)
     int count, key;
{
#if defined (VI_MODE)
  _rl_set_insert_mode (RL_IM_INSERT, 1);	/* vi mode ignores insert mode */
  rl_editing_mode = vi_mode;
  rl_vi_insert_mode (1, key);
#endif /* VI_MODE */

  return 0;
}

int
rl_emacs_editing_mode (count, key)
     int count, key;
{
  rl_editing_mode = emacs_mode;
  _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
  _rl_keymap = emacs_standard_keymap;
  return 0;
}

/* Function for the rest of the library to use to set insert/overwrite mode. */
void
_rl_set_insert_mode (im, force)
     int im, force;
{
#ifdef CURSOR_MODE
  _rl_set_cursor (im, force);
#endif

  rl_insert_mode = im;
}

/* Toggle overwrite mode.  A positive explicit argument selects overwrite
   mode.  A negative or zero explicit argument selects insert mode. */
int
rl_overwrite_mode (count, key)
     int count, key;
{
  if (rl_explicit_arg == 0)
    _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
  else if (count > 0)
    _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
  else
    _rl_set_insert_mode (RL_IM_INSERT, 0);

  return 0;
}
