OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [readline/] [text.c] - Diff between revs 827 and 840

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 827 Rev 840
/* text.c -- text handling commands for readline. */
/* text.c -- text handling commands for readline. */
 
 
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
 
 
   This file is part of the GNU Readline Library, a library for
   This file is part of the GNU Readline Library, a library for
   reading lines of text with interactive input and history editing.
   reading lines of text with interactive input and history editing.
 
 
   The GNU Readline Library is free software; you can redistribute it
   The GNU Readline Library is free software; you can redistribute it
   and/or modify it under the terms of the GNU General Public License
   and/or modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; either version 2, or
   as published by the Free Software Foundation; either version 2, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   The GNU Readline Library is distributed in the hope that it will be
   The GNU Readline Library is distributed in the hope that it will be
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   The GNU General Public License is often shipped with GNU software, and
   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
   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,
   have a copy of the license, write to the Free Software Foundation,
   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#define READLINE_LIBRARY
 
 
#if defined (HAVE_CONFIG_H)
#if defined (HAVE_CONFIG_H)
#  include <config.h>
#  include <config.h>
#endif
#endif
 
 
#if defined (HAVE_UNISTD_H)
#if defined (HAVE_UNISTD_H)
#  include <unistd.h>
#  include <unistd.h>
#endif /* HAVE_UNISTD_H */
#endif /* HAVE_UNISTD_H */
 
 
#if defined (HAVE_STDLIB_H)
#if defined (HAVE_STDLIB_H)
#  include <stdlib.h>
#  include <stdlib.h>
#else
#else
#  include "ansi_stdlib.h"
#  include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#endif /* HAVE_STDLIB_H */
 
 
#if defined (HAVE_LOCALE_H)
#if defined (HAVE_LOCALE_H)
#  include <locale.h>
#  include <locale.h>
#endif
#endif
 
 
#include <stdio.h>
#include <stdio.h>
 
 
/* System-specific feature definitions and include files. */
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rldefs.h"
#include "rlmbutil.h"
#include "rlmbutil.h"
 
 
#if defined (__EMX__)
#if defined (__EMX__)
#  define INCL_DOSPROCESS
#  define INCL_DOSPROCESS
#  include <os2.h>
#  include <os2.h>
#endif /* __EMX__ */
#endif /* __EMX__ */
 
 
/* Some standard library routines. */
/* Some standard library routines. */
#include "readline.h"
#include "readline.h"
#include "history.h"
#include "history.h"
 
 
#include "rlprivate.h"
#include "rlprivate.h"
#include "rlshell.h"
#include "rlshell.h"
#include "xmalloc.h"
#include "xmalloc.h"
 
 
/* Forward declarations. */
/* Forward declarations. */
static int rl_change_case PARAMS((int, int));
static int rl_change_case PARAMS((int, int));
static int _rl_char_search PARAMS((int, int, int));
static int _rl_char_search PARAMS((int, int, int));
 
 
#if defined (READLINE_CALLBACKS)
#if defined (READLINE_CALLBACKS)
static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *));
static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *));
static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *));
static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *));
#endif
#endif
 
 
/* **************************************************************** */
/* **************************************************************** */
/*                                                                  */
/*                                                                  */
/*                      Insert and Delete                           */
/*                      Insert and Delete                           */
/*                                                                  */
/*                                                                  */
/* **************************************************************** */
/* **************************************************************** */
 
 
/* Insert a string of text into the line at point.  This is the only
/* Insert a string of text into the line at point.  This is the only
   way that you should do insertion.  _rl_insert_char () calls this
   way that you should do insertion.  _rl_insert_char () calls this
   function.  Returns the number of characters inserted. */
   function.  Returns the number of characters inserted. */
int
int
rl_insert_text (string)
rl_insert_text (string)
     const char *string;
     const char *string;
{
{
  register int i, l;
  register int i, l;
 
 
  l = (string && *string) ? strlen (string) : 0;
  l = (string && *string) ? strlen (string) : 0;
  if (l == 0)
  if (l == 0)
    return 0;
    return 0;
 
 
  if (rl_end + l >= rl_line_buffer_len)
  if (rl_end + l >= rl_line_buffer_len)
    rl_extend_line_buffer (rl_end + l);
    rl_extend_line_buffer (rl_end + l);
 
 
  for (i = rl_end; i >= rl_point; i--)
  for (i = rl_end; i >= rl_point; i--)
    rl_line_buffer[i + l] = rl_line_buffer[i];
    rl_line_buffer[i + l] = rl_line_buffer[i];
  strncpy (rl_line_buffer + rl_point, string, l);
  strncpy (rl_line_buffer + rl_point, string, l);
 
 
  /* Remember how to undo this if we aren't undoing something. */
  /* Remember how to undo this if we aren't undoing something. */
  if (_rl_doing_an_undo == 0)
  if (_rl_doing_an_undo == 0)
    {
    {
      /* If possible and desirable, concatenate the undos. */
      /* If possible and desirable, concatenate the undos. */
      if ((l == 1) &&
      if ((l == 1) &&
          rl_undo_list &&
          rl_undo_list &&
          (rl_undo_list->what == UNDO_INSERT) &&
          (rl_undo_list->what == UNDO_INSERT) &&
          (rl_undo_list->end == rl_point) &&
          (rl_undo_list->end == rl_point) &&
          (rl_undo_list->end - rl_undo_list->start < 20))
          (rl_undo_list->end - rl_undo_list->start < 20))
        rl_undo_list->end++;
        rl_undo_list->end++;
      else
      else
        rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
        rl_add_undo (UNDO_INSERT, rl_point, rl_point + l, (char *)NULL);
    }
    }
  rl_point += l;
  rl_point += l;
  rl_end += l;
  rl_end += l;
  rl_line_buffer[rl_end] = '\0';
  rl_line_buffer[rl_end] = '\0';
  return l;
  return l;
}
}
 
 
/* Delete the string between FROM and TO.  FROM is inclusive, TO is not.
/* Delete the string between FROM and TO.  FROM is inclusive, TO is not.
   Returns the number of characters deleted. */
   Returns the number of characters deleted. */
int
int
rl_delete_text (from, to)
rl_delete_text (from, to)
     int from, to;
     int from, to;
{
{
  register char *text;
  register char *text;
  register int diff, i;
  register int diff, i;
 
 
  /* Fix it if the caller is confused. */
  /* Fix it if the caller is confused. */
  if (from > to)
  if (from > to)
    SWAP (from, to);
    SWAP (from, to);
 
 
  /* fix boundaries */
  /* fix boundaries */
  if (to > rl_end)
  if (to > rl_end)
    {
    {
      to = rl_end;
      to = rl_end;
      if (from > to)
      if (from > to)
        from = to;
        from = to;
    }
    }
  if (from < 0)
  if (from < 0)
    from = 0;
    from = 0;
 
 
  text = rl_copy_text (from, to);
  text = rl_copy_text (from, to);
 
 
  /* Some versions of strncpy() can't handle overlapping arguments. */
  /* Some versions of strncpy() can't handle overlapping arguments. */
  diff = to - from;
  diff = to - from;
  for (i = from; i < rl_end - diff; i++)
  for (i = from; i < rl_end - diff; i++)
    rl_line_buffer[i] = rl_line_buffer[i + diff];
    rl_line_buffer[i] = rl_line_buffer[i + diff];
 
 
  /* Remember how to undo this delete. */
  /* Remember how to undo this delete. */
  if (_rl_doing_an_undo == 0)
  if (_rl_doing_an_undo == 0)
    rl_add_undo (UNDO_DELETE, from, to, text);
    rl_add_undo (UNDO_DELETE, from, to, text);
  else
  else
    free (text);
    free (text);
 
 
  rl_end -= diff;
  rl_end -= diff;
  rl_line_buffer[rl_end] = '\0';
  rl_line_buffer[rl_end] = '\0';
  return (diff);
  return (diff);
}
}
 
 
/* Fix up point so that it is within the line boundaries after killing
/* Fix up point so that it is within the line boundaries after killing
   text.  If FIX_MARK_TOO is non-zero, the mark is forced within line
   text.  If FIX_MARK_TOO is non-zero, the mark is forced within line
   boundaries also. */
   boundaries also. */
 
 
#define _RL_FIX_POINT(x) \
#define _RL_FIX_POINT(x) \
        do { \
        do { \
        if (x > rl_end) \
        if (x > rl_end) \
          x = rl_end; \
          x = rl_end; \
        else if (x < 0) \
        else if (x < 0) \
          x = 0; \
          x = 0; \
        } while (0)
        } while (0)
 
 
void
void
_rl_fix_point (fix_mark_too)
_rl_fix_point (fix_mark_too)
     int fix_mark_too;
     int fix_mark_too;
{
{
  _RL_FIX_POINT (rl_point);
  _RL_FIX_POINT (rl_point);
  if (fix_mark_too)
  if (fix_mark_too)
    _RL_FIX_POINT (rl_mark);
    _RL_FIX_POINT (rl_mark);
}
}
#undef _RL_FIX_POINT
#undef _RL_FIX_POINT
 
 
/* Replace the contents of the line buffer between START and END with
/* Replace the contents of the line buffer between START and END with
   TEXT.  The operation is undoable.  To replace the entire line in an
   TEXT.  The operation is undoable.  To replace the entire line in an
   undoable mode, use _rl_replace_text(text, 0, rl_end); */
   undoable mode, use _rl_replace_text(text, 0, rl_end); */
int
int
_rl_replace_text (text, start, end)
_rl_replace_text (text, start, end)
     const char *text;
     const char *text;
     int start, end;
     int start, end;
{
{
  int n;
  int n;
 
 
  rl_begin_undo_group ();
  rl_begin_undo_group ();
  rl_delete_text (start, end + 1);
  rl_delete_text (start, end + 1);
  rl_point = start;
  rl_point = start;
  n = rl_insert_text (text);
  n = rl_insert_text (text);
  rl_end_undo_group ();
  rl_end_undo_group ();
 
 
  return n;
  return n;
}
}
 
 
/* Replace the current line buffer contents with TEXT.  If CLEAR_UNDO is
/* Replace the current line buffer contents with TEXT.  If CLEAR_UNDO is
   non-zero, we free the current undo list. */
   non-zero, we free the current undo list. */
void
void
rl_replace_line (text, clear_undo)
rl_replace_line (text, clear_undo)
     const char *text;
     const char *text;
     int clear_undo;
     int clear_undo;
{
{
  int len;
  int len;
 
 
  len = strlen (text);
  len = strlen (text);
  if (len >= rl_line_buffer_len)
  if (len >= rl_line_buffer_len)
    rl_extend_line_buffer (len);
    rl_extend_line_buffer (len);
  strcpy (rl_line_buffer, text);
  strcpy (rl_line_buffer, text);
  rl_end = len;
  rl_end = len;
 
 
  if (clear_undo)
  if (clear_undo)
    rl_free_undo_list ();
    rl_free_undo_list ();
 
 
  _rl_fix_point (1);
  _rl_fix_point (1);
}
}
 
 
/* **************************************************************** */
/* **************************************************************** */
/*                                                                  */
/*                                                                  */
/*                      Readline character functions                */
/*                      Readline character functions                */
/*                                                                  */
/*                                                                  */
/* **************************************************************** */
/* **************************************************************** */
 
 
/* This is not a gap editor, just a stupid line input routine.  No hair
/* This is not a gap editor, just a stupid line input routine.  No hair
   is involved in writing any of the functions, and none should be. */
   is involved in writing any of the functions, and none should be. */
 
 
/* Note that:
/* Note that:
 
 
   rl_end is the place in the string that we would place '\0';
   rl_end is the place in the string that we would place '\0';
   i.e., it is always safe to place '\0' there.
   i.e., it is always safe to place '\0' there.
 
 
   rl_point is the place in the string where the cursor is.  Sometimes
   rl_point is the place in the string where the cursor is.  Sometimes
   this is the same as rl_end.
   this is the same as rl_end.
 
 
   Any command that is called interactively receives two arguments.
   Any command that is called interactively receives two arguments.
   The first is a count: the numeric arg pased to this command.
   The first is a count: the numeric arg pased to this command.
   The second is the key which invoked this command.
   The second is the key which invoked this command.
*/
*/
 
 
/* **************************************************************** */
/* **************************************************************** */
/*                                                                  */
/*                                                                  */
/*                      Movement Commands                           */
/*                      Movement Commands                           */
/*                                                                  */
/*                                                                  */
/* **************************************************************** */
/* **************************************************************** */
 
 
/* Note that if you `optimize' the display for these functions, you cannot
/* Note that if you `optimize' the display for these functions, you cannot
   use said functions in other functions which do not do optimizing display.
   use said functions in other functions which do not do optimizing display.
   I.e., you will have to update the data base for rl_redisplay, and you
   I.e., you will have to update the data base for rl_redisplay, and you
   might as well let rl_redisplay do that job. */
   might as well let rl_redisplay do that job. */
 
 
/* Move forward COUNT bytes. */
/* Move forward COUNT bytes. */
int
int
rl_forward_byte (count, key)
rl_forward_byte (count, key)
     int count, key;
     int count, key;
{
{
  if (count < 0)
  if (count < 0)
    return (rl_backward_byte (-count, key));
    return (rl_backward_byte (-count, key));
 
 
  if (count > 0)
  if (count > 0)
    {
    {
      int end = rl_point + count;
      int end = rl_point + count;
#if defined (VI_MODE)
#if defined (VI_MODE)
      int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end;
      int lend = rl_end > 0 ? rl_end - (rl_editing_mode == vi_mode) : rl_end;
#else
#else
      int lend = rl_end;
      int lend = rl_end;
#endif
#endif
 
 
      if (end > lend)
      if (end > lend)
        {
        {
          rl_point = lend;
          rl_point = lend;
          rl_ding ();
          rl_ding ();
        }
        }
      else
      else
        rl_point = end;
        rl_point = end;
    }
    }
 
 
  if (rl_end < 0)
  if (rl_end < 0)
    rl_end = 0;
    rl_end = 0;
 
 
  return 0;
  return 0;
}
}
 
 
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
/* Move forward COUNT characters. */
/* Move forward COUNT characters. */
int
int
rl_forward_char (count, key)
rl_forward_char (count, key)
     int count, key;
     int count, key;
{
{
  int point;
  int point;
 
 
  if (MB_CUR_MAX == 1 || rl_byte_oriented)
  if (MB_CUR_MAX == 1 || rl_byte_oriented)
    return (rl_forward_byte (count, key));
    return (rl_forward_byte (count, key));
 
 
  if (count < 0)
  if (count < 0)
    return (rl_backward_char (-count, key));
    return (rl_backward_char (-count, key));
 
 
  if (count > 0)
  if (count > 0)
    {
    {
      point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
      point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
 
 
#if defined (VI_MODE)
#if defined (VI_MODE)
      if (rl_end <= point && rl_editing_mode == vi_mode)
      if (rl_end <= point && rl_editing_mode == vi_mode)
        point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
        point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
#endif
#endif
 
 
      if (rl_point == point)
      if (rl_point == point)
        rl_ding ();
        rl_ding ();
 
 
      rl_point = point;
      rl_point = point;
 
 
      if (rl_end < 0)
      if (rl_end < 0)
        rl_end = 0;
        rl_end = 0;
    }
    }
 
 
  return 0;
  return 0;
}
}
#else /* !HANDLE_MULTIBYTE */
#else /* !HANDLE_MULTIBYTE */
int
int
rl_forward_char (count, key)
rl_forward_char (count, key)
     int count, key;
     int count, key;
{
{
  return (rl_forward_byte (count, key));
  return (rl_forward_byte (count, key));
}
}
#endif /* !HANDLE_MULTIBYTE */
#endif /* !HANDLE_MULTIBYTE */
 
 
/* Backwards compatibility. */
/* Backwards compatibility. */
int
int
rl_forward (count, key)
rl_forward (count, key)
     int count, key;
     int count, key;
{
{
  return (rl_forward_char (count, key));
  return (rl_forward_char (count, key));
}
}
 
 
/* Move backward COUNT bytes. */
/* Move backward COUNT bytes. */
int
int
rl_backward_byte (count, key)
rl_backward_byte (count, key)
     int count, key;
     int count, key;
{
{
  if (count < 0)
  if (count < 0)
    return (rl_forward_byte (-count, key));
    return (rl_forward_byte (-count, key));
 
 
  if (count > 0)
  if (count > 0)
    {
    {
      if (rl_point < count)
      if (rl_point < count)
        {
        {
          rl_point = 0;
          rl_point = 0;
          rl_ding ();
          rl_ding ();
        }
        }
      else
      else
        rl_point -= count;
        rl_point -= count;
    }
    }
 
 
  if (rl_point < 0)
  if (rl_point < 0)
    rl_point = 0;
    rl_point = 0;
 
 
  return 0;
  return 0;
}
}
 
 
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
/* Move backward COUNT characters. */
/* Move backward COUNT characters. */
int
int
rl_backward_char (count, key)
rl_backward_char (count, key)
     int count, key;
     int count, key;
{
{
  int point;
  int point;
 
 
  if (MB_CUR_MAX == 1 || rl_byte_oriented)
  if (MB_CUR_MAX == 1 || rl_byte_oriented)
    return (rl_backward_byte (count, key));
    return (rl_backward_byte (count, key));
 
 
  if (count < 0)
  if (count < 0)
    return (rl_forward_char (-count, key));
    return (rl_forward_char (-count, key));
 
 
  if (count > 0)
  if (count > 0)
    {
    {
      point = rl_point;
      point = rl_point;
 
 
      while (count > 0 && point > 0)
      while (count > 0 && point > 0)
        {
        {
          point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
          point = _rl_find_prev_mbchar (rl_line_buffer, point, MB_FIND_NONZERO);
          count--;
          count--;
        }
        }
      if (count > 0)
      if (count > 0)
        {
        {
          rl_point = 0;
          rl_point = 0;
          rl_ding ();
          rl_ding ();
        }
        }
      else
      else
        rl_point = point;
        rl_point = point;
    }
    }
 
 
  return 0;
  return 0;
}
}
#else
#else
int
int
rl_backward_char (count, key)
rl_backward_char (count, key)
     int count, key;
     int count, key;
{
{
  return (rl_backward_byte (count, key));
  return (rl_backward_byte (count, key));
}
}
#endif
#endif
 
 
/* Backwards compatibility. */
/* Backwards compatibility. */
int
int
rl_backward (count, key)
rl_backward (count, key)
     int count, key;
     int count, key;
{
{
  return (rl_backward_char (count, key));
  return (rl_backward_char (count, key));
}
}
 
 
/* Move to the beginning of the line. */
/* Move to the beginning of the line. */
int
int
rl_beg_of_line (count, key)
rl_beg_of_line (count, key)
     int count, key;
     int count, key;
{
{
  rl_point = 0;
  rl_point = 0;
  return 0;
  return 0;
}
}
 
 
/* Move to the end of the line. */
/* Move to the end of the line. */
int
int
rl_end_of_line (count, key)
rl_end_of_line (count, key)
     int count, key;
     int count, key;
{
{
  rl_point = rl_end;
  rl_point = rl_end;
  return 0;
  return 0;
}
}
 
 
/* Move forward a word.  We do what Emacs does.  Handles multibyte chars. */
/* Move forward a word.  We do what Emacs does.  Handles multibyte chars. */
int
int
rl_forward_word (count, key)
rl_forward_word (count, key)
     int count, key;
     int count, key;
{
{
  int c;
  int c;
 
 
  if (count < 0)
  if (count < 0)
    return (rl_backward_word (-count, key));
    return (rl_backward_word (-count, key));
 
 
  while (count)
  while (count)
    {
    {
      if (rl_point == rl_end)
      if (rl_point == rl_end)
        return 0;
        return 0;
 
 
      /* If we are not in a word, move forward until we are in one.
      /* If we are not in a word, move forward until we are in one.
         Then, move forward until we hit a non-alphabetic character. */
         Then, move forward until we hit a non-alphabetic character. */
      c = _rl_char_value (rl_line_buffer, rl_point);
      c = _rl_char_value (rl_line_buffer, rl_point);
 
 
      if (_rl_walphabetic (c) == 0)
      if (_rl_walphabetic (c) == 0)
        {
        {
          rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
          rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
          while (rl_point < rl_end)
          while (rl_point < rl_end)
            {
            {
              c = _rl_char_value (rl_line_buffer, rl_point);
              c = _rl_char_value (rl_line_buffer, rl_point);
              if (_rl_walphabetic (c))
              if (_rl_walphabetic (c))
                break;
                break;
              rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
              rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
            }
            }
        }
        }
 
 
      if (rl_point == rl_end)
      if (rl_point == rl_end)
        return 0;
        return 0;
 
 
      rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
      rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
      while (rl_point < rl_end)
      while (rl_point < rl_end)
        {
        {
          c = _rl_char_value (rl_line_buffer, rl_point);
          c = _rl_char_value (rl_line_buffer, rl_point);
          if (_rl_walphabetic (c) == 0)
          if (_rl_walphabetic (c) == 0)
            break;
            break;
          rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
          rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
        }
        }
 
 
      --count;
      --count;
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
/* Move backward a word.  We do what Emacs does.  Handles multibyte chars. */
/* Move backward a word.  We do what Emacs does.  Handles multibyte chars. */
int
int
rl_backward_word (count, key)
rl_backward_word (count, key)
     int count, key;
     int count, key;
{
{
  int c, p;
  int c, p;
 
 
  if (count < 0)
  if (count < 0)
    return (rl_forward_word (-count, key));
    return (rl_forward_word (-count, key));
 
 
  while (count)
  while (count)
    {
    {
      if (rl_point == 0)
      if (rl_point == 0)
        return 0;
        return 0;
 
 
      /* Like rl_forward_word (), except that we look at the characters
      /* Like rl_forward_word (), except that we look at the characters
         just before point. */
         just before point. */
 
 
      p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
      p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
      c = _rl_char_value (rl_line_buffer, p);
      c = _rl_char_value (rl_line_buffer, p);
 
 
      if (_rl_walphabetic (c) == 0)
      if (_rl_walphabetic (c) == 0)
        {
        {
          rl_point = p;
          rl_point = p;
          while (rl_point > 0)
          while (rl_point > 0)
            {
            {
              p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
              p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
              c = _rl_char_value (rl_line_buffer, p);
              c = _rl_char_value (rl_line_buffer, p);
              if (_rl_walphabetic (c))
              if (_rl_walphabetic (c))
                break;
                break;
              rl_point = p;
              rl_point = p;
            }
            }
        }
        }
 
 
      while (rl_point)
      while (rl_point)
        {
        {
          p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
          p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
          c = _rl_char_value (rl_line_buffer, p);
          c = _rl_char_value (rl_line_buffer, p);
          if (_rl_walphabetic (c) == 0)
          if (_rl_walphabetic (c) == 0)
            break;
            break;
          else
          else
            rl_point = p;
            rl_point = p;
        }
        }
 
 
      --count;
      --count;
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
/* Clear the current line.  Numeric argument to C-l does this. */
/* Clear the current line.  Numeric argument to C-l does this. */
int
int
rl_refresh_line (ignore1, ignore2)
rl_refresh_line (ignore1, ignore2)
     int ignore1, ignore2;
     int ignore1, ignore2;
{
{
  int curr_line;
  int curr_line;
 
 
  curr_line = _rl_current_display_line ();
  curr_line = _rl_current_display_line ();
 
 
  _rl_move_vert (curr_line);
  _rl_move_vert (curr_line);
  _rl_move_cursor_relative (0, rl_line_buffer);   /* XXX is this right */
  _rl_move_cursor_relative (0, rl_line_buffer);   /* XXX is this right */
 
 
  _rl_clear_to_eol (0);          /* arg of 0 means to not use spaces */
  _rl_clear_to_eol (0);          /* arg of 0 means to not use spaces */
 
 
  rl_forced_update_display ();
  rl_forced_update_display ();
  rl_display_fixed = 1;
  rl_display_fixed = 1;
 
 
  return 0;
  return 0;
}
}
 
 
/* C-l typed to a line without quoting clears the screen, and then reprints
/* C-l typed to a line without quoting clears the screen, and then reprints
   the prompt and the current input line.  Given a numeric arg, redraw only
   the prompt and the current input line.  Given a numeric arg, redraw only
   the current line. */
   the current line. */
int
int
rl_clear_screen (count, key)
rl_clear_screen (count, key)
     int count, key;
     int count, key;
{
{
  if (rl_explicit_arg)
  if (rl_explicit_arg)
    {
    {
      rl_refresh_line (count, key);
      rl_refresh_line (count, key);
      return 0;
      return 0;
    }
    }
 
 
  _rl_clear_screen ();          /* calls termcap function to clear screen */
  _rl_clear_screen ();          /* calls termcap function to clear screen */
  rl_forced_update_display ();
  rl_forced_update_display ();
  rl_display_fixed = 1;
  rl_display_fixed = 1;
 
 
  return 0;
  return 0;
}
}
 
 
int
int
rl_arrow_keys (count, c)
rl_arrow_keys (count, c)
     int count, c;
     int count, c;
{
{
  int ch;
  int ch;
 
 
  RL_SETSTATE(RL_STATE_MOREINPUT);
  RL_SETSTATE(RL_STATE_MOREINPUT);
  ch = rl_read_key ();
  ch = rl_read_key ();
  RL_UNSETSTATE(RL_STATE_MOREINPUT);
  RL_UNSETSTATE(RL_STATE_MOREINPUT);
 
 
  switch (_rl_to_upper (ch))
  switch (_rl_to_upper (ch))
    {
    {
    case 'A':
    case 'A':
      rl_get_previous_history (count, ch);
      rl_get_previous_history (count, ch);
      break;
      break;
 
 
    case 'B':
    case 'B':
      rl_get_next_history (count, ch);
      rl_get_next_history (count, ch);
      break;
      break;
 
 
    case 'C':
    case 'C':
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
        rl_forward_char (count, ch);
        rl_forward_char (count, ch);
      else
      else
        rl_forward_byte (count, ch);
        rl_forward_byte (count, ch);
      break;
      break;
 
 
    case 'D':
    case 'D':
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
        rl_backward_char (count, ch);
        rl_backward_char (count, ch);
      else
      else
        rl_backward_byte (count, ch);
        rl_backward_byte (count, ch);
      break;
      break;
 
 
    default:
    default:
      rl_ding ();
      rl_ding ();
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
/* **************************************************************** */
/* **************************************************************** */
/*                                                                  */
/*                                                                  */
/*                      Text commands                               */
/*                      Text commands                               */
/*                                                                  */
/*                                                                  */
/* **************************************************************** */
/* **************************************************************** */
 
 
#ifdef HANDLE_MULTIBYTE
#ifdef HANDLE_MULTIBYTE
static char pending_bytes[MB_LEN_MAX];
static char pending_bytes[MB_LEN_MAX];
static int pending_bytes_length = 0;
static int pending_bytes_length = 0;
static mbstate_t ps = {0};
static mbstate_t ps = {0};
#endif
#endif
 
 
/* Insert the character C at the current location, moving point forward.
/* Insert the character C at the current location, moving point forward.
   If C introduces a multibyte sequence, we read the whole sequence and
   If C introduces a multibyte sequence, we read the whole sequence and
   then insert the multibyte char into the line buffer. */
   then insert the multibyte char into the line buffer. */
int
int
_rl_insert_char (count, c)
_rl_insert_char (count, c)
     int count, c;
     int count, c;
{
{
  register int i;
  register int i;
  char *string;
  char *string;
#ifdef HANDLE_MULTIBYTE
#ifdef HANDLE_MULTIBYTE
  int string_size;
  int string_size;
  char incoming[MB_LEN_MAX + 1];
  char incoming[MB_LEN_MAX + 1];
  int incoming_length = 0;
  int incoming_length = 0;
  mbstate_t ps_back;
  mbstate_t ps_back;
  static int stored_count = 0;
  static int stored_count = 0;
#endif
#endif
 
 
  if (count <= 0)
  if (count <= 0)
    return 0;
    return 0;
 
 
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
  if (MB_CUR_MAX == 1 || rl_byte_oriented)
  if (MB_CUR_MAX == 1 || rl_byte_oriented)
    {
    {
      incoming[0] = c;
      incoming[0] = c;
      incoming[1] = '\0';
      incoming[1] = '\0';
      incoming_length = 1;
      incoming_length = 1;
    }
    }
  else
  else
    {
    {
      wchar_t wc;
      wchar_t wc;
      size_t ret;
      size_t ret;
 
 
      if (stored_count <= 0)
      if (stored_count <= 0)
        stored_count = count;
        stored_count = count;
      else
      else
        count = stored_count;
        count = stored_count;
 
 
      ps_back = ps;
      ps_back = ps;
      pending_bytes[pending_bytes_length++] = c;
      pending_bytes[pending_bytes_length++] = c;
      ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
      ret = mbrtowc (&wc, pending_bytes, pending_bytes_length, &ps);
 
 
      if (ret == (size_t)-2)
      if (ret == (size_t)-2)
        {
        {
          /* Bytes too short to compose character, try to wait for next byte.
          /* Bytes too short to compose character, try to wait for next byte.
             Restore the state of the byte sequence, because in this case the
             Restore the state of the byte sequence, because in this case the
             effect of mbstate is undefined. */
             effect of mbstate is undefined. */
          ps = ps_back;
          ps = ps_back;
          return 1;
          return 1;
        }
        }
      else if (ret == (size_t)-1)
      else if (ret == (size_t)-1)
        {
        {
          /* Invalid byte sequence for the current locale.  Treat first byte
          /* Invalid byte sequence for the current locale.  Treat first byte
             as a single character. */
             as a single character. */
          incoming[0] = pending_bytes[0];
          incoming[0] = pending_bytes[0];
          incoming[1] = '\0';
          incoming[1] = '\0';
          incoming_length = 1;
          incoming_length = 1;
          pending_bytes_length--;
          pending_bytes_length--;
          memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
          memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
          /* Clear the state of the byte sequence, because in this case the
          /* Clear the state of the byte sequence, because in this case the
             effect of mbstate is undefined. */
             effect of mbstate is undefined. */
          memset (&ps, 0, sizeof (mbstate_t));
          memset (&ps, 0, sizeof (mbstate_t));
        }
        }
      else if (ret == (size_t)0)
      else if (ret == (size_t)0)
        {
        {
          incoming[0] = '\0';
          incoming[0] = '\0';
          incoming_length = 0;
          incoming_length = 0;
          pending_bytes_length--;
          pending_bytes_length--;
          /* Clear the state of the byte sequence, because in this case the
          /* Clear the state of the byte sequence, because in this case the
             effect of mbstate is undefined. */
             effect of mbstate is undefined. */
          memset (&ps, 0, sizeof (mbstate_t));
          memset (&ps, 0, sizeof (mbstate_t));
        }
        }
      else
      else
        {
        {
          /* We successfully read a single multibyte character. */
          /* We successfully read a single multibyte character. */
          memcpy (incoming, pending_bytes, pending_bytes_length);
          memcpy (incoming, pending_bytes, pending_bytes_length);
          incoming[pending_bytes_length] = '\0';
          incoming[pending_bytes_length] = '\0';
          incoming_length = pending_bytes_length;
          incoming_length = pending_bytes_length;
          pending_bytes_length = 0;
          pending_bytes_length = 0;
        }
        }
    }
    }
#endif /* HANDLE_MULTIBYTE */
#endif /* HANDLE_MULTIBYTE */
 
 
  /* If we can optimize, then do it.  But don't let people crash
  /* If we can optimize, then do it.  But don't let people crash
     readline because of extra large arguments. */
     readline because of extra large arguments. */
  if (count > 1 && count <= 1024)
  if (count > 1 && count <= 1024)
    {
    {
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
      string_size = count * incoming_length;
      string_size = count * incoming_length;
      string = (char *)xmalloc (1 + string_size);
      string = (char *)xmalloc (1 + string_size);
 
 
      i = 0;
      i = 0;
      while (i < string_size)
      while (i < string_size)
        {
        {
          strncpy (string + i, incoming, incoming_length);
          strncpy (string + i, incoming, incoming_length);
          i += incoming_length;
          i += incoming_length;
        }
        }
      incoming_length = 0;
      incoming_length = 0;
      stored_count = 0;
      stored_count = 0;
#else /* !HANDLE_MULTIBYTE */
#else /* !HANDLE_MULTIBYTE */
      string = (char *)xmalloc (1 + count);
      string = (char *)xmalloc (1 + count);
 
 
      for (i = 0; i < count; i++)
      for (i = 0; i < count; i++)
        string[i] = c;
        string[i] = c;
#endif /* !HANDLE_MULTIBYTE */
#endif /* !HANDLE_MULTIBYTE */
 
 
      string[i] = '\0';
      string[i] = '\0';
      rl_insert_text (string);
      rl_insert_text (string);
      free (string);
      free (string);
 
 
      return 0;
      return 0;
    }
    }
 
 
  if (count > 1024)
  if (count > 1024)
    {
    {
      int decreaser;
      int decreaser;
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
      string_size = incoming_length * 1024;
      string_size = incoming_length * 1024;
      string = (char *)xmalloc (1 + string_size);
      string = (char *)xmalloc (1 + string_size);
 
 
      i = 0;
      i = 0;
      while (i < string_size)
      while (i < string_size)
        {
        {
          strncpy (string + i, incoming, incoming_length);
          strncpy (string + i, incoming, incoming_length);
          i += incoming_length;
          i += incoming_length;
        }
        }
 
 
      while (count)
      while (count)
        {
        {
          decreaser = (count > 1024) ? 1024 : count;
          decreaser = (count > 1024) ? 1024 : count;
          string[decreaser*incoming_length] = '\0';
          string[decreaser*incoming_length] = '\0';
          rl_insert_text (string);
          rl_insert_text (string);
          count -= decreaser;
          count -= decreaser;
        }
        }
 
 
      free (string);
      free (string);
      incoming_length = 0;
      incoming_length = 0;
      stored_count = 0;
      stored_count = 0;
#else /* !HANDLE_MULTIBYTE */
#else /* !HANDLE_MULTIBYTE */
      char str[1024+1];
      char str[1024+1];
 
 
      for (i = 0; i < 1024; i++)
      for (i = 0; i < 1024; i++)
        str[i] = c;
        str[i] = c;
 
 
      while (count)
      while (count)
        {
        {
          decreaser = (count > 1024 ? 1024 : count);
          decreaser = (count > 1024 ? 1024 : count);
          str[decreaser] = '\0';
          str[decreaser] = '\0';
          rl_insert_text (str);
          rl_insert_text (str);
          count -= decreaser;
          count -= decreaser;
        }
        }
#endif /* !HANDLE_MULTIBYTE */
#endif /* !HANDLE_MULTIBYTE */
 
 
      return 0;
      return 0;
    }
    }
 
 
  if (MB_CUR_MAX == 1 || rl_byte_oriented)
  if (MB_CUR_MAX == 1 || rl_byte_oriented)
    {
    {
      /* We are inserting a single character.
      /* We are inserting a single character.
         If there is pending input, then make a string of all of the
         If there is pending input, then make a string of all of the
         pending characters that are bound to rl_insert, and insert
         pending characters that are bound to rl_insert, and insert
         them all. */
         them all. */
      if (_rl_any_typein ())
      if (_rl_any_typein ())
        _rl_insert_typein (c);
        _rl_insert_typein (c);
      else
      else
        {
        {
          /* Inserting a single character. */
          /* Inserting a single character. */
          char str[2];
          char str[2];
 
 
          str[1] = '\0';
          str[1] = '\0';
          str[0] = c;
          str[0] = c;
          rl_insert_text (str);
          rl_insert_text (str);
        }
        }
    }
    }
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
  else
  else
    {
    {
      rl_insert_text (incoming);
      rl_insert_text (incoming);
      stored_count = 0;
      stored_count = 0;
    }
    }
#endif
#endif
 
 
  return 0;
  return 0;
}
}
 
 
/* Overwrite the character at point (or next COUNT characters) with C.
/* Overwrite the character at point (or next COUNT characters) with C.
   If C introduces a multibyte character sequence, read the entire sequence
   If C introduces a multibyte character sequence, read the entire sequence
   before starting the overwrite loop. */
   before starting the overwrite loop. */
int
int
_rl_overwrite_char (count, c)
_rl_overwrite_char (count, c)
     int count, c;
     int count, c;
{
{
  int i;
  int i;
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
  char mbkey[MB_LEN_MAX];
  char mbkey[MB_LEN_MAX];
  int k;
  int k;
 
 
  /* Read an entire multibyte character sequence to insert COUNT times. */
  /* Read an entire multibyte character sequence to insert COUNT times. */
  if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
  if (count > 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
    k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
    k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
#endif
#endif
 
 
  rl_begin_undo_group ();
  rl_begin_undo_group ();
 
 
  for (i = 0; i < count; i++)
  for (i = 0; i < count; i++)
    {
    {
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
        rl_insert_text (mbkey);
        rl_insert_text (mbkey);
      else
      else
#endif
#endif
        _rl_insert_char (1, c);
        _rl_insert_char (1, c);
 
 
      if (rl_point < rl_end)
      if (rl_point < rl_end)
        rl_delete (1, c);
        rl_delete (1, c);
    }
    }
 
 
  rl_end_undo_group ();
  rl_end_undo_group ();
 
 
  return 0;
  return 0;
}
}
 
 
int
int
rl_insert (count, c)
rl_insert (count, c)
     int count, c;
     int count, c;
{
{
  return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
  return (rl_insert_mode == RL_IM_INSERT ? _rl_insert_char (count, c)
                                         : _rl_overwrite_char (count, c));
                                         : _rl_overwrite_char (count, c));
}
}
 
 
/* Insert the next typed character verbatim. */
/* Insert the next typed character verbatim. */
static int
static int
_rl_insert_next (count)
_rl_insert_next (count)
     int count;
     int count;
{
{
  int c;
  int c;
 
 
  RL_SETSTATE(RL_STATE_MOREINPUT);
  RL_SETSTATE(RL_STATE_MOREINPUT);
  c = rl_read_key ();
  c = rl_read_key ();
  RL_UNSETSTATE(RL_STATE_MOREINPUT);
  RL_UNSETSTATE(RL_STATE_MOREINPUT);
 
 
#if defined (HANDLE_SIGNALS)
#if defined (HANDLE_SIGNALS)
  if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
  if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
    _rl_restore_tty_signals ();
    _rl_restore_tty_signals ();
#endif
#endif
 
 
  return (_rl_insert_char (count, c));
  return (_rl_insert_char (count, c));
}
}
 
 
#if defined (READLINE_CALLBACKS)
#if defined (READLINE_CALLBACKS)
static int
static int
_rl_insert_next_callback (data)
_rl_insert_next_callback (data)
     _rl_callback_generic_arg *data;
     _rl_callback_generic_arg *data;
{
{
  int count;
  int count;
 
 
  count = data->count;
  count = data->count;
 
 
  /* Deregister function, let rl_callback_read_char deallocate data */
  /* Deregister function, let rl_callback_read_char deallocate data */
  _rl_callback_func = 0;
  _rl_callback_func = 0;
  _rl_want_redisplay = 1;
  _rl_want_redisplay = 1;
 
 
  return _rl_insert_next (count);
  return _rl_insert_next (count);
}
}
#endif
#endif
 
 
int
int
rl_quoted_insert (count, key)
rl_quoted_insert (count, key)
     int count, key;
     int count, key;
{
{
  /* Let's see...should the callback interface futz with signal handling? */
  /* Let's see...should the callback interface futz with signal handling? */
#if defined (HANDLE_SIGNALS)
#if defined (HANDLE_SIGNALS)
  if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
  if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
    _rl_disable_tty_signals ();
    _rl_disable_tty_signals ();
#endif
#endif
 
 
#if defined (READLINE_CALLBACKS)
#if defined (READLINE_CALLBACKS)
  if (RL_ISSTATE (RL_STATE_CALLBACK))
  if (RL_ISSTATE (RL_STATE_CALLBACK))
    {
    {
      _rl_callback_data = _rl_callback_data_alloc (count);
      _rl_callback_data = _rl_callback_data_alloc (count);
      _rl_callback_func = _rl_insert_next_callback;
      _rl_callback_func = _rl_insert_next_callback;
      return (0);
      return (0);
    }
    }
#endif
#endif
 
 
  return _rl_insert_next (count);
  return _rl_insert_next (count);
}
}
 
 
/* Insert a tab character. */
/* Insert a tab character. */
int
int
rl_tab_insert (count, key)
rl_tab_insert (count, key)
     int count, key;
     int count, key;
{
{
  return (_rl_insert_char (count, '\t'));
  return (_rl_insert_char (count, '\t'));
}
}
 
 
/* What to do when a NEWLINE is pressed.  We accept the whole line.
/* What to do when a NEWLINE is pressed.  We accept the whole line.
   KEY is the key that invoked this command.  I guess it could have
   KEY is the key that invoked this command.  I guess it could have
   meaning in the future. */
   meaning in the future. */
int
int
rl_newline (count, key)
rl_newline (count, key)
     int count, key;
     int count, key;
{
{
  rl_done = 1;
  rl_done = 1;
 
 
  if (_rl_history_preserve_point)
  if (_rl_history_preserve_point)
    _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
    _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
 
 
  RL_SETSTATE(RL_STATE_DONE);
  RL_SETSTATE(RL_STATE_DONE);
 
 
#if defined (VI_MODE)
#if defined (VI_MODE)
  if (rl_editing_mode == vi_mode)
  if (rl_editing_mode == vi_mode)
    {
    {
      _rl_vi_done_inserting ();
      _rl_vi_done_inserting ();
      if (_rl_vi_textmod_command (_rl_vi_last_command) == 0)     /* XXX */
      if (_rl_vi_textmod_command (_rl_vi_last_command) == 0)     /* XXX */
        _rl_vi_reset_last ();
        _rl_vi_reset_last ();
    }
    }
#endif /* VI_MODE */
#endif /* VI_MODE */
 
 
  /* If we've been asked to erase empty lines, suppress the final update,
  /* If we've been asked to erase empty lines, suppress the final update,
     since _rl_update_final calls rl_crlf(). */
     since _rl_update_final calls rl_crlf(). */
  if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
  if (rl_erase_empty_line && rl_point == 0 && rl_end == 0)
    return 0;
    return 0;
 
 
  if (readline_echoing_p)
  if (readline_echoing_p)
    _rl_update_final ();
    _rl_update_final ();
  return 0;
  return 0;
}
}
 
 
/* What to do for some uppercase characters, like meta characters,
/* What to do for some uppercase characters, like meta characters,
   and some characters appearing in emacs_ctlx_keymap.  This function
   and some characters appearing in emacs_ctlx_keymap.  This function
   is just a stub, you bind keys to it and the code in _rl_dispatch ()
   is just a stub, you bind keys to it and the code in _rl_dispatch ()
   is special cased. */
   is special cased. */
int
int
rl_do_lowercase_version (ignore1, ignore2)
rl_do_lowercase_version (ignore1, ignore2)
     int ignore1, ignore2;
     int ignore1, ignore2;
{
{
  return 0;
  return 0;
}
}
 
 
/* This is different from what vi does, so the code's not shared.  Emacs
/* This is different from what vi does, so the code's not shared.  Emacs
   rubout in overwrite mode has one oddity:  it replaces a control
   rubout in overwrite mode has one oddity:  it replaces a control
   character that's displayed as two characters (^X) with two spaces. */
   character that's displayed as two characters (^X) with two spaces. */
int
int
_rl_overwrite_rubout (count, key)
_rl_overwrite_rubout (count, key)
     int count, key;
     int count, key;
{
{
  int opoint;
  int opoint;
  int i, l;
  int i, l;
 
 
  if (rl_point == 0)
  if (rl_point == 0)
    {
    {
      rl_ding ();
      rl_ding ();
      return 1;
      return 1;
    }
    }
 
 
  opoint = rl_point;
  opoint = rl_point;
 
 
  /* L == number of spaces to insert */
  /* L == number of spaces to insert */
  for (i = l = 0; i < count; i++)
  for (i = l = 0; i < count; i++)
    {
    {
      rl_backward_char (1, key);
      rl_backward_char (1, key);
      l += rl_character_len (rl_line_buffer[rl_point], rl_point);       /* not exactly right */
      l += rl_character_len (rl_line_buffer[rl_point], rl_point);       /* not exactly right */
    }
    }
 
 
  rl_begin_undo_group ();
  rl_begin_undo_group ();
 
 
  if (count > 1 || rl_explicit_arg)
  if (count > 1 || rl_explicit_arg)
    rl_kill_text (opoint, rl_point);
    rl_kill_text (opoint, rl_point);
  else
  else
    rl_delete_text (opoint, rl_point);
    rl_delete_text (opoint, rl_point);
 
 
  /* Emacs puts point at the beginning of the sequence of spaces. */
  /* Emacs puts point at the beginning of the sequence of spaces. */
  if (rl_point < rl_end)
  if (rl_point < rl_end)
    {
    {
      opoint = rl_point;
      opoint = rl_point;
      _rl_insert_char (l, ' ');
      _rl_insert_char (l, ' ');
      rl_point = opoint;
      rl_point = opoint;
    }
    }
 
 
  rl_end_undo_group ();
  rl_end_undo_group ();
 
 
  return 0;
  return 0;
}
}
 
 
/* Rubout the character behind point. */
/* Rubout the character behind point. */
int
int
rl_rubout (count, key)
rl_rubout (count, key)
     int count, key;
     int count, key;
{
{
  if (count < 0)
  if (count < 0)
    return (rl_delete (-count, key));
    return (rl_delete (-count, key));
 
 
  if (!rl_point)
  if (!rl_point)
    {
    {
      rl_ding ();
      rl_ding ();
      return -1;
      return -1;
    }
    }
 
 
  if (rl_insert_mode == RL_IM_OVERWRITE)
  if (rl_insert_mode == RL_IM_OVERWRITE)
    return (_rl_overwrite_rubout (count, key));
    return (_rl_overwrite_rubout (count, key));
 
 
  return (_rl_rubout_char (count, key));
  return (_rl_rubout_char (count, key));
}
}
 
 
int
int
_rl_rubout_char (count, key)
_rl_rubout_char (count, key)
     int count, key;
     int count, key;
{
{
  int orig_point;
  int orig_point;
  unsigned char c;
  unsigned char c;
 
 
  /* Duplicated code because this is called from other parts of the library. */
  /* Duplicated code because this is called from other parts of the library. */
  if (count < 0)
  if (count < 0)
    return (rl_delete (-count, key));
    return (rl_delete (-count, key));
 
 
  if (rl_point == 0)
  if (rl_point == 0)
    {
    {
      rl_ding ();
      rl_ding ();
      return -1;
      return -1;
    }
    }
 
 
  orig_point = rl_point;
  orig_point = rl_point;
  if (count > 1 || rl_explicit_arg)
  if (count > 1 || rl_explicit_arg)
    {
    {
      rl_backward_char (count, key);
      rl_backward_char (count, key);
      rl_kill_text (orig_point, rl_point);
      rl_kill_text (orig_point, rl_point);
    }
    }
  else if (MB_CUR_MAX == 1 || rl_byte_oriented)
  else if (MB_CUR_MAX == 1 || rl_byte_oriented)
    {
    {
      c = rl_line_buffer[--rl_point];
      c = rl_line_buffer[--rl_point];
      rl_delete_text (rl_point, orig_point);
      rl_delete_text (rl_point, orig_point);
      /* The erase-at-end-of-line hack is of questionable merit now. */
      /* The erase-at-end-of-line hack is of questionable merit now. */
      if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
      if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
        {
        {
          int l;
          int l;
          l = rl_character_len (c, rl_point);
          l = rl_character_len (c, rl_point);
          _rl_erase_at_end_of_line (l);
          _rl_erase_at_end_of_line (l);
        }
        }
    }
    }
  else
  else
    {
    {
      rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
      rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
      rl_delete_text (rl_point, orig_point);
      rl_delete_text (rl_point, orig_point);
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
/* Delete the character under the cursor.  Given a numeric argument,
/* Delete the character under the cursor.  Given a numeric argument,
   kill that many characters instead. */
   kill that many characters instead. */
int
int
rl_delete (count, key)
rl_delete (count, key)
     int count, key;
     int count, key;
{
{
  if (count < 0)
  if (count < 0)
    return (_rl_rubout_char (-count, key));
    return (_rl_rubout_char (-count, key));
 
 
  if (rl_point == rl_end)
  if (rl_point == rl_end)
    {
    {
      rl_ding ();
      rl_ding ();
      return -1;
      return -1;
    }
    }
 
 
  if (count > 1 || rl_explicit_arg)
  if (count > 1 || rl_explicit_arg)
    {
    {
      int orig_point = rl_point;
      int orig_point = rl_point;
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
        rl_forward_char (count, key);
        rl_forward_char (count, key);
      else
      else
        rl_forward_byte (count, key);
        rl_forward_byte (count, key);
 
 
      rl_kill_text (orig_point, rl_point);
      rl_kill_text (orig_point, rl_point);
      rl_point = orig_point;
      rl_point = orig_point;
    }
    }
  else
  else
    {
    {
      int new_point;
      int new_point;
 
 
      new_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
      new_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
      rl_delete_text (rl_point, new_point);
      rl_delete_text (rl_point, new_point);
    }
    }
  return 0;
  return 0;
}
}
 
 
/* Delete the character under the cursor, unless the insertion
/* Delete the character under the cursor, unless the insertion
   point is at the end of the line, in which case the character
   point is at the end of the line, in which case the character
   behind the cursor is deleted.  COUNT is obeyed and may be used
   behind the cursor is deleted.  COUNT is obeyed and may be used
   to delete forward or backward that many characters. */
   to delete forward or backward that many characters. */
int
int
rl_rubout_or_delete (count, key)
rl_rubout_or_delete (count, key)
     int count, key;
     int count, key;
{
{
  if (rl_end != 0 && rl_point == rl_end)
  if (rl_end != 0 && rl_point == rl_end)
    return (_rl_rubout_char (count, key));
    return (_rl_rubout_char (count, key));
  else
  else
    return (rl_delete (count, key));
    return (rl_delete (count, key));
}
}
 
 
/* Delete all spaces and tabs around point. */
/* Delete all spaces and tabs around point. */
int
int
rl_delete_horizontal_space (count, ignore)
rl_delete_horizontal_space (count, ignore)
     int count, ignore;
     int count, ignore;
{
{
  int start = rl_point;
  int start = rl_point;
 
 
  while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
  while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
    rl_point--;
    rl_point--;
 
 
  start = rl_point;
  start = rl_point;
 
 
  while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
  while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
    rl_point++;
    rl_point++;
 
 
  if (start != rl_point)
  if (start != rl_point)
    {
    {
      rl_delete_text (start, rl_point);
      rl_delete_text (start, rl_point);
      rl_point = start;
      rl_point = start;
    }
    }
 
 
  if (rl_point < 0)
  if (rl_point < 0)
    rl_point = 0;
    rl_point = 0;
 
 
  return 0;
  return 0;
}
}
 
 
/* Like the tcsh editing function delete-char-or-list.  The eof character
/* Like the tcsh editing function delete-char-or-list.  The eof character
   is caught before this is invoked, so this really does the same thing as
   is caught before this is invoked, so this really does the same thing as
   delete-char-or-list-or-eof, as long as it's bound to the eof character. */
   delete-char-or-list-or-eof, as long as it's bound to the eof character. */
int
int
rl_delete_or_show_completions (count, key)
rl_delete_or_show_completions (count, key)
     int count, key;
     int count, key;
{
{
  if (rl_end != 0 && rl_point == rl_end)
  if (rl_end != 0 && rl_point == rl_end)
    return (rl_possible_completions (count, key));
    return (rl_possible_completions (count, key));
  else
  else
    return (rl_delete (count, key));
    return (rl_delete (count, key));
}
}
 
 
#ifndef RL_COMMENT_BEGIN_DEFAULT
#ifndef RL_COMMENT_BEGIN_DEFAULT
#define RL_COMMENT_BEGIN_DEFAULT "#"
#define RL_COMMENT_BEGIN_DEFAULT "#"
#endif
#endif
 
 
/* Turn the current line into a comment in shell history.
/* Turn the current line into a comment in shell history.
   A K*rn shell style function. */
   A K*rn shell style function. */
int
int
rl_insert_comment (count, key)
rl_insert_comment (count, key)
     int count, key;
     int count, key;
{
{
  char *rl_comment_text;
  char *rl_comment_text;
  int rl_comment_len;
  int rl_comment_len;
 
 
  rl_beg_of_line (1, key);
  rl_beg_of_line (1, key);
  rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
  rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
 
 
  if (rl_explicit_arg == 0)
  if (rl_explicit_arg == 0)
    rl_insert_text (rl_comment_text);
    rl_insert_text (rl_comment_text);
  else
  else
    {
    {
      rl_comment_len = strlen (rl_comment_text);
      rl_comment_len = strlen (rl_comment_text);
      if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
      if (STREQN (rl_comment_text, rl_line_buffer, rl_comment_len))
        rl_delete_text (rl_point, rl_point + rl_comment_len);
        rl_delete_text (rl_point, rl_point + rl_comment_len);
      else
      else
        rl_insert_text (rl_comment_text);
        rl_insert_text (rl_comment_text);
    }
    }
 
 
  (*rl_redisplay_function) ();
  (*rl_redisplay_function) ();
  rl_newline (1, '\n');
  rl_newline (1, '\n');
 
 
  return (0);
  return (0);
}
}
 
 
/* **************************************************************** */
/* **************************************************************** */
/*                                                                  */
/*                                                                  */
/*                      Changing Case                               */
/*                      Changing Case                               */
/*                                                                  */
/*                                                                  */
/* **************************************************************** */
/* **************************************************************** */
 
 
/* The three kinds of things that we know how to do. */
/* The three kinds of things that we know how to do. */
#define UpCase 1
#define UpCase 1
#define DownCase 2
#define DownCase 2
#define CapCase 3
#define CapCase 3
 
 
/* Uppercase the word at point. */
/* Uppercase the word at point. */
int
int
rl_upcase_word (count, key)
rl_upcase_word (count, key)
     int count, key;
     int count, key;
{
{
  return (rl_change_case (count, UpCase));
  return (rl_change_case (count, UpCase));
}
}
 
 
/* Lowercase the word at point. */
/* Lowercase the word at point. */
int
int
rl_downcase_word (count, key)
rl_downcase_word (count, key)
     int count, key;
     int count, key;
{
{
  return (rl_change_case (count, DownCase));
  return (rl_change_case (count, DownCase));
}
}
 
 
/* Upcase the first letter, downcase the rest. */
/* Upcase the first letter, downcase the rest. */
int
int
rl_capitalize_word (count, key)
rl_capitalize_word (count, key)
     int count, key;
     int count, key;
{
{
 return (rl_change_case (count, CapCase));
 return (rl_change_case (count, CapCase));
}
}
 
 
/* The meaty function.
/* The meaty function.
   Change the case of COUNT words, performing OP on them.
   Change the case of COUNT words, performing OP on them.
   OP is one of UpCase, DownCase, or CapCase.
   OP is one of UpCase, DownCase, or CapCase.
   If a negative argument is given, leave point where it started,
   If a negative argument is given, leave point where it started,
   otherwise, leave it where it moves to. */
   otherwise, leave it where it moves to. */
static int
static int
rl_change_case (count, op)
rl_change_case (count, op)
     int count, op;
     int count, op;
{
{
  int start, next, end;
  int start, next, end;
  int inword, c, nc, nop;
  int inword, c, nc, nop;
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
  wchar_t wc, nwc;
  wchar_t wc, nwc;
  char mb[MB_LEN_MAX+1];
  char mb[MB_LEN_MAX+1];
  int mblen, p;
  int mblen, p;
  mbstate_t ps;
  mbstate_t ps;
#endif
#endif
 
 
  start = rl_point;
  start = rl_point;
  rl_forward_word (count, 0);
  rl_forward_word (count, 0);
  end = rl_point;
  end = rl_point;
 
 
  if (op != UpCase && op != DownCase && op != CapCase)
  if (op != UpCase && op != DownCase && op != CapCase)
    {
    {
      rl_ding ();
      rl_ding ();
      return -1;
      return -1;
    }
    }
 
 
  if (count < 0)
  if (count < 0)
    SWAP (start, end);
    SWAP (start, end);
 
 
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
  memset (&ps, 0, sizeof (mbstate_t));
  memset (&ps, 0, sizeof (mbstate_t));
#endif
#endif
 
 
  /* We are going to modify some text, so let's prepare to undo it. */
  /* We are going to modify some text, so let's prepare to undo it. */
  rl_modifying (start, end);
  rl_modifying (start, end);
 
 
  inword = 0;
  inword = 0;
  while (start < end)
  while (start < end)
    {
    {
      c = _rl_char_value (rl_line_buffer, start);
      c = _rl_char_value (rl_line_buffer, start);
      /*  This assumes that the upper and lower case versions are the same width. */
      /*  This assumes that the upper and lower case versions are the same width. */
      next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
      next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
 
 
      if (_rl_walphabetic (c) == 0)
      if (_rl_walphabetic (c) == 0)
        {
        {
          inword = 0;
          inword = 0;
          start = next;
          start = next;
          continue;
          continue;
        }
        }
 
 
      if (op == CapCase)
      if (op == CapCase)
        {
        {
          nop = inword ? DownCase : UpCase;
          nop = inword ? DownCase : UpCase;
          inword = 1;
          inword = 1;
        }
        }
      else
      else
        nop = op;
        nop = op;
      if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c))
      if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c))
        {
        {
          nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
          nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
          rl_line_buffer[start] = nc;
          rl_line_buffer[start] = nc;
        }
        }
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
      else
      else
        {
        {
          mbrtowc (&wc, rl_line_buffer + start, end - start, &ps);
          mbrtowc (&wc, rl_line_buffer + start, end - start, &ps);
          nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
          nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
          if  (nwc != wc)       /*  just skip unchanged characters */
          if  (nwc != wc)       /*  just skip unchanged characters */
            {
            {
              mblen = wcrtomb (mb, nwc, &ps);
              mblen = wcrtomb (mb, nwc, &ps);
              if (mblen > 0)
              if (mblen > 0)
                mb[mblen] = '\0';
                mb[mblen] = '\0';
              /* Assume the same width */
              /* Assume the same width */
              strncpy (rl_line_buffer + start, mb, mblen);
              strncpy (rl_line_buffer + start, mb, mblen);
            }
            }
        }
        }
#endif
#endif
 
 
      start = next;
      start = next;
    }
    }
 
 
  rl_point = end;
  rl_point = end;
  return 0;
  return 0;
}
}
 
 
/* **************************************************************** */
/* **************************************************************** */
/*                                                                  */
/*                                                                  */
/*                      Transposition                               */
/*                      Transposition                               */
/*                                                                  */
/*                                                                  */
/* **************************************************************** */
/* **************************************************************** */
 
 
/* Transpose the words at point.  If point is at the end of the line,
/* Transpose the words at point.  If point is at the end of the line,
   transpose the two words before point. */
   transpose the two words before point. */
int
int
rl_transpose_words (count, key)
rl_transpose_words (count, key)
     int count, key;
     int count, key;
{
{
  char *word1, *word2;
  char *word1, *word2;
  int w1_beg, w1_end, w2_beg, w2_end;
  int w1_beg, w1_end, w2_beg, w2_end;
  int orig_point = rl_point;
  int orig_point = rl_point;
 
 
  if (!count)
  if (!count)
    return 0;
    return 0;
 
 
  /* Find the two words. */
  /* Find the two words. */
  rl_forward_word (count, key);
  rl_forward_word (count, key);
  w2_end = rl_point;
  w2_end = rl_point;
  rl_backward_word (1, key);
  rl_backward_word (1, key);
  w2_beg = rl_point;
  w2_beg = rl_point;
  rl_backward_word (count, key);
  rl_backward_word (count, key);
  w1_beg = rl_point;
  w1_beg = rl_point;
  rl_forward_word (1, key);
  rl_forward_word (1, key);
  w1_end = rl_point;
  w1_end = rl_point;
 
 
  /* Do some check to make sure that there really are two words. */
  /* Do some check to make sure that there really are two words. */
  if ((w1_beg == w2_beg) || (w2_beg < w1_end))
  if ((w1_beg == w2_beg) || (w2_beg < w1_end))
    {
    {
      rl_ding ();
      rl_ding ();
      rl_point = orig_point;
      rl_point = orig_point;
      return -1;
      return -1;
    }
    }
 
 
  /* Get the text of the words. */
  /* Get the text of the words. */
  word1 = rl_copy_text (w1_beg, w1_end);
  word1 = rl_copy_text (w1_beg, w1_end);
  word2 = rl_copy_text (w2_beg, w2_end);
  word2 = rl_copy_text (w2_beg, w2_end);
 
 
  /* We are about to do many insertions and deletions.  Remember them
  /* We are about to do many insertions and deletions.  Remember them
     as one operation. */
     as one operation. */
  rl_begin_undo_group ();
  rl_begin_undo_group ();
 
 
  /* Do the stuff at word2 first, so that we don't have to worry
  /* Do the stuff at word2 first, so that we don't have to worry
     about word1 moving. */
     about word1 moving. */
  rl_point = w2_beg;
  rl_point = w2_beg;
  rl_delete_text (w2_beg, w2_end);
  rl_delete_text (w2_beg, w2_end);
  rl_insert_text (word1);
  rl_insert_text (word1);
 
 
  rl_point = w1_beg;
  rl_point = w1_beg;
  rl_delete_text (w1_beg, w1_end);
  rl_delete_text (w1_beg, w1_end);
  rl_insert_text (word2);
  rl_insert_text (word2);
 
 
  /* This is exactly correct since the text before this point has not
  /* This is exactly correct since the text before this point has not
     changed in length. */
     changed in length. */
  rl_point = w2_end;
  rl_point = w2_end;
 
 
  /* I think that does it. */
  /* I think that does it. */
  rl_end_undo_group ();
  rl_end_undo_group ();
  free (word1);
  free (word1);
  free (word2);
  free (word2);
 
 
  return 0;
  return 0;
}
}
 
 
/* Transpose the characters at point.  If point is at the end of the line,
/* Transpose the characters at point.  If point is at the end of the line,
   then transpose the characters before point. */
   then transpose the characters before point. */
int
int
rl_transpose_chars (count, key)
rl_transpose_chars (count, key)
     int count, key;
     int count, key;
{
{
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
  char *dummy;
  char *dummy;
  int i;
  int i;
#else
#else
  char dummy[2];
  char dummy[2];
#endif
#endif
  int char_length, prev_point;
  int char_length, prev_point;
 
 
  if (count == 0)
  if (count == 0)
    return 0;
    return 0;
 
 
  if (!rl_point || rl_end < 2)
  if (!rl_point || rl_end < 2)
    {
    {
      rl_ding ();
      rl_ding ();
      return -1;
      return -1;
    }
    }
 
 
  rl_begin_undo_group ();
  rl_begin_undo_group ();
 
 
  if (rl_point == rl_end)
  if (rl_point == rl_end)
    {
    {
      rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
      rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
      count = 1;
      count = 1;
    }
    }
 
 
  prev_point = rl_point;
  prev_point = rl_point;
  rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
  rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
 
 
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
  char_length = prev_point - rl_point;
  char_length = prev_point - rl_point;
  dummy = (char *)xmalloc (char_length + 1);
  dummy = (char *)xmalloc (char_length + 1);
  for (i = 0; i < char_length; i++)
  for (i = 0; i < char_length; i++)
    dummy[i] = rl_line_buffer[rl_point + i];
    dummy[i] = rl_line_buffer[rl_point + i];
  dummy[i] = '\0';
  dummy[i] = '\0';
#else
#else
  dummy[0] = rl_line_buffer[rl_point];
  dummy[0] = rl_line_buffer[rl_point];
  dummy[char_length = 1] = '\0';
  dummy[char_length = 1] = '\0';
#endif
#endif
 
 
  rl_delete_text (rl_point, rl_point + char_length);
  rl_delete_text (rl_point, rl_point + char_length);
 
 
  rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
  rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
 
 
  _rl_fix_point (0);
  _rl_fix_point (0);
  rl_insert_text (dummy);
  rl_insert_text (dummy);
  rl_end_undo_group ();
  rl_end_undo_group ();
 
 
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
  free (dummy);
  free (dummy);
#endif
#endif
 
 
  return 0;
  return 0;
}
}
 
 
/* **************************************************************** */
/* **************************************************************** */
/*                                                                  */
/*                                                                  */
/*                      Character Searching                         */
/*                      Character Searching                         */
/*                                                                  */
/*                                                                  */
/* **************************************************************** */
/* **************************************************************** */
 
 
int
int
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
_rl_char_search_internal (count, dir, smbchar, len)
_rl_char_search_internal (count, dir, smbchar, len)
     int count, dir;
     int count, dir;
     char *smbchar;
     char *smbchar;
     int len;
     int len;
#else
#else
_rl_char_search_internal (count, dir, schar)
_rl_char_search_internal (count, dir, schar)
     int count, dir, schar;
     int count, dir, schar;
#endif
#endif
{
{
  int pos, inc;
  int pos, inc;
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
  int prepos;
  int prepos;
#endif
#endif
 
 
  pos = rl_point;
  pos = rl_point;
  inc = (dir < 0) ? -1 : 1;
  inc = (dir < 0) ? -1 : 1;
  while (count)
  while (count)
    {
    {
      if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
      if ((dir < 0 && pos <= 0) || (dir > 0 && pos >= rl_end))
        {
        {
          rl_ding ();
          rl_ding ();
          return -1;
          return -1;
        }
        }
 
 
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
      pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
      pos = (inc > 0) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
                      : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
                      : _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
#else
#else
      pos += inc;
      pos += inc;
#endif
#endif
      do
      do
        {
        {
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
          if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
          if (_rl_is_mbchar_matched (rl_line_buffer, pos, rl_end, smbchar, len))
#else
#else
          if (rl_line_buffer[pos] == schar)
          if (rl_line_buffer[pos] == schar)
#endif
#endif
            {
            {
              count--;
              count--;
              if (dir < 0)
              if (dir < 0)
                rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
                rl_point = (dir == BTO) ? _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)
                                        : pos;
                                        : pos;
              else
              else
                rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
                rl_point = (dir == FTO) ? _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)
                                        : pos;
                                        : pos;
              break;
              break;
            }
            }
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
          prepos = pos;
          prepos = pos;
#endif
#endif
        }
        }
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
      while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
      while ((dir < 0) ? (pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY)) != prepos
                       : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
                       : (pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY)) != prepos);
#else
#else
      while ((dir < 0) ? pos-- : ++pos < rl_end);
      while ((dir < 0) ? pos-- : ++pos < rl_end);
#endif
#endif
    }
    }
  return (0);
  return (0);
}
}
 
 
/* Search COUNT times for a character read from the current input stream.
/* Search COUNT times for a character read from the current input stream.
   FDIR is the direction to search if COUNT is non-negative; otherwise
   FDIR is the direction to search if COUNT is non-negative; otherwise
   the search goes in BDIR.  So much is dependent on HANDLE_MULTIBYTE
   the search goes in BDIR.  So much is dependent on HANDLE_MULTIBYTE
   that there are two separate versions of this function. */
   that there are two separate versions of this function. */
#if defined (HANDLE_MULTIBYTE)
#if defined (HANDLE_MULTIBYTE)
static int
static int
_rl_char_search (count, fdir, bdir)
_rl_char_search (count, fdir, bdir)
     int count, fdir, bdir;
     int count, fdir, bdir;
{
{
  char mbchar[MB_LEN_MAX];
  char mbchar[MB_LEN_MAX];
  int mb_len;
  int mb_len;
 
 
  mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
  mb_len = _rl_read_mbchar (mbchar, MB_LEN_MAX);
 
 
  if (count < 0)
  if (count < 0)
    return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
    return (_rl_char_search_internal (-count, bdir, mbchar, mb_len));
  else
  else
    return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
    return (_rl_char_search_internal (count, fdir, mbchar, mb_len));
}
}
#else /* !HANDLE_MULTIBYTE */
#else /* !HANDLE_MULTIBYTE */
static int
static int
_rl_char_search (count, fdir, bdir)
_rl_char_search (count, fdir, bdir)
     int count, fdir, bdir;
     int count, fdir, bdir;
{
{
  int c;
  int c;
 
 
  RL_SETSTATE(RL_STATE_MOREINPUT);
  RL_SETSTATE(RL_STATE_MOREINPUT);
  c = rl_read_key ();
  c = rl_read_key ();
  RL_UNSETSTATE(RL_STATE_MOREINPUT);
  RL_UNSETSTATE(RL_STATE_MOREINPUT);
 
 
  if (count < 0)
  if (count < 0)
    return (_rl_char_search_internal (-count, bdir, c));
    return (_rl_char_search_internal (-count, bdir, c));
  else
  else
    return (_rl_char_search_internal (count, fdir, c));
    return (_rl_char_search_internal (count, fdir, c));
}
}
#endif /* !HANDLE_MULTIBYTE */
#endif /* !HANDLE_MULTIBYTE */
 
 
#if defined (READLINE_CALLBACKS)
#if defined (READLINE_CALLBACKS)
static int
static int
_rl_char_search_callback (data)
_rl_char_search_callback (data)
     _rl_callback_generic_arg *data;
     _rl_callback_generic_arg *data;
{
{
  _rl_callback_func = 0;
  _rl_callback_func = 0;
  _rl_want_redisplay = 1;
  _rl_want_redisplay = 1;
 
 
  return (_rl_char_search (data->count, data->i1, data->i2));
  return (_rl_char_search (data->count, data->i1, data->i2));
}
}
#endif
#endif
 
 
int
int
rl_char_search (count, key)
rl_char_search (count, key)
     int count, key;
     int count, key;
{
{
#if defined (READLINE_CALLBACKS)
#if defined (READLINE_CALLBACKS)
  if (RL_ISSTATE (RL_STATE_CALLBACK))
  if (RL_ISSTATE (RL_STATE_CALLBACK))
    {
    {
      _rl_callback_data = _rl_callback_data_alloc (count);
      _rl_callback_data = _rl_callback_data_alloc (count);
      _rl_callback_data->i1 = FFIND;
      _rl_callback_data->i1 = FFIND;
      _rl_callback_data->i2 = BFIND;
      _rl_callback_data->i2 = BFIND;
      _rl_callback_func = _rl_char_search_callback;
      _rl_callback_func = _rl_char_search_callback;
      return (0);
      return (0);
    }
    }
#endif
#endif
 
 
  return (_rl_char_search (count, FFIND, BFIND));
  return (_rl_char_search (count, FFIND, BFIND));
}
}
 
 
int
int
rl_backward_char_search (count, key)
rl_backward_char_search (count, key)
     int count, key;
     int count, key;
{
{
#if defined (READLINE_CALLBACKS)
#if defined (READLINE_CALLBACKS)
  if (RL_ISSTATE (RL_STATE_CALLBACK))
  if (RL_ISSTATE (RL_STATE_CALLBACK))
    {
    {
      _rl_callback_data = _rl_callback_data_alloc (count);
      _rl_callback_data = _rl_callback_data_alloc (count);
      _rl_callback_data->i1 = BFIND;
      _rl_callback_data->i1 = BFIND;
      _rl_callback_data->i2 = FFIND;
      _rl_callback_data->i2 = FFIND;
      _rl_callback_func = _rl_char_search_callback;
      _rl_callback_func = _rl_char_search_callback;
      return (0);
      return (0);
    }
    }
#endif
#endif
 
 
  return (_rl_char_search (count, BFIND, FFIND));
  return (_rl_char_search (count, BFIND, FFIND));
}
}
 
 
/* **************************************************************** */
/* **************************************************************** */
/*                                                                  */
/*                                                                  */
/*                 The Mark and the Region.                         */
/*                 The Mark and the Region.                         */
/*                                                                  */
/*                                                                  */
/* **************************************************************** */
/* **************************************************************** */
 
 
/* Set the mark at POSITION. */
/* Set the mark at POSITION. */
int
int
_rl_set_mark_at_pos (position)
_rl_set_mark_at_pos (position)
     int position;
     int position;
{
{
  if (position > rl_end)
  if (position > rl_end)
    return -1;
    return -1;
 
 
  rl_mark = position;
  rl_mark = position;
  return 0;
  return 0;
}
}
 
 
/* A bindable command to set the mark. */
/* A bindable command to set the mark. */
int
int
rl_set_mark (count, key)
rl_set_mark (count, key)
     int count, key;
     int count, key;
{
{
  return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
  return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
}
}
 
 
/* Exchange the position of mark and point. */
/* Exchange the position of mark and point. */
int
int
rl_exchange_point_and_mark (count, key)
rl_exchange_point_and_mark (count, key)
     int count, key;
     int count, key;
{
{
  if (rl_mark > rl_end)
  if (rl_mark > rl_end)
    rl_mark = -1;
    rl_mark = -1;
 
 
  if (rl_mark == -1)
  if (rl_mark == -1)
    {
    {
      rl_ding ();
      rl_ding ();
      return -1;
      return -1;
    }
    }
  else
  else
    SWAP (rl_point, rl_mark);
    SWAP (rl_point, rl_mark);
 
 
  return 0;
  return 0;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.