Blame input.c

Packit a71c51
/* input.c -- character input functions for readline. */
Packit a71c51
Packit a71c51
/* Copyright (C) 1994-2010 Free Software Foundation, Inc.
Packit a71c51
Packit a71c51
   This file is part of the GNU Readline Library (Readline), a library
Packit a71c51
   for reading lines of text with interactive input and history editing.      
Packit a71c51
Packit a71c51
   Readline is free software: you can redistribute it and/or modify
Packit a71c51
   it under the terms of the GNU General Public License as published by
Packit a71c51
   the Free Software Foundation, either version 3 of the License, or
Packit a71c51
   (at your option) any later version.
Packit a71c51
Packit a71c51
   Readline is distributed in the hope that it will be useful,
Packit a71c51
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a71c51
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit a71c51
   GNU General Public License for more details.
Packit a71c51
Packit a71c51
   You should have received a copy of the GNU General Public License
Packit a71c51
   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
Packit a71c51
*/
Packit a71c51
Packit a71c51
#define READLINE_LIBRARY
Packit a71c51
Packit a71c51
#if defined (__TANDEM)
Packit a71c51
#  include <floss.h>
Packit a71c51
#endif
Packit a71c51
Packit a71c51
#if defined (HAVE_CONFIG_H)
Packit a71c51
#  include <config.h>
Packit a71c51
#endif
Packit a71c51
Packit a71c51
#include <sys/types.h>
Packit a71c51
#include <fcntl.h>
Packit a71c51
#if defined (HAVE_SYS_FILE_H)
Packit a71c51
#  include <sys/file.h>
Packit a71c51
#endif /* HAVE_SYS_FILE_H */
Packit a71c51
Packit a71c51
#if defined (HAVE_UNISTD_H)
Packit a71c51
#  include <unistd.h>
Packit a71c51
#endif /* HAVE_UNISTD_H */
Packit a71c51
Packit a71c51
#if defined (HAVE_STDLIB_H)
Packit a71c51
#  include <stdlib.h>
Packit a71c51
#else
Packit a71c51
#  include "ansi_stdlib.h"
Packit a71c51
#endif /* HAVE_STDLIB_H */
Packit a71c51
Packit a71c51
#include "posixselect.h"
Packit a71c51
Packit a71c51
#if defined (FIONREAD_IN_SYS_IOCTL)
Packit a71c51
#  include <sys/ioctl.h>
Packit a71c51
#endif
Packit a71c51
Packit a71c51
#include <stdio.h>
Packit a71c51
#include <errno.h>
Packit a71c51
Packit a71c51
#if !defined (errno)
Packit a71c51
extern int errno;
Packit a71c51
#endif /* !errno */
Packit a71c51
Packit a71c51
/* System-specific feature definitions and include files. */
Packit a71c51
#include "rldefs.h"
Packit a71c51
#include "rlmbutil.h"
Packit a71c51
Packit a71c51
/* Some standard library routines. */
Packit a71c51
#include "readline.h"
Packit a71c51
Packit a71c51
#include "rlprivate.h"
Packit a71c51
#include "rlshell.h"
Packit a71c51
#include "xmalloc.h"
Packit a71c51
Packit a71c51
/* What kind of non-blocking I/O do we have? */
Packit a71c51
#if !defined (O_NDELAY) && defined (O_NONBLOCK)
Packit a71c51
#  define O_NDELAY O_NONBLOCK	/* Posix style */
Packit a71c51
#endif
Packit a71c51
Packit a71c51
/* Non-null means it is a pointer to a function to run while waiting for
Packit a71c51
   character input. */
Packit a71c51
rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
Packit a71c51
Packit a71c51
rl_getc_func_t *rl_getc_function = rl_getc;
Packit a71c51
Packit a71c51
static int _keyboard_input_timeout = 100000;		/* 0.1 seconds; it's in usec */
Packit a71c51
Packit a71c51
static int ibuffer_space PARAMS((void));
Packit a71c51
static int rl_get_char PARAMS((int *));
Packit a71c51
static int rl_gather_tyi PARAMS((void));
Packit a71c51
Packit a71c51
/* **************************************************************** */
Packit a71c51
/*								    */
Packit a71c51
/*			Character Input Buffering       	    */
Packit a71c51
/*								    */
Packit a71c51
/* **************************************************************** */
Packit a71c51
Packit a71c51
static int pop_index, push_index;
Packit a71c51
static unsigned char ibuffer[512];
Packit a71c51
static int ibuffer_len = sizeof (ibuffer) - 1;
Packit a71c51
Packit a71c51
#define any_typein (push_index != pop_index)
Packit a71c51
Packit a71c51
int
Packit a71c51
_rl_any_typein ()
Packit a71c51
{
Packit a71c51
  return any_typein;
Packit a71c51
}
Packit a71c51
Packit a71c51
/* Return the amount of space available in the buffer for stuffing
Packit a71c51
   characters. */
Packit a71c51
static int
Packit a71c51
ibuffer_space ()
Packit a71c51
{
Packit a71c51
  if (pop_index > push_index)
Packit a71c51
    return (pop_index - push_index - 1);
Packit a71c51
  else
Packit a71c51
    return (ibuffer_len - (push_index - pop_index));
Packit a71c51
}
Packit a71c51
Packit a71c51
/* Get a key from the buffer of characters to be read.
Packit a71c51
   Return the key in KEY.
Packit a71c51
   Result is KEY if there was a key, or 0 if there wasn't. */
Packit a71c51
static int
Packit a71c51
rl_get_char (key)
Packit a71c51
     int *key;
Packit a71c51
{
Packit a71c51
  if (push_index == pop_index)
Packit a71c51
    return (0);
Packit a71c51
Packit a71c51
  *key = ibuffer[pop_index++];
Packit a71c51
#if 0
Packit a71c51
  if (pop_index >= ibuffer_len)
Packit a71c51
#else
Packit a71c51
  if (pop_index > ibuffer_len)
Packit a71c51
#endif
Packit a71c51
    pop_index = 0;
Packit a71c51
Packit a71c51
  return (1);
Packit a71c51
}
Packit a71c51
Packit a71c51
/* Stuff KEY into the *front* of the input buffer.
Packit a71c51
   Returns non-zero if successful, zero if there is
Packit a71c51
   no space left in the buffer. */
Packit a71c51
int
Packit a71c51
_rl_unget_char (key)
Packit a71c51
     int key;
Packit a71c51
{
Packit a71c51
  if (ibuffer_space ())
Packit a71c51
    {
Packit a71c51
      pop_index--;
Packit a71c51
      if (pop_index < 0)
Packit a71c51
	pop_index = ibuffer_len;
Packit a71c51
      ibuffer[pop_index] = key;
Packit a71c51
      return (1);
Packit a71c51
    }
Packit a71c51
  return (0);
Packit a71c51
}
Packit a71c51
Packit a71c51
int
Packit a71c51
_rl_pushed_input_available ()
Packit a71c51
{
Packit a71c51
  return (push_index != pop_index);
Packit a71c51
}
Packit a71c51
Packit a71c51
/* If a character is available to be read, then read it and stuff it into
Packit a71c51
   IBUFFER.  Otherwise, just return.  Returns number of characters read
Packit a71c51
   (0 if none available) and -1 on error (EIO). */
Packit a71c51
static int
Packit a71c51
rl_gather_tyi ()
Packit a71c51
{
Packit a71c51
  int tty;
Packit a71c51
  register int tem, result;
Packit a71c51
  int chars_avail, k;
Packit a71c51
  char input;
Packit a71c51
#if defined(HAVE_SELECT)
Packit a71c51
  fd_set readfds, exceptfds;
Packit a71c51
  struct timeval timeout;
Packit a71c51
#endif
Packit a71c51
Packit a71c51
  chars_avail = 0;
Packit a71c51
  tty = fileno (rl_instream);
Packit a71c51
Packit a71c51
#if defined (HAVE_SELECT)
Packit a71c51
  FD_ZERO (&readfds);
Packit a71c51
  FD_ZERO (&exceptfds);
Packit a71c51
  FD_SET (tty, &readfds);
Packit a71c51
  FD_SET (tty, &exceptfds);
Packit a71c51
  USEC_TO_TIMEVAL (_keyboard_input_timeout, timeout);
Packit a71c51
  result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
Packit a71c51
  if (result <= 0)
Packit a71c51
    return 0;	/* Nothing to read. */
Packit a71c51
#endif
Packit a71c51
Packit a71c51
  result = -1;
Packit a71c51
#if defined (FIONREAD)
Packit a71c51
  errno = 0;
Packit a71c51
  result = ioctl (tty, FIONREAD, &chars_avail);
Packit a71c51
  if (result == -1 && errno == EIO)
Packit a71c51
    return -1;
Packit a71c51
#endif
Packit a71c51
Packit a71c51
#if defined (O_NDELAY)
Packit a71c51
  if (result == -1)
Packit a71c51
    {
Packit a71c51
      tem = fcntl (tty, F_GETFL, 0);
Packit a71c51
Packit a71c51
      fcntl (tty, F_SETFL, (tem | O_NDELAY));
Packit a71c51
      chars_avail = read (tty, &input, 1);
Packit a71c51
Packit a71c51
      fcntl (tty, F_SETFL, tem);
Packit a71c51
      if (chars_avail == -1 && errno == EAGAIN)
Packit a71c51
	return 0;
Packit a71c51
      if (chars_avail == 0)	/* EOF */
Packit a71c51
	{
Packit a71c51
	  rl_stuff_char (EOF);
Packit a71c51
	  return (0);
Packit a71c51
	}
Packit a71c51
    }
Packit a71c51
#endif /* O_NDELAY */
Packit a71c51
Packit a71c51
#if defined (__MINGW32__)
Packit a71c51
  /* Use getch/_kbhit to check for available console input, in the same way
Packit a71c51
     that we read it normally. */
Packit a71c51
   chars_avail = isatty (tty) ? _kbhit () : 0;
Packit a71c51
   result = 0;
Packit a71c51
#endif
Packit a71c51
Packit a71c51
  /* If there's nothing available, don't waste time trying to read
Packit a71c51
     something. */
Packit a71c51
  if (chars_avail <= 0)
Packit a71c51
    return 0;
Packit a71c51
Packit a71c51
  tem = ibuffer_space ();
Packit a71c51
Packit a71c51
  if (chars_avail > tem)
Packit a71c51
    chars_avail = tem;
Packit a71c51
Packit a71c51
  /* One cannot read all of the available input.  I can only read a single
Packit a71c51
     character at a time, or else programs which require input can be
Packit a71c51
     thwarted.  If the buffer is larger than one character, I lose.
Packit a71c51
     Damn! */
Packit a71c51
  if (tem < ibuffer_len)
Packit a71c51
    chars_avail = 0;
Packit a71c51
Packit a71c51
  if (result != -1)
Packit a71c51
    {
Packit a71c51
      while (chars_avail--)
Packit a71c51
	{
Packit a71c51
	  RL_CHECK_SIGNALS ();
Packit a71c51
	  k = (*rl_getc_function) (rl_instream);
Packit a71c51
	  if (rl_stuff_char (k) == 0)
Packit a71c51
	    break;			/* some problem; no more room */
Packit a71c51
	  if (k == NEWLINE || k == RETURN)
Packit a71c51
	    break;
Packit a71c51
	}
Packit a71c51
    }
Packit a71c51
  else
Packit a71c51
    {
Packit a71c51
      if (chars_avail)
Packit a71c51
	rl_stuff_char (input);
Packit a71c51
    }
Packit a71c51
Packit a71c51
  return 1;
Packit a71c51
}
Packit a71c51
Packit a71c51
int
Packit a71c51
rl_set_keyboard_input_timeout (u)
Packit a71c51
     int u;
Packit a71c51
{
Packit a71c51
  int o;
Packit a71c51
Packit a71c51
  o = _keyboard_input_timeout;
Packit a71c51
  if (u >= 0)
Packit a71c51
    _keyboard_input_timeout = u;
Packit a71c51
  return (o);
Packit a71c51
}
Packit a71c51
Packit a71c51
/* Is there input available to be read on the readline input file
Packit a71c51
   descriptor?  Only works if the system has select(2) or FIONREAD.
Packit a71c51
   Uses the value of _keyboard_input_timeout as the timeout; if another
Packit a71c51
   readline function wants to specify a timeout and not leave it up to
Packit a71c51
   the user, it should use _rl_input_queued(timeout_value_in_microseconds)
Packit a71c51
   instead. */
Packit a71c51
int
Packit a71c51
_rl_input_available ()
Packit a71c51
{
Packit a71c51
#if defined(HAVE_SELECT)
Packit a71c51
  fd_set readfds, exceptfds;
Packit a71c51
  struct timeval timeout;
Packit a71c51
#endif
Packit a71c51
#if !defined (HAVE_SELECT) && defined(FIONREAD)
Packit a71c51
  int chars_avail;
Packit a71c51
#endif
Packit a71c51
  int tty;
Packit a71c51
Packit a71c51
  tty = fileno (rl_instream);
Packit a71c51
Packit a71c51
#if defined (HAVE_SELECT)
Packit a71c51
  FD_ZERO (&readfds);
Packit a71c51
  FD_ZERO (&exceptfds);
Packit a71c51
  FD_SET (tty, &readfds);
Packit a71c51
  FD_SET (tty, &exceptfds);
Packit a71c51
  timeout.tv_sec = 0;
Packit a71c51
  timeout.tv_usec = _keyboard_input_timeout;
Packit a71c51
  return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
Packit a71c51
#else
Packit a71c51
Packit a71c51
#if defined (FIONREAD)
Packit a71c51
  if (ioctl (tty, FIONREAD, &chars_avail) == 0)
Packit a71c51
    return (chars_avail);
Packit a71c51
#endif
Packit a71c51
Packit a71c51
#endif
Packit a71c51
Packit a71c51
#if defined (__MINGW32__)
Packit a71c51
  if (isatty (tty))
Packit a71c51
    return (_kbhit ());
Packit a71c51
#endif
Packit a71c51
Packit a71c51
  return 0;
Packit a71c51
}
Packit a71c51
Packit a71c51
int
Packit a71c51
_rl_input_queued (t)
Packit a71c51
     int t;
Packit a71c51
{
Packit a71c51
  int old_timeout, r;
Packit a71c51
Packit a71c51
  old_timeout = rl_set_keyboard_input_timeout (t);
Packit a71c51
  r = _rl_input_available ();
Packit a71c51
  rl_set_keyboard_input_timeout (old_timeout);
Packit a71c51
  return r;
Packit a71c51
}
Packit a71c51
Packit a71c51
void
Packit a71c51
_rl_insert_typein (c)
Packit a71c51
     int c;     
Packit a71c51
{    	
Packit a71c51
  int key, t, i;
Packit a71c51
  char *string;
Packit a71c51
Packit a71c51
  i = key = 0;
Packit a71c51
  string = (char *)xmalloc (ibuffer_len + 1);
Packit a71c51
  string[i++] = (char) c;
Packit a71c51
Packit a71c51
  while ((t = rl_get_char (&key)) &&
Packit a71c51
	 _rl_keymap[key].type == ISFUNC &&
Packit a71c51
	 _rl_keymap[key].function == rl_insert)
Packit a71c51
    string[i++] = key;
Packit a71c51
Packit a71c51
  if (t)
Packit a71c51
    _rl_unget_char (key);
Packit a71c51
Packit a71c51
  string[i] = '\0';
Packit a71c51
  rl_insert_text (string);
Packit a71c51
  xfree (string);
Packit a71c51
}
Packit a71c51
Packit a71c51
/* Add KEY to the buffer of characters to be read.  Returns 1 if the
Packit a71c51
   character was stuffed correctly; 0 otherwise. */
Packit a71c51
int
Packit a71c51
rl_stuff_char (key)
Packit a71c51
     int key;
Packit a71c51
{
Packit a71c51
  if (ibuffer_space () == 0)
Packit a71c51
    return 0;
Packit a71c51
Packit a71c51
  if (key == EOF)
Packit a71c51
    {
Packit a71c51
      key = NEWLINE;
Packit a71c51
      rl_pending_input = EOF;
Packit a71c51
      RL_SETSTATE (RL_STATE_INPUTPENDING);
Packit a71c51
    }
Packit a71c51
  ibuffer[push_index++] = key;
Packit a71c51
#if 0
Packit a71c51
  if (push_index >= ibuffer_len)
Packit a71c51
#else
Packit a71c51
  if (push_index > ibuffer_len)
Packit a71c51
#endif
Packit a71c51
    push_index = 0;
Packit a71c51
Packit a71c51
  return 1;
Packit a71c51
}
Packit a71c51
Packit a71c51
/* Make C be the next command to be executed. */
Packit a71c51
int
Packit a71c51
rl_execute_next (c)
Packit a71c51
     int c;
Packit a71c51
{
Packit a71c51
  rl_pending_input = c;
Packit a71c51
  RL_SETSTATE (RL_STATE_INPUTPENDING);
Packit a71c51
  return 0;
Packit a71c51
}
Packit a71c51
Packit a71c51
/* Clear any pending input pushed with rl_execute_next() */
Packit a71c51
int
Packit a71c51
rl_clear_pending_input ()
Packit a71c51
{
Packit a71c51
  rl_pending_input = 0;
Packit a71c51
  RL_UNSETSTATE (RL_STATE_INPUTPENDING);
Packit a71c51
  return 0;
Packit a71c51
}
Packit a71c51
Packit a71c51
/* **************************************************************** */
Packit a71c51
/*								    */
Packit a71c51
/*			     Character Input			    */
Packit a71c51
/*								    */
Packit a71c51
/* **************************************************************** */
Packit a71c51
Packit a71c51
/* Read a key, including pending input. */
Packit a71c51
int
Packit a71c51
rl_read_key ()
Packit a71c51
{
Packit a71c51
  int c;
Packit a71c51
Packit a71c51
  rl_key_sequence_length++;
Packit a71c51
Packit a71c51
  if (rl_pending_input)
Packit a71c51
    {
Packit a71c51
      c = rl_pending_input;
Packit a71c51
      rl_clear_pending_input ();
Packit a71c51
    }
Packit a71c51
  else
Packit a71c51
    {
Packit a71c51
      /* If input is coming from a macro, then use that. */
Packit a71c51
      if (c = _rl_next_macro_key ())
Packit a71c51
	return (c);
Packit a71c51
Packit a71c51
      /* If the user has an event function, then call it periodically. */
Packit a71c51
      if (rl_event_hook)
Packit a71c51
	{
Packit a71c51
	  while (rl_event_hook)
Packit a71c51
	    {
Packit a71c51
	      if (rl_gather_tyi () < 0)	/* XXX - EIO */
Packit a71c51
		{
Packit a71c51
		  rl_done = 1;
Packit a71c51
		  return ('\n');
Packit a71c51
		}
Packit a71c51
	      RL_CHECK_SIGNALS ();
Packit a71c51
	      if (rl_get_char (&c) != 0)
Packit a71c51
		break;
Packit a71c51
	      if (rl_done)		/* XXX - experimental */
Packit a71c51
		return ('\n');
Packit a71c51
	      (*rl_event_hook) ();
Packit a71c51
	    }
Packit a71c51
	}
Packit a71c51
      else
Packit a71c51
	{
Packit a71c51
	  if (rl_get_char (&c) == 0)
Packit a71c51
	    c = (*rl_getc_function) (rl_instream);
Packit a71c51
	  RL_CHECK_SIGNALS ();
Packit a71c51
	}
Packit a71c51
    }
Packit a71c51
Packit a71c51
  return (c);
Packit a71c51
}
Packit a71c51
Packit a71c51
int
Packit a71c51
rl_getc (stream)
Packit a71c51
     FILE *stream;
Packit a71c51
{
Packit a71c51
  int result;
Packit a71c51
  unsigned char c;
Packit a71c51
Packit a71c51
  while (1)
Packit a71c51
    {
Packit a71c51
      RL_CHECK_SIGNALS ();
Packit a71c51
Packit a71c51
#if defined (__MINGW32__)
Packit a71c51
      if (isatty (fileno (stream)))
Packit a71c51
	return (getch ());
Packit a71c51
#endif
Packit a71c51
      result = read (fileno (stream), &c, sizeof (unsigned char));
Packit a71c51
Packit a71c51
      if (result == sizeof (unsigned char))
Packit a71c51
	return (c);
Packit a71c51
Packit a71c51
      /* If zero characters are returned, then the file that we are
Packit a71c51
	 reading from is empty!  Return EOF in that case. */
Packit a71c51
      if (result == 0)
Packit a71c51
	return (EOF);
Packit a71c51
Packit a71c51
#if defined (__BEOS__)
Packit a71c51
      if (errno == EINTR)
Packit a71c51
	continue;
Packit a71c51
#endif
Packit a71c51
Packit a71c51
#if defined (EWOULDBLOCK)
Packit a71c51
#  define X_EWOULDBLOCK EWOULDBLOCK
Packit a71c51
#else
Packit a71c51
#  define X_EWOULDBLOCK -99
Packit a71c51
#endif
Packit a71c51
Packit a71c51
#if defined (EAGAIN)
Packit a71c51
#  define X_EAGAIN EAGAIN
Packit a71c51
#else
Packit a71c51
#  define X_EAGAIN -99
Packit a71c51
#endif
Packit a71c51
Packit a71c51
      if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)
Packit a71c51
	{
Packit a71c51
	  if (sh_unset_nodelay_mode (fileno (stream)) < 0)
Packit a71c51
	    return (EOF);
Packit a71c51
	  continue;
Packit a71c51
	}
Packit a71c51
Packit a71c51
#undef X_EWOULDBLOCK
Packit a71c51
#undef X_EAGAIN
Packit a71c51
Packit a71c51
      /* If the error that we received was SIGINT, then try again,
Packit a71c51
	 this is simply an interrupted system call to read ().
Packit a71c51
	 Otherwise, some error ocurred, also signifying EOF. */
Packit a71c51
      if (errno != EINTR)
Packit a71c51
	return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
Packit a71c51
    }
Packit a71c51
}
Packit a71c51
Packit a71c51
#if defined (HANDLE_MULTIBYTE)
Packit a71c51
/* read multibyte char */
Packit a71c51
int
Packit a71c51
_rl_read_mbchar (mbchar, size)
Packit a71c51
     char *mbchar;
Packit a71c51
     int size;
Packit a71c51
{
Packit a71c51
  int mb_len, c;
Packit a71c51
  size_t mbchar_bytes_length;
Packit a71c51
  wchar_t wc;
Packit a71c51
  mbstate_t ps, ps_back;
Packit a71c51
Packit a71c51
  memset(&ps, 0, sizeof (mbstate_t));
Packit a71c51
  memset(&ps_back, 0, sizeof (mbstate_t));
Packit a71c51
Packit a71c51
  mb_len = 0;  
Packit a71c51
  while (mb_len < size)
Packit a71c51
    {
Packit a71c51
      RL_SETSTATE(RL_STATE_MOREINPUT);
Packit a71c51
      c = rl_read_key ();
Packit a71c51
      RL_UNSETSTATE(RL_STATE_MOREINPUT);
Packit a71c51
Packit a71c51
      if (c < 0)
Packit a71c51
	break;
Packit a71c51
Packit a71c51
      mbchar[mb_len++] = c;
Packit a71c51
Packit a71c51
      mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
Packit a71c51
      if (mbchar_bytes_length == (size_t)(-1))
Packit a71c51
	break;		/* invalid byte sequence for the current locale */
Packit a71c51
      else if (mbchar_bytes_length == (size_t)(-2))
Packit a71c51
	{
Packit a71c51
	  /* shorted bytes */
Packit a71c51
	  ps = ps_back;
Packit a71c51
	  continue;
Packit a71c51
	} 
Packit a71c51
      else if (mbchar_bytes_length == 0)
Packit a71c51
	{
Packit a71c51
	  mbchar[0] = '\0';	/* null wide character */
Packit a71c51
	  mb_len = 1;
Packit a71c51
	  break;
Packit a71c51
	}
Packit a71c51
      else if (mbchar_bytes_length > (size_t)(0))
Packit a71c51
	break;
Packit a71c51
    }
Packit a71c51
Packit a71c51
  return mb_len;
Packit a71c51
}
Packit a71c51
Packit a71c51
/* Read a multibyte-character string whose first character is FIRST into
Packit a71c51
   the buffer MB of length MLEN.  Returns the last character read, which
Packit a71c51
   may be FIRST.  Used by the search functions, among others.  Very similar
Packit a71c51
   to _rl_read_mbchar. */
Packit a71c51
int
Packit a71c51
_rl_read_mbstring (first, mb, mlen)
Packit a71c51
     int first;
Packit a71c51
     char *mb;
Packit a71c51
     int mlen;
Packit a71c51
{
Packit a71c51
  int i, c;
Packit a71c51
  mbstate_t ps;
Packit a71c51
Packit a71c51
  c = first;
Packit a71c51
  memset (mb, 0, mlen);
Packit a71c51
  for (i = 0; c >= 0 && i < mlen; i++)
Packit a71c51
    {
Packit a71c51
      mb[i] = (char)c;
Packit a71c51
      memset (&ps, 0, sizeof (mbstate_t));
Packit a71c51
      if (_rl_get_char_len (mb, &ps) == -2)
Packit a71c51
	{
Packit a71c51
	  /* Read more for multibyte character */
Packit a71c51
	  RL_SETSTATE (RL_STATE_MOREINPUT);
Packit a71c51
	  c = rl_read_key ();
Packit a71c51
	  RL_UNSETSTATE (RL_STATE_MOREINPUT);
Packit a71c51
	}
Packit a71c51
      else
Packit a71c51
	break;
Packit a71c51
    }
Packit a71c51
  return c;
Packit a71c51
}
Packit a71c51
#endif /* HANDLE_MULTIBYTE */