Commit 29d7b245 authored by unknown's avatar unknown

Merge tsmith@bk-internal.mysql.com:/home/bk/mysql-5.0-build

into  ramayana.hindu.god:/home/tsmith/m/bk/build/50

parents 7f99a2db dd433ff1
Basic Installation
==================
These are installation instructions for Readline-5.0.
These are installation instructions for Readline-5.2.
The simplest way to compile readline is:
......@@ -238,6 +238,9 @@ SHLIB_XLDFLAGS Additional flags to pass to SHOBJ_LD for shared library
SHLIB_LIBS Any additional libraries that shared libraries should be
linked against when they are created.
SHLIB_LIBPREF The prefix to use when generating the filename of the shared
library. The default is `lib'; Cygwin uses `cyg'.
SHLIB_LIBSUFF The suffix to add to `libreadline' and `libhistory' when
generating the filename of the shared library. Many systems
use `so'; HP-UX uses `sl'.
......@@ -254,6 +257,17 @@ SHLIB_LIBVERSION The string to append to the filename to indicate the version
numbers; use `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' on those systems.
Other Unix versions use different schemes.
SHLIB_DLLVERSION The version number for shared libraries that determines API
compatibility between readline versions and the underlying
system. Used only on Cygwin. Defaults to $SHLIB_MAJOR, but
can be overridden at configuration time by defining DLLVERSION
in the environment.
SHLIB_DOT The character used to separate the name of the shared library
from the suffix and version information. The default is `.';
systems like Cygwin which don't separate version information
from the library name should set this to the empty string.
SHLIB_STATUS Set this to `supported' when you have defined the other
necessary variables. Make uses this to determine whether
or not shared library creation should be attempted. If
......
Introduction
============
This is the Gnu Readline library, version 5.0.
This is the Gnu Readline library, version 5.2.
The Readline library provides a set of functions for use by applications
that allow users to edit command lines as they are typed in. Both
......@@ -102,6 +102,9 @@ SHLIB_XLDFLAGS Additional flags to pass to SHOBJ_LD for shared library
SHLIB_LIBS Any additional libraries that shared libraries should be
linked against when they are created.
SHLIB_LIBPREF The prefix to use when generating the filename of the shared
library. The default is `lib'; Cygwin uses `cyg'.
SHLIB_LIBSUFF The suffix to add to `libreadline' and `libhistory' when
generating the filename of the shared library. Many systems
use `so'; HP-UX uses `sl'.
......@@ -118,6 +121,17 @@ SHLIB_LIBVERSION The string to append to the filename to indicate the version
numbers; use `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' on those systems.
Other Unix versions use different schemes.
SHLIB_DLLVERSION The version number for shared libraries that determines API
compatibility between readline versions and the underlying
system. Used only on Cygwin. Defaults to $SHLIB_MAJOR, but
can be overridden at configuration time by defining DLLVERSION
in the environment.
SHLIB_DOT The character used to separate the name of the shared library
from the suffix and version information. The default is `.';
systems like Cygwin which don't separate version information
from the library name should set this to the empty string.
SHLIB_STATUS Set this to `supported' when you have defined the other
necessary variables. Make uses this to determine whether
or not shared library creation should be attempted.
......@@ -169,4 +183,4 @@ list (mirrored to the Usenet newsgroup gnu.bash.bug) often contains
Readline bug reports and fixes.
Chet Ramey
chet@po.cwru.edu
chet.ramey@case.edu
/* bind.c -- key binding and startup file support for the readline library. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -26,7 +26,9 @@
# include <floss.h>
#endif
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
......@@ -75,6 +77,9 @@ static char *_rl_read_file PARAMS((char *, size_t *));
static void _rl_init_file_error PARAMS((const char *));
static int _rl_read_init_file PARAMS((const char *, int));
static int glean_key_from_name PARAMS((char *));
static int find_boolean_var PARAMS((const char *));
static char *_rl_get_string_variable_value PARAMS((const char *));
static int substring_member_of_array PARAMS((char *, const char **));
static int currently_reading_init_file;
......@@ -337,10 +342,9 @@ rl_generic_bind (type, keyseq, data, map)
KEYMAP_ENTRY k;
k.function = 0;
k.type= 0;
/* If no keys to bind to, exit right away. */
if (!keyseq || !*keyseq)
if (keyseq == 0 || *keyseq == 0)
{
if (type == ISMACR)
free (data);
......@@ -366,9 +370,12 @@ rl_generic_bind (type, keyseq, data, map)
ic = uc;
if (ic < 0 || ic >= KEYMAP_SIZE)
{
free (keys);
return -1;
}
if (_rl_convert_meta_chars_to_ascii && META_CHAR (ic))
if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
{
ic = UNMETA (ic);
if (map[ESC].type == ISKMAP)
......@@ -435,7 +442,7 @@ rl_translate_keyseq (seq, array, len)
{
register int i, c, l, temp;
for (i = l = 0; (c = seq[i]); i++)
for (i = l = 0; c = seq[i]; i++)
{
if (c == '\\')
{
......@@ -458,8 +465,24 @@ rl_translate_keyseq (seq, array, len)
}
else if (c == 'M')
{
i++;
i++; /* seq[i] == '-' */
/* XXX - obey convert-meta setting */
if (_rl_convert_meta_chars_to_ascii && _rl_keymap[ESC].type == ISKMAP)
array[l++] = ESC; /* ESC is meta-prefix */
else if (seq[i+1] == '\\' && seq[i+2] == 'C' && seq[i+3] == '-')
{
i += 4;
temp = (seq[i] == '?') ? RUBOUT : CTRL (_rl_to_upper (seq[i]));
array[l++] = META (temp);
}
else
{
/* This doesn't yet handle things like \M-\a, which may
or may not have any reasonable meaning. You're
probably better off using straight octal or hex. */
i++;
array[l++] = META (seq[i]);
}
}
else if (c == 'C')
{
......@@ -554,6 +577,11 @@ rl_untranslate_keyseq (seq)
kseq[i++] = '-';
c = UNMETA (c);
}
else if (c == ESC)
{
kseq[i++] = '\\';
c = 'e';
}
else if (CTRL_CHAR (c))
{
kseq[i++] = '\\';
......@@ -602,7 +630,12 @@ _rl_untranslate_macro_value (seq)
*r++ = '-';
c = UNMETA (c);
}
else if (CTRL_CHAR (c) && c != ESC)
else if (c == ESC)
{
*r++ = '\\';
c = 'e';
}
else if (CTRL_CHAR (c))
{
*r++ = '\\';
*r++ = 'C';
......@@ -661,7 +694,7 @@ rl_function_of_keyseq (keyseq, map, type)
{
register int i;
if (!map)
if (map == 0)
map = _rl_keymap;
for (i = 0; keyseq && keyseq[i]; i++)
......@@ -670,25 +703,27 @@ rl_function_of_keyseq (keyseq, map, type)
if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii)
{
if (map[ESC].type != ISKMAP)
if (map[ESC].type == ISKMAP)
{
map = FUNCTION_TO_KEYMAP (map, ESC);
ic = UNMETA (ic);
}
/* XXX - should we just return NULL here, since this obviously
doesn't match? */
else
{
if (type)
*type = map[ESC].type;
return (map[ESC].function);
}
else
{
map = FUNCTION_TO_KEYMAP (map, ESC);
ic = UNMETA (ic);
}
}
if (map[ic].type == ISKMAP)
{
/* If this is the last key in the key sequence, return the
map. */
if (!keyseq[i + 1])
if (keyseq[i + 1] == '\0')
{
if (type)
*type = ISKMAP;
......@@ -698,7 +733,12 @@ rl_function_of_keyseq (keyseq, map, type)
else
map = FUNCTION_TO_KEYMAP (map, ic);
}
else
/* If we're not at the end of the key sequence, and the current key
is bound to something other than a keymap, then the entire key
sequence is not bound. */
else if (map[ic].type != ISKMAP && keyseq[i+1])
return ((rl_command_func_t *)NULL);
else /* map[ic].type != ISKMAP && keyseq[i+1] == 0 */
{
if (type)
*type = map[ic].type;
......@@ -736,8 +776,7 @@ _rl_read_file (filename, sizep)
file_size = (size_t)finfo.st_size;
/* check for overflow on very large files */
if ((long long) file_size != (long long) finfo.st_size ||
file_size + 1 < file_size)
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
if (file >= 0)
close (file);
......@@ -767,8 +806,8 @@ _rl_read_file (filename, sizep)
/* Re-read the current keybindings file. */
int
rl_re_read_init_file (int count __attribute__((unused)),
int ignore __attribute__((unused)))
rl_re_read_init_file (count, ignore)
int count, ignore;
{
int r;
r = rl_read_init_file ((const char *)NULL);
......@@ -781,6 +820,7 @@ rl_re_read_init_file (int count __attribute__((unused)),
1. the filename used for the previous call
2. the value of the shell variable `INPUTRC'
3. ~/.inputrc
4. /etc/inputrc
If the file existed and could be opened and read, 0 is returned,
otherwise errno is returned. */
int
......@@ -789,17 +829,18 @@ rl_read_init_file (filename)
{
/* Default the filename. */
if (filename == 0)
{
filename = last_readline_init_file;
if (filename == 0)
filename = sh_get_env_value ("INPUTRC");
if (filename == 0)
if (filename == 0 || *filename == 0)
{
filename = DEFAULT_INPUTRC;
/* Try to read DEFAULT_INPUTRC; fall back to SYS_INPUTRC on failure */
if (_rl_read_init_file (filename, 0) == 0)
return 0;
filename = SYS_INPUTRC;
}
if (*filename == 0)
filename = DEFAULT_INPUTRC;
#if defined (__MSDOS__)
if (_rl_read_init_file (filename, 0) == 0)
return 0;
......@@ -989,7 +1030,8 @@ parser_if (args)
/* Invert the current parser state if there is anything on the stack. */
static int
parser_else (char *args __attribute__((unused)))
parser_else (args)
char *args;
{
register int i;
......@@ -1019,7 +1061,8 @@ parser_else (char *args __attribute__((unused)))
/* Terminate a conditional, popping the value of
_rl_parsing_conditionalized_out from the stack. */
static int
parser_endif (char *args __attribute__((unused)))
parser_endif (args)
char *args;
{
if (if_stack_depth)
_rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
......@@ -1142,7 +1185,7 @@ rl_parse_and_bind (string)
{
int passc = 0;
for (i = 1; (c = string[i]); i++)
for (i = 1; c = string[i]; i++)
{
if (passc)
{
......@@ -1183,9 +1226,9 @@ rl_parse_and_bind (string)
/* If this is a command to set a variable, then do that. */
if (_rl_stricmp (string, "set") == 0)
{
char *var = string + i;
char *value;
char *var, *value, *e;
var = string + i;
/* Make VAR point to start of variable name. */
while (*var && whitespace (*var)) var++;
......@@ -1196,6 +1239,20 @@ rl_parse_and_bind (string)
*value++ = '\0';
while (*value && whitespace (*value)) value++;
/* Strip trailing whitespace from values to boolean variables. Temp
fix until I get a real quoted-string parser here. */
i = find_boolean_var (var);
if (i >= 0)
{
/* remove trailing whitespace */
e = value + strlen (value) - 1;
while (e >= value && whitespace (*e))
e--;
e++; /* skip back to whitespace or EOS */
if (*e && e >= value)
*e = '\0';
}
rl_variable_bind (var, value);
return 0;
}
......@@ -1216,9 +1273,10 @@ rl_parse_and_bind (string)
the quoted string delimiter, like the shell. */
if (*funname == '\'' || *funname == '"')
{
int delimiter = string[i++], passc;
int delimiter, passc;
for (passc = 0; (c = string[i]); i++)
delimiter = string[i++];
for (passc = 0; c = string[i]; i++)
{
if (passc)
{
......@@ -1353,6 +1411,7 @@ static struct {
int *value;
int flags;
} boolean_varlist [] = {
{ "bind-tty-special-chars", &_rl_bind_stty_chars, 0 },
{ "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
{ "byte-oriented", &rl_byte_oriented, 0 },
{ "completion-ignore-case", &_rl_completion_case_fold, 0 },
......@@ -1377,7 +1436,7 @@ static struct {
#if defined (VISIBLE_STATS)
{ "visible-stats", &rl_visible_stats, 0 },
#endif /* VISIBLE_STATS */
{ (char *)NULL, (int *)NULL, 0 }
{ (char *)NULL, (int *)NULL }
};
static int
......@@ -1446,7 +1505,7 @@ static struct {
{ "editing-mode", V_STRING, sv_editmode },
{ "isearch-terminators", V_STRING, sv_isrchterm },
{ "keymap", V_STRING, sv_keymap },
{ (char *)NULL, 0, 0 }
{ (char *)NULL, 0 }
};
static int
......@@ -1466,13 +1525,32 @@ find_string_var (name)
values result in 0 (false). */
static int
bool_to_int (value)
const char *value;
const char *value;
{
return (value == 0 || *value == '\0' ||
(_rl_stricmp (value, "on") == 0) ||
(value[0] == '1' && value[1] == '\0'));
}
char *
rl_variable_value (name)
const char *name;
{
register int i;
/* Check for simple variables first. */
i = find_boolean_var (name);
if (i >= 0)
return (*boolean_varlist[i].value ? "on" : "off");
i = find_string_var (name);
if (i >= 0)
return (_rl_get_string_variable_value (string_varlist[i].name));
/* Unknown variable names return NULL. */
return 0;
}
int
rl_variable_bind (name, value)
const char *name, *value;
......@@ -1725,13 +1803,13 @@ char *
rl_get_keymap_name_from_edit_mode ()
{
if (rl_editing_mode == emacs_mode)
return (char*) "emacs";
return "emacs";
#if defined (VI_MODE)
else if (rl_editing_mode == vi_mode)
return (char*) "vi";
return "vi";
#endif /* VI_MODE */
else
return (char*) "none";
return "none";
}
/* **************************************************************** */
......@@ -1899,12 +1977,16 @@ rl_invoking_keyseqs_in_map (function, map)
char *keyname = (char *)xmalloc (6 + strlen (seqs[i]));
if (key == ESC)
#if 0
sprintf (keyname, "\\e");
#else
/* XXX - experimental */
{
/* If ESC is the meta prefix and we're converting chars
with the eighth bit set to ESC-prefixed sequences, then
we can use \M-. Otherwise we need to use the sequence
for ESC. */
if (_rl_convert_meta_chars_to_ascii && map[ESC].type == ISKMAP)
sprintf (keyname, "\\M-");
#endif
else
sprintf (keyname, "\\e");
}
else if (CTRL_CHAR (key))
sprintf (keyname, "\\C-%c", _rl_to_lower (UNCTRL (key)));
else if (key == RUBOUT)
......@@ -1966,7 +2048,7 @@ rl_function_dumper (print_readably)
fprintf (rl_outstream, "\n");
for (i = 0; (name = names[i]); i++)
for (i = 0; name = names[i]; i++)
{
rl_command_func_t *function;
char **invokers;
......@@ -2025,8 +2107,8 @@ rl_function_dumper (print_readably)
rl_outstream. If an explicit argument is given, then print
the output in such a way that it can be read back in. */
int
rl_dump_functions (int count __attribute__((unused)),
int key __attribute__((unused)))
rl_dump_functions (count, key)
int count, key;
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
......@@ -2105,7 +2187,8 @@ rl_macro_dumper (print_readably)
}
int
rl_dump_macros(int count __attribute__((unused)), int key __attribute__((unused)))
rl_dump_macros (count, key)
int count, key;
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
......@@ -2114,87 +2197,96 @@ rl_dump_macros(int count __attribute__((unused)), int key __attribute__((unused)
return (0);
}
void
rl_variable_dumper (print_readably)
int print_readably;
static char *
_rl_get_string_variable_value (name)
const char *name;
{
int i;
const char *kname;
static char numbuf[32];
char *ret;
for (i = 0; boolean_varlist[i].name; i++)
if (_rl_stricmp (name, "bell-style") == 0)
{
if (print_readably)
fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name,
*boolean_varlist[i].value ? "on" : "off");
else
fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name,
*boolean_varlist[i].value ? "on" : "off");
}
/* bell-style */
switch (_rl_bell_preference)
{
case NO_BELL:
kname = "none"; break;
return "none";
case VISIBLE_BELL:
kname = "visible"; break;
return "visible";
case AUDIBLE_BELL:
default:
kname = "audible"; break;
return "audible";
}
}
else if (_rl_stricmp (name, "comment-begin") == 0)
return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
else if (_rl_stricmp (name, "completion-query-items") == 0)
{
sprintf (numbuf, "%d", rl_completion_query_items);
return (numbuf);
}
else if (_rl_stricmp (name, "editing-mode") == 0)
return (rl_get_keymap_name_from_edit_mode ());
else if (_rl_stricmp (name, "isearch-terminators") == 0)
{
if (_rl_isearch_terminators == 0)
return 0;
ret = _rl_untranslate_macro_value (_rl_isearch_terminators);
if (ret)
{
strncpy (numbuf, ret, sizeof (numbuf) - 1);
free (ret);
numbuf[sizeof(numbuf) - 1] = '\0';
}
if (print_readably)
fprintf (rl_outstream, "set bell-style %s\n", kname);
else
fprintf (rl_outstream, "bell-style is set to `%s'\n", kname);
/* comment-begin */
if (print_readably)
fprintf (rl_outstream, "set comment-begin %s\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
else
fprintf (rl_outstream, "comment-begin is set to `%s'\n", _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
/* completion-query-items */
if (print_readably)
fprintf (rl_outstream, "set completion-query-items %d\n", rl_completion_query_items);
numbuf[0] = '\0';
return numbuf;
}
else if (_rl_stricmp (name, "keymap") == 0)
{
ret = rl_get_keymap_name (_rl_keymap);
if (ret == 0)
ret = rl_get_keymap_name_from_edit_mode ();
return (ret ? ret : "none");
}
else
fprintf (rl_outstream, "completion-query-items is set to `%d'\n", rl_completion_query_items);
return (0);
}
/* editing-mode */
if (print_readably)
fprintf (rl_outstream, "set editing-mode %s\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
else
fprintf (rl_outstream, "editing-mode is set to `%s'\n", (rl_editing_mode == emacs_mode) ? "emacs" : "vi");
void
rl_variable_dumper (print_readably)
int print_readably;
{
int i;
char *v;
/* isearch-terminators */
if (_rl_isearch_terminators)
for (i = 0; boolean_varlist[i].name; i++)
{
char *disp;
disp = _rl_untranslate_macro_value (_rl_isearch_terminators);
if (print_readably)
fprintf (rl_outstream, "set isearch-terminators \"%s\"\n", disp);
fprintf (rl_outstream, "set %s %s\n", boolean_varlist[i].name,
*boolean_varlist[i].value ? "on" : "off");
else
fprintf (rl_outstream, "isearch-terminators is set to \"%s\"\n", disp);
free (disp);
fprintf (rl_outstream, "%s is set to `%s'\n", boolean_varlist[i].name,
*boolean_varlist[i].value ? "on" : "off");
}
/* keymap */
kname = rl_get_keymap_name (_rl_keymap);
if (kname == 0)
kname = rl_get_keymap_name_from_edit_mode ();
for (i = 0; string_varlist[i].name; i++)
{
v = _rl_get_string_variable_value (string_varlist[i].name);
if (v == 0) /* _rl_isearch_terminators can be NULL */
continue;
if (print_readably)
fprintf (rl_outstream, "set keymap %s\n", kname ? kname : "none");
fprintf (rl_outstream, "set %s %s\n", string_varlist[i].name, v);
else
fprintf (rl_outstream, "keymap is set to `%s'\n", kname ? kname : "none");
fprintf (rl_outstream, "%s is set to `%s'\n", string_varlist[i].name, v);
}
}
/* Print all of the current variables and their values to
rl_outstream. If an explicit argument is given, then print
the output in such a way that it can be read back in. */
int
rl_dump_variables(int count __attribute__((unused)), int key __attribute__((unused)))
rl_dump_variables (count, key)
int count, key;
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
......
/* callback.c -- functions to use readline as an X `callback' mechanism. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -21,7 +21,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include "rlconf.h"
......@@ -41,6 +43,12 @@
#include "rldefs.h"
#include "readline.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* Private data for callback registration functions. See comments in
rl_callback_read_char for more details. */
_rl_callback_func_t *_rl_callback_func = 0;
_rl_callback_generic_arg *_rl_callback_data = 0;
/* **************************************************************** */
/* */
......@@ -70,6 +78,7 @@ _rl_callback_newline ()
{
in_handler = 1;
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
#if defined (HANDLE_SIGNALS)
......@@ -87,6 +96,7 @@ rl_callback_handler_install (prompt, linefunc)
rl_vcpfunc_t *linefunc;
{
rl_set_prompt (prompt);
RL_SETSTATE (RL_STATE_CALLBACK);
rl_linefunc = linefunc;
_rl_callback_newline ();
}
......@@ -96,7 +106,8 @@ void
rl_callback_read_char ()
{
char *line;
int eof;
int eof, jcode;
static procenv_t olevel;
if (rl_linefunc == NULL)
{
......@@ -104,15 +115,88 @@ rl_callback_read_char ()
abort ();
}
memcpy ((void *)olevel, (void *)readline_top_level, sizeof (procenv_t));
jcode = setjmp (readline_top_level);
if (jcode)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
memcpy ((void *)readline_top_level, (void *)olevel, sizeof (procenv_t));
return;
}
do
{
if (RL_ISSTATE (RL_STATE_ISEARCH))
{
eof = _rl_isearch_callback (_rl_iscxt);
if (eof == 0 && (RL_ISSTATE (RL_STATE_ISEARCH) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
rl_callback_read_char ();
return;
}
else if (RL_ISSTATE (RL_STATE_NSEARCH))
{
eof = _rl_nsearch_callback (_rl_nscxt);
return;
}
else if (RL_ISSTATE (RL_STATE_NUMERICARG))
{
eof = _rl_arg_callback (_rl_argcxt);
if (eof == 0 && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0) && RL_ISSTATE (RL_STATE_INPUTPENDING))
rl_callback_read_char ();
/* XXX - this should handle _rl_last_command_was_kill better */
else if (RL_ISSTATE (RL_STATE_NUMERICARG) == 0)
_rl_internal_char_cleanup ();
return;
}
else if (RL_ISSTATE (RL_STATE_MULTIKEY))
{
eof = _rl_dispatch_callback (_rl_kscxt); /* For now */
while ((eof == -1 || eof == -2) && RL_ISSTATE (RL_STATE_MULTIKEY) && _rl_kscxt && (_rl_kscxt->flags & KSEQ_DISPATCHED))
eof = _rl_dispatch_callback (_rl_kscxt);
if (RL_ISSTATE (RL_STATE_MULTIKEY) == 0)
{
_rl_internal_char_cleanup ();
_rl_want_redisplay = 1;
}
}
else if (_rl_callback_func)
{
/* This allows functions that simply need to read an additional
character (like quoted-insert) to register a function to be
called when input is available. _rl_callback_data is simply a
pointer to a struct that has the argument count originally
passed to the registering function and space for any additional
parameters. */
eof = (*_rl_callback_func) (_rl_callback_data);
/* If the function `deregisters' itself, make sure the data is
cleaned up. */
if (_rl_callback_func == 0)
{
if (_rl_callback_data)
{
_rl_callback_data_dispose (_rl_callback_data);
_rl_callback_data = 0;
}
_rl_internal_char_cleanup ();
}
}
else
eof = readline_internal_char ();
/* We loop in case some function has pushed input back with rl_execute_next. */
for (;;)
if (rl_done == 0 && _rl_want_redisplay)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
}
if (rl_done)
{
line = readline_internal_teardown (eof);
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
rl_clear_signals ();
......@@ -129,11 +213,8 @@ rl_callback_read_char ()
if (in_handler == 0 && rl_linefunc)
_rl_callback_newline ();
}
if (rl_pending_input || _rl_pushed_input_available ())
eof = readline_internal_char ();
else
break;
}
while (rl_pending_input || _rl_pushed_input_available () || RL_ISSTATE (RL_STATE_MACROINPUT));
}
/* Remove the handler, and make sure the terminal is in its normal state. */
......@@ -141,9 +222,11 @@ void
rl_callback_handler_remove ()
{
rl_linefunc = NULL;
RL_UNSETSTATE (RL_STATE_CALLBACK);
if (in_handler)
{
in_handler = 0;
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
rl_clear_signals ();
......@@ -151,4 +234,25 @@ rl_callback_handler_remove ()
}
}
_rl_callback_generic_arg *
_rl_callback_data_alloc (count)
int count;
{
_rl_callback_generic_arg *arg;
arg = (_rl_callback_generic_arg *)xmalloc (sizeof (_rl_callback_generic_arg));
arg->count = count;
arg->i1 = arg->i2 = 0;
return arg;
}
void _rl_callback_data_dispose (arg)
_rl_callback_generic_arg *arg;
{
if (arg)
free (arg);
}
#endif
......@@ -59,11 +59,7 @@
#define largest_char 255 /* Largest character value. */
#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0))
#if largest_char >= 255
#define META_CHAR(c) ((c) > meta_character_threshold)
#else
#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
#endif
#define CTRL(c) ((c) & control_character_mask)
#define META(c) ((c) | meta_character_bit)
......@@ -90,6 +86,8 @@
/* Some systems define these; we want our definitions. */
#undef ISPRINT
/* Beware: these only work with single-byte ASCII characters. */
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
......
......@@ -21,7 +21,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
......
/* complete.c -- filename completion for readline. */
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -21,18 +21,12 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__)
#define _XOPEN_SOURCE 500
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include "config_readline.h"
#include <sys/types.h>
/* To get SuSE 9.3 to define wcwidth() (in wchar.h) */
#include <fcntl.h>
#if defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
......@@ -54,7 +48,9 @@
extern int errno;
#endif /* !errno */
#if defined (HAVE_PWD_H)
#include <pwd.h>
#endif
#include "posixdir.h"
#include "posixstat.h"
......@@ -85,9 +81,9 @@ typedef int QSFUNC ();
/* Most systems don't declare getpwent in <pwd.h> if _POSIX_SOURCE is
defined. */
#if !defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE)
#if defined (HAVE_GETPWENT) && (!defined (HAVE_GETPW_DECLS) || defined (_POSIX_SOURCE))
extern struct passwd *getpwent PARAMS((void));
#endif /* !HAVE_GETPW_DECLS || _POSIX_SOURCE */
#endif /* HAVE_GETPWENT && (!HAVE_GETPW_DECLS || _POSIX_SOURCE) */
/* If non-zero, then this is the address of a function to call when
completing a word would normally display the list of possible matches.
......@@ -212,7 +208,8 @@ int rl_completion_type = 0;
/* Up to this many items will be displayed in response to a
possible-completions call. After that, we ask the user if
she is sure she wants to see them all. */
she is sure she wants to see them all. A negative value means
don't ask. */
int rl_completion_query_items = 100;
int _rl_page_completions = 1;
......@@ -360,15 +357,15 @@ rl_complete (ignore, invoking_key)
/* List the possible completions. See description of rl_complete (). */
int
rl_possible_completions (int ignore __attribute__((unused)),
int invoking_key __attribute__((unused)))
rl_possible_completions (ignore, invoking_key)
int ignore, invoking_key;
{
return (rl_complete_internal ('?'));
}
int
rl_insert_completions (int ignore __attribute__((unused)),
int invoking_key __attribute__((unused)))
rl_insert_completions (ignore, invoking_key)
int ignore, invoking_key;
{
return (rl_complete_internal ('*'));
}
......@@ -627,6 +624,8 @@ fnprint (to_print)
mbstate_t ps;
const char *end;
size_t tlen;
int width, w;
wchar_t wc;
end = to_print + strlen (to_print) + 1;
memset (&ps, 0, sizeof (mbstate_t));
......@@ -659,21 +658,28 @@ fnprint (to_print)
else
{
#if defined (HANDLE_MULTIBYTE)
tlen = mbrlen (s, end - s, &ps);
tlen = mbrtowc (&wc, s, end - s, &ps);
if (MB_INVALIDCH (tlen))
{
tlen = 1;
width = 1;
memset (&ps, 0, sizeof (mbstate_t));
}
else if (MB_NULLWCH (tlen))
break;
else
{
w = wcwidth (wc);
width = (w >= 0) ? w : 1;
}
fwrite (s, 1, tlen, rl_outstream);
s += tlen;
printed_len += width;
#else
putc (*s, rl_outstream);
s++;
#endif
printed_len++;
#endif
}
}
......@@ -689,7 +695,7 @@ print_filename (to_print, full_pathname)
char *to_print, *full_pathname;
{
int printed_len, extension_char, slen, tlen;
char *s, c, *new_full_pathname;
char *s, c, *new_full_pathname, *dn;
extension_char = 0;
printed_len = fnprint (to_print);
......@@ -714,7 +720,17 @@ print_filename (to_print, full_pathname)
files in the root directory. If we pass a null string to the
bash directory completion hook, for example, it will expand it
to the current directory. We just want the `/'. */
s = tilde_expand (full_pathname && *full_pathname ? full_pathname : "/");
if (full_pathname == 0 || *full_pathname == 0)
dn = "/";
else if (full_pathname[0] != '/')
dn = full_pathname;
else if (full_pathname[1] == 0)
dn = "//"; /* restore trailing slash to `//' */
else if (full_pathname[1] == '/' && full_pathname[2] == 0)
dn = "/"; /* don't turn /// into // */
else
dn = full_pathname;
s = tilde_expand (dn);
if (rl_directory_completion_hook)
(*rl_directory_completion_hook) (&s);
......@@ -722,6 +738,10 @@ print_filename (to_print, full_pathname)
tlen = strlen (to_print);
new_full_pathname = (char *)xmalloc (slen + tlen + 2);
strcpy (new_full_pathname, s);
if (s[slen - 1] == '/')
slen--;
else
new_full_pathname[slen] = '/';
new_full_pathname[slen] = '/';
strcpy (new_full_pathname + slen + 1, to_print);
......@@ -760,7 +780,10 @@ print_filename (to_print, full_pathname)
}
static char *
rl_quote_filename (char *s, int rtype __attribute__((unused)), char *qcp)
rl_quote_filename (s, rtype, qcp)
char *s;
int rtype;
char *qcp;
{
char *r;
......@@ -810,14 +833,7 @@ _rl_find_completion_word (fp, dp)
quote substrings for the completer. Try to find the start
of an unclosed quoted substring. */
/* FOUND_QUOTE is set so we know what kind of quotes we found. */
#if defined (HANDLE_MULTIBYTE)
for (scan = pass_next = 0; scan < end;
scan = ((MB_CUR_MAX == 1 || rl_byte_oriented)
? (scan + 1)
: _rl_find_next_mbchar (rl_line_buffer, scan, 1, MB_FIND_ANY)))
#else
for (scan = pass_next = 0; scan < end; scan++)
#endif
for (scan = pass_next = 0; scan < end; scan = MB_NEXTCHAR (rl_line_buffer, scan, 1, MB_FIND_ANY))
{
if (pass_next)
{
......@@ -867,11 +883,7 @@ _rl_find_completion_word (fp, dp)
/* We didn't find an unclosed quoted substring upon which to do
completion, so use the word break characters to find the
substring on which to complete. */
#if defined (HANDLE_MULTIBYTE)
while ((rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_ANY)))
#else
while (--rl_point)
#endif
while (rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_ANY))
{
scan = rl_line_buffer[rl_point];
......@@ -938,7 +950,7 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
rl_compentry_func_t *our_func;
int found_quote, quote_char;
{
char **matches, *temp;
char **matches;
rl_completion_found_quote = found_quote;
rl_completion_quote_character = quote_char;
......@@ -957,21 +969,9 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
}
}
/* Beware -- we're stripping the quotes here. Do this only if we know
we are doing filename completion and the application has defined a
filename dequoting function. */
temp = (char *)NULL;
if (found_quote && our_func == rl_filename_completion_function &&
rl_filename_dequoting_function)
{
/* delete single and double quotes */
temp = (*rl_filename_dequoting_function) (text, quote_char);
text = temp; /* not freeing text is not a memory leak */
}
/* XXX -- filename dequoting moved into rl_filename_completion_function */
matches = rl_completion_matches (text, our_func);
FREE (temp);
return matches;
}
......@@ -1104,7 +1104,8 @@ compute_lcd_of_matches (match_list, matches, text)
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
mbstate_t ps_back = ps1;
mbstate_t ps_back;
ps_back = ps1;
if (!_rl_compare_chars (match_list[i], si, &ps1, match_list[i+1], si, &ps2))
break;
else if ((v = _rl_get_char_len (&match_list[i][si], &ps_back)) > 1)
......@@ -1154,8 +1155,7 @@ compute_lcd_of_matches (match_list, matches, text)
rl_completion_found_quote &&
rl_filename_quoting_desired)
{
dtext = (*rl_filename_dequoting_function)
((char*) text, rl_completion_quote_character);
dtext = (*rl_filename_dequoting_function) ((char *)text, rl_completion_quote_character);
text = dtext;
}
......@@ -1401,7 +1401,7 @@ display_matches (matches)
/* If there are many items, then ask the user if she really wants to
see them all. */
if (len >= rl_completion_query_items)
if (rl_completion_query_items > 0 && len >= rl_completion_query_items)
{
rl_crlf ();
fprintf (rl_outstream, "Display all %d possibilities? (y or n)", len);
......@@ -1538,7 +1538,7 @@ append_to_match (text, delimiter, quote_char, nontrivial_match)
: stat (filename, &finfo);
if (s == 0 && S_ISDIR (finfo.st_mode))
{
if (_rl_complete_mark_directories)
if (_rl_complete_mark_directories /* && rl_completion_suppress_append == 0 */)
{
/* This is clumsy. Avoid putting in a double slash if point
is at the end of the line and the previous character is a
......@@ -1802,7 +1802,7 @@ rl_completion_matches (text, entry_function)
match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
match_list[1] = (char *)NULL;
while ((string = (*entry_function) (text, matches)))
while (string = (*entry_function) (text, matches))
{
if (matches + 1 == match_list_size)
match_list = (char **)xrealloc
......@@ -1852,16 +1852,20 @@ rl_username_completion_function (text, state)
setpwent ();
}
while ((entry = getpwent ()))
#if defined (HAVE_GETPWENT)
while (entry = getpwent ())
{
/* Null usernames should result in all users as possible completions. */
if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
break;
}
#endif
if (entry == 0)
{
#if defined (HAVE_GETPWENT)
endpwent ();
#endif
return ((char *)NULL);
}
else
......@@ -1959,13 +1963,30 @@ rl_filename_completion_function (text, state)
if (rl_directory_rewrite_hook)
(*rl_directory_rewrite_hook) (&dirname);
/* The directory completion hook should perform any necessary
dequoting. */
if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
{
free (users_dirname);
users_dirname = savestring (dirname);
}
else if (rl_completion_found_quote && rl_filename_dequoting_function)
{
/* delete single and double quotes */
temp = (*rl_filename_dequoting_function) (users_dirname, rl_completion_quote_character);
free (users_dirname);
users_dirname = temp;
}
directory = opendir (dirname);
/* Now dequote a non-null filename. */
if (filename && *filename && rl_completion_found_quote && rl_filename_dequoting_function)
{
/* delete single and double quotes */
temp = (*rl_filename_dequoting_function) (filename, rl_completion_quote_character);
free (filename);
filename = temp;
}
filename_len = strlen (filename);
rl_filename_completion_desired = 1;
......@@ -2088,7 +2109,8 @@ rl_filename_completion_function (text, state)
hit the end of the match list, we restore the original unmatched text,
ring the bell, and reset the counter to zero. */
int
rl_menu_complete (int count, int ignore __attribute__((unused)))
rl_menu_complete (count, ignore)
int count, ignore;
{
rl_compentry_func_t *our_func;
int matching_filenames, found_quote;
......@@ -2172,9 +2194,11 @@ rl_menu_complete (int count, int ignore __attribute__((unused)))
return (0);
}
match_list_index = (match_list_index + count) % match_list_size;
match_list_index += count;
if (match_list_index < 0)
match_list_index += match_list_size;
else
match_list_index %= match_list_size;
if (match_list_index == 0 && match_list_size > 1)
{
......
......@@ -4,9 +4,27 @@ dnl
dnl report bugs to chet@po.cwru.edu
dnl
dnl Process this file with autoconf to produce a configure script.
AC_REVISION([for Readline 5.0, version 2.52, from autoconf version] AC_ACVERSION)
AC_INIT(readline, 5.0-rc1, bug-readline@gnu.org)
# Copyright (C) 1987-2005 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
AC_REVISION([for Readline 5.2, version 2.61])
AC_INIT(readline, 5.2, bug-readline@gnu.org)
dnl make sure we are using a recent autoconf version
AC_PREREQ(2.50)
......@@ -16,20 +34,28 @@ AC_CONFIG_AUX_DIR(./support)
AC_CONFIG_HEADERS(config.h)
dnl update the value of RL_READLINE_VERSION in readline.h when this changes
LIBVERSION=5.0
LIBVERSION=5.2
AC_CANONICAL_HOST
dnl configure defaults
opt_curses=no
opt_purify=no
dnl arguments to configure
AC_ARG_WITH(curses, AC_HELP_STRING([--with-curses], [use the curses library instead of the termcap library]), opt_curses=$withval)
AC_ARG_WITH(purify, AC_HELP_STRING([--with-purify], [configure to postprocess with purify]), opt_purify=$withval)
if test "$opt_curses" = "yes"; then
prefer_curses=yes
fi
if test "$opt_purify" = yes; then
PURIFY="purify"
else
PURIFY=
fi
dnl option parsing for optional features
opt_multibyte=yes
opt_static_libs=yes
......@@ -43,6 +69,36 @@ if test $opt_multibyte = no; then
AC_DEFINE(NO_MULTIBYTE_SUPPORT)
fi
dnl load up the cross-building cache file -- add more cases and cache
dnl files as necessary
dnl Note that host and target machine are the same, and different than the
dnl build machine.
CROSS_COMPILE=
if test "x$cross_compiling" = "xyes"; then
case "${host}" in
*-cygwin*)
cross_cache=${srcdir}/cross-build/cygwin.cache
;;
*-mingw*)
cross_cache=${srcdir}/cross-build/mingw.cache
;;
i[[3456]]86-*-beos*)
cross_cache=${srcdir}/cross-build/x86-beos.cache
;;
*) echo "configure: cross-compiling for $host is not supported" >&2
;;
esac
if test -n "${cross_cache}" && test -r "${cross_cache}"; then
echo "loading cross-build cache file ${cross_cache}"
. ${cross_cache}
fi
unset cross_cache
CROSS_COMPILE='-DCROSS_COMPILING'
AC_SUBST(CROSS_COMPILE)
fi
echo ""
echo "Beginning configuration for readline-$LIBVERSION for ${host_cpu}-${host_vendor}-${host_os}"
echo ""
......@@ -83,14 +139,24 @@ AC_HEADER_STDC
AC_HEADER_STAT
AC_HEADER_DIRENT
AC_CHECK_FUNCS(lstat memmove putenv select setenv setlocale \
strcasecmp strpbrk tcgetattr vsnprintf isascii isxdigit)
AC_CHECK_FUNCS(fcntl kill lstat)
AC_CHECK_FUNCS(memmove putenv select setenv setlocale \
strcasecmp strpbrk tcgetattr vsnprintf)
AC_CHECK_FUNCS(isascii isxdigit)
AC_CHECK_FUNCS(getpwent getpwnam getpwuid)
AC_FUNC_STRCOLL
AC_CHECK_HEADERS(unistd.h stdlib.h varargs.h stdarg.h string.h strings.h \
limits.h sys/ptem.h sys/pte.h sys/stream.h sys/select.h \
termcap.h termios.h termio.h sys/file.h locale.h memory.h )
AC_CHECK_HEADERS(fcntl.h unistd.h stdlib.h varargs.h stdarg.h string.h strings.h \
limits.h locale.h pwd.h memory.h termcap.h termios.h termio.h)
AC_CHECK_HEADERS(sys/pte.h sys/stream.h sys/select.h sys/file.h)
AC_CHECK_HEADERS(sys/ptem.h,,,
[[
#if HAVE_SYS_STREAM_H
# include <sys/stream.h>
#endif
]])
BASH_SYS_SIGNAL_VINTAGE
BASH_SYS_REINSTALL_SIGHANDLERS
......@@ -143,7 +209,13 @@ esac
#
if test -f ${srcdir}/support/shobj-conf; then
AC_MSG_CHECKING(configuration for building shared libraries)
eval `${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}`
eval `TERMCAP_LIB=$TERMCAP_LIB ${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}`
# case "$SHLIB_LIBS" in
# *curses*|*termcap*|*termlib*) ;;
# *) SHLIB_LIBS="$SHLIB_LIBS $TERMCAP_LIB" ;;
# esac
AC_SUBST(SHOBJ_CC)
AC_SUBST(SHOBJ_CFLAGS)
AC_SUBST(SHOBJ_LD)
......@@ -153,8 +225,11 @@ if test -f ${srcdir}/support/shobj-conf; then
AC_SUBST(SHOBJ_STATUS)
AC_SUBST(SHLIB_STATUS)
AC_SUBST(SHLIB_XLDFLAGS)
AC_SUBST(SHLIB_DOT)
AC_SUBST(SHLIB_LIBPREF)
AC_SUBST(SHLIB_LIBSUFF)
AC_SUBST(SHLIB_LIBVERSION)
AC_SUBST(SHLIB_DLLVERSION)
AC_SUBST(SHLIB_LIBS)
AC_MSG_RESULT($SHLIB_STATUS)
......@@ -191,6 +266,12 @@ msdosdjgpp*) BUILD_DIR=`pwd.exe` ;; # to prevent //d/path/file
*) BUILD_DIR=`pwd` ;;
esac
case "$BUILD_DIR" in
*\ *) BUILD_DIR=`echo "$BUILD_DIR" | sed 's: :\\\\ :g'` ;;
*) ;;
esac
AC_SUBST(PURIFY)
AC_SUBST(BUILD_DIR)
AC_SUBST(CFLAGS)
......
/* display.c -- readline redisplay facility. */
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
/* Copyright (C) 1987-2006 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -21,16 +21,12 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 500
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include "config_readline.h"
#include <sys/types.h>
/* To get SuSE 9.3 to define wcwidth() (in wchar.h) */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
......@@ -63,10 +59,6 @@
extern char *strchr (), *strrchr ();
#endif /* !strchr && !__STDC__ */
#if defined (HACK_TERMCAP_MOTION)
extern char *_rl_term_forward_char;
#endif
static void update_line PARAMS((char *, char *, int, int, int, int));
static void space_to_eol PARAMS((int));
static void delete_chars PARAMS((int));
......@@ -84,9 +76,18 @@ static int *inv_lbreaks, *vis_lbreaks;
static int inv_lbsize, vis_lbsize;
/* Heuristic used to decide whether it is faster to move from CUR to NEW
by backing up or outputting a carriage return and moving forward. */
by backing up or outputting a carriage return and moving forward. CUR
and NEW are either both buffer positions or absolute screen positions. */
#define CR_FASTER(new, cur) (((new) + 1) < ((cur) - (new)))
/* _rl_last_c_pos is an absolute cursor position in multibyte locales and a
buffer index in others. This macro is used when deciding whether the
current cursor position is in the middle of a prompt string containing
invisible characters. */
#define PROMPT_ENDING_INDEX \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) ? prompt_physical_chars : prompt_last_invisible+1)
/* **************************************************************** */
/* */
/* Display stuff */
......@@ -122,16 +123,25 @@ rl_voidfunc_t *rl_redisplay_function = rl_redisplay;
int rl_display_fixed = 0;
int _rl_suppress_redisplay = 0;
int _rl_want_redisplay = 0;
/* The stuff that gets printed out before the actual text of the line.
This is usually pointing to rl_prompt. */
char *rl_display_prompt = (char *)NULL;
/* Pseudo-global variables declared here. */
/* The visible cursor position. If you print some text, adjust this. */
/* NOTE: _rl_last_c_pos is used as a buffer index when not in a locale
supporting multibyte characters, and an absolute cursor position when
in such a locale. This is an artifact of the donated multibyte support.
Care must be taken when modifying its value. */
int _rl_last_c_pos = 0;
int _rl_last_v_pos = 0;
static int cpos_adjusted;
static int cpos_buffer_position;
/* Number of lines currently on screen minus 1. */
int _rl_vis_botlin = 0;
......@@ -158,6 +168,7 @@ static int line_size = 1024;
include invisible characters. */
static char *local_prompt, *local_prompt_prefix;
static int local_prompt_len;
static int prompt_visible_length, prompt_prefix_length;
/* The number of invisible characters in the line currently being
......@@ -184,6 +195,19 @@ static int prompt_last_screen_line;
static int prompt_physical_chars;
/* Variables to save and restore prompt and display information. */
/* These are getting numerous enough that it's time to create a struct. */
static char *saved_local_prompt;
static char *saved_local_prefix;
static int saved_last_invisible;
static int saved_visible_length;
static int saved_prefix_length;
static int saved_local_length;
static int saved_invis_chars_first_line;
static int saved_physical_chars;
/* Expand the prompt string S and return the number of visible
characters in *LP, if LP is not null. This is currently more-or-less
a placeholder for expansion. LIP, if non-null is a place to store the
......@@ -204,8 +228,8 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
char *pmt;
int *lp, *lip, *niflp, *vlp;
{
char *r, *ret, *p;
int l, rl, last, ignoring, ninvis, invfl, ind, pind, physchars;
char *r, *ret, *p, *igstart;
int l, rl, last, ignoring, ninvis, invfl, invflset, ind, pind, physchars;
/* Short-circuit if we can. */
if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
......@@ -218,7 +242,7 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
if (niflp)
*niflp = 0;
if (vlp)
*vlp = lp ? *lp : (int) strlen (r);
*vlp = lp ? *lp : strlen (r);
return r;
}
......@@ -226,19 +250,23 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
r = ret = (char *)xmalloc (l + 1);
invfl = 0; /* invisible chars in first line of prompt */
invflset = 0; /* we only want to set invfl once */
igstart = 0;
for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
{
/* This code strips the invisible character string markers
RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
if (*p == RL_PROMPT_START_IGNORE)
if (ignoring == 0 && *p == RL_PROMPT_START_IGNORE) /* XXX - check ignoring? */
{
ignoring++;
ignoring = 1;
igstart = p;
continue;
}
else if (ignoring && *p == RL_PROMPT_END_IGNORE)
{
ignoring = 0;
if (p != (igstart + 1))
last = r - ret - 1;
continue;
}
......@@ -253,7 +281,10 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
while (l--)
*r++ = *p++;
if (!ignoring)
{
rl += ind - pind;
physchars += _rl_col_width (pmt, pind, ind);
}
else
ninvis += ind - pind;
p--; /* compensate for later increment */
......@@ -263,16 +294,19 @@ expand_prompt (pmt, lp, lip, niflp, vlp)
{
*r++ = *p;
if (!ignoring)
{
rl++; /* visible length byte counter */
physchars++;
}
else
ninvis++; /* invisible chars byte counter */
}
if (rl >= _rl_screenwidth)
if (invflset == 0 && rl >= _rl_screenwidth)
{
invfl = ninvis;
if (ignoring == 0)
physchars++;
invflset = 1;
}
}
}
......@@ -332,7 +366,9 @@ rl_expand_prompt (prompt)
FREE (local_prompt_prefix);
local_prompt = local_prompt_prefix = (char *)0;
prompt_last_invisible = prompt_visible_length = 0;
local_prompt_len = 0;
prompt_last_invisible = prompt_invis_chars_first_line = 0;
prompt_visible_length = prompt_physical_chars = 0;
if (prompt == 0 || *prompt == 0)
return (0);
......@@ -346,6 +382,7 @@ rl_expand_prompt (prompt)
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)0;
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
return (prompt_visible_length);
}
else
......@@ -355,15 +392,16 @@ rl_expand_prompt (prompt)
local_prompt = expand_prompt (p, &prompt_visible_length,
&prompt_last_invisible,
(int *)NULL,
(int *)NULL);
&prompt_physical_chars);
c = *t; *t = '\0';
/* The portion of the prompt string up to and including the
final newline is now null-terminated. */
local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
(int *)NULL,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
(int *)NULL);
*t = c;
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
return (prompt_prefix_length);
}
}
......@@ -420,13 +458,13 @@ rl_redisplay ()
{
register int in, out, c, linenum, cursor_linenum;
register char *line;
int c_pos, inv_botlin, lb_botlin, lb_linenum;
int newlines, lpos, temp, modmark;
int inv_botlin, lb_botlin, lb_linenum, o_cpos;
int newlines, lpos, temp, modmark, n0, num;
char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE)
wchar_t wc;
size_t wc_bytes;
int wc_width= 0;
int wc_width;
mbstate_t ps;
int _rl_wrapped_multicolumn = 0;
#endif
......@@ -435,16 +473,16 @@ rl_redisplay ()
return;
if (!rl_display_prompt)
rl_display_prompt = (char*) "";
rl_display_prompt = "";
if (invisible_line == 0)
if (invisible_line == 0 || vis_lbreaks == 0)
{
init_line_structures (0);
rl_on_new_line ();
}
/* Draw the line into the buffer. */
c_pos = -1;
cpos_buffer_position = -1;
line = invisible_line;
out = inv_botlin = 0;
......@@ -471,24 +509,23 @@ rl_redisplay ()
number of non-visible characters in the prompt string. */
if (rl_display_prompt == rl_prompt || local_prompt)
{
int local_len = local_prompt ? strlen (local_prompt) : 0;
if (local_prompt_prefix && forced_display)
_rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
if (local_len > 0)
if (local_prompt_len > 0)
{
temp = local_len + out + 2;
temp = local_prompt_len + out + 2;
if (temp >= line_size)
{
line_size = (temp + 1024) - (temp % 1024);
visible_line = (char *)xrealloc (visible_line, line_size);
line = invisible_line = (char *)xrealloc (invisible_line, line_size);
}
strncpy (line + out, local_prompt, local_len);
out += local_len;
strncpy (line + out, local_prompt, local_prompt_len);
out += local_prompt_len;
}
line[out] = '\0';
wrap_offset = local_len - prompt_visible_length;
wrap_offset = local_prompt_len - prompt_visible_length;
}
else
{
......@@ -524,17 +561,6 @@ rl_redisplay ()
wrap_offset = prompt_invis_chars_first_line = 0;
}
#if defined (HANDLE_MULTIBYTE)
#define CHECK_INV_LBREAKS() \
do { \
if (newlines >= (inv_lbsize - 2)) \
{ \
inv_lbsize *= 2; \
inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
_rl_wrapped_line = (int *)xrealloc (_rl_wrapped_line, inv_lbsize * sizeof (int)); \
} \
} while (0)
#else
#define CHECK_INV_LBREAKS() \
do { \
if (newlines >= (inv_lbsize - 2)) \
......@@ -543,7 +569,6 @@ rl_redisplay ()
inv_lbreaks = (int *)xrealloc (inv_lbreaks, inv_lbsize * sizeof (int)); \
} \
} while (0)
#endif
#if defined (HANDLE_MULTIBYTE)
#define CHECK_LPOS() \
......@@ -589,6 +614,7 @@ rl_redisplay ()
#if defined (HANDLE_MULTIBYTE)
memset (_rl_wrapped_line, 0, vis_lbsize);
num = 0;
#endif
/* prompt_invis_chars_first_line is the number of invisible characters in
......@@ -600,6 +626,7 @@ rl_redisplay ()
contents of the command line? */
while (lpos >= _rl_screenwidth)
{
int z;
/* fix from Darin Johnson <darin@acuson.com> for prompt string with
invisible characters that is longer than the screen width. The
prompt_invis_chars_first_line variable could be made into an array
......@@ -607,19 +634,47 @@ rl_redisplay ()
probably too much work for the benefit gained. How many people have
prompts that exceed two physical lines?
Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
temp = ((newlines + 1) * _rl_screenwidth) +
((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
n0 = num;
temp = local_prompt_len;
while (num < temp)
{
z = _rl_col_width (local_prompt, n0, num);
if (z > _rl_screenwidth)
{
num = _rl_find_prev_mbchar (local_prompt, num, MB_FIND_ANY);
break;
}
else if (z == _rl_screenwidth)
break;
num++;
}
temp = num;
}
else
#endif /* !HANDLE_MULTIBYTE */
temp = ((newlines + 1) * _rl_screenwidth);
/* Now account for invisible characters in the current line. */
temp += ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
: ((newlines == 1) ? wrap_offset : 0))
: ((newlines == 0) ? wrap_offset :0));
inv_lbreaks[++newlines] = temp;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
lpos -= _rl_col_width (local_prompt, n0, num);
else
#endif
lpos -= _rl_screenwidth;
}
prompt_last_screen_line = newlines;
/* Draw the rest of the line (after the prompt) into invisible_line, keeping
track of where the cursor is (c_pos), the number of the line containing
track of where the cursor is (cpos_buffer_position), the number of the line containing
the cursor (lb_linenum), the last line number (lb_botlin and inv_botlin).
It maintains an array of line breaks for display (inv_lbreaks).
This handles expanding tabs for display and displaying meta characters. */
......@@ -672,7 +727,7 @@ rl_redisplay ()
if (in == rl_point)
{
c_pos = out;
cpos_buffer_position = out;
lb_linenum = newlines;
}
......@@ -766,10 +821,10 @@ rl_redisplay ()
}
if (in == rl_point)
{
c_pos = out;
cpos_buffer_position = out;
lb_linenum = newlines;
}
for (i = in; i < (int) (in+wc_bytes); i++)
for (i = in; i < in+wc_bytes; i++)
line[out++] = rl_line_buffer[i];
for (i = 0; i < wc_width; i++)
CHECK_LPOS();
......@@ -797,9 +852,9 @@ rl_redisplay ()
}
line[out] = '\0';
if (c_pos < 0)
if (cpos_buffer_position < 0)
{
c_pos = out;
cpos_buffer_position = out;
lb_linenum = newlines;
}
......@@ -808,7 +863,7 @@ rl_redisplay ()
inv_lbreaks[newlines+1] = out;
cursor_linenum = lb_linenum;
/* C_POS == position in buffer where cursor should be placed.
/* CPOS_BUFFER_POSITION == position in buffer where cursor should be placed.
CURSOR_LINENUM == line number where the cursor should be placed. */
/* PWP: now is when things get a bit hairy. The visible and invisible
......@@ -822,7 +877,7 @@ rl_redisplay ()
if (_rl_horizontal_scroll_mode == 0 && _rl_term_up && *_rl_term_up)
{
int nleft, pos, changed_screen_line;
int nleft, pos, changed_screen_line, tx;
if (!rl_display_fixed || forced_display)
{
......@@ -847,15 +902,38 @@ rl_redisplay ()
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? (char*) "" : VIS_CHARS(line)
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
/* For each line in the buffer, do the updating display. */
for (linenum = 0; linenum <= inv_botlin; linenum++)
{
/* This can lead us astray if we execute a program that changes
the locale from a non-multibyte to a multibyte one. */
o_cpos = _rl_last_c_pos;
cpos_adjusted = 0;
update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
/* update_line potentially changes _rl_last_c_pos, but doesn't
take invisible characters into account, since _rl_last_c_pos
is an absolute cursor position in a multibyte locale. See
if compensating here is the right thing, or if we have to
change update_line itself. There is one case in which
update_line adjusts _rl_last_c_pos itself (so it can pass
_rl_move_cursor_relative accurate values); it communicates
this back by setting cpos_adjusted. If we assume that
_rl_last_c_pos is correct (an absolute cursor position) each
time update_line is called, then we can assume in our
calculations that o_cpos does not need to be adjusted by
wrap_offset. */
if (linenum == 0 && (MB_CUR_MAX > 1 && rl_byte_oriented == 0) &&
cpos_adjusted == 0 &&
_rl_last_c_pos != o_cpos &&
_rl_last_c_pos > wrap_offset &&
o_cpos < prompt_last_invisible)
_rl_last_c_pos -= wrap_offset;
/* If this is the line with the prompt, we might need to
compensate for invisible characters in the new line. Do
this only if there is not more than one new line (which
......@@ -867,6 +945,9 @@ rl_redisplay ()
(wrap_offset > visible_wrap_offset) &&
(_rl_last_c_pos < visible_first_line_len))
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
nleft = _rl_screenwidth - _rl_last_c_pos;
else
nleft = _rl_screenwidth + wrap_offset - _rl_last_c_pos;
if (nleft)
_rl_clear_to_eol (nleft);
......@@ -888,7 +969,7 @@ rl_redisplay ()
_rl_move_vert (linenum);
_rl_move_cursor_relative (0, tt);
_rl_clear_to_eol
((linenum == _rl_vis_botlin) ? (int) strlen (tt) : _rl_screenwidth);
((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
}
}
_rl_vis_botlin = inv_botlin;
......@@ -903,7 +984,7 @@ rl_redisplay ()
the physical cursor position on the screen stays the same,
but the buffer position needs to be adjusted to account
for invisible characters. */
if (cursor_linenum == 0 && wrap_offset)
if ((MB_CUR_MAX == 1 || rl_byte_oriented) && cursor_linenum == 0 && wrap_offset)
_rl_last_c_pos += wrap_offset;
}
......@@ -914,7 +995,11 @@ rl_redisplay ()
invisible character in the prompt string. */
nleft = prompt_visible_length + wrap_offset;
if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
_rl_last_c_pos <= prompt_last_invisible && local_prompt)
#if 0
_rl_last_c_pos <= PROMPT_ENDING_INDEX && local_prompt)
#else
_rl_last_c_pos < PROMPT_ENDING_INDEX && local_prompt)
#endif
{
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
......@@ -924,7 +1009,7 @@ rl_redisplay ()
#endif
_rl_output_some_chars (local_prompt, nleft);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
_rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft);
_rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft) - wrap_offset;
else
_rl_last_c_pos = nleft;
}
......@@ -933,21 +1018,35 @@ rl_redisplay ()
in the buffer? */
pos = inv_lbreaks[cursor_linenum];
/* nleft == number of characters in the line buffer between the
start of the line and the cursor position. */
nleft = c_pos - pos;
start of the line and the desired cursor position. */
nleft = cpos_buffer_position - pos;
/* NLEFT is now a number of characters in a buffer. When in a
multibyte locale, however, _rl_last_c_pos is an absolute cursor
position that doesn't take invisible characters in the prompt
into account. We use a fudge factor to compensate. */
/* Since _rl_backspace() doesn't know about invisible characters in the
prompt, and there's no good way to tell it, we compensate for
those characters here and call _rl_backspace() directly. */
if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
{
_rl_backspace (_rl_last_c_pos - nleft);
/* TX == new physical cursor position in multibyte locale. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
_rl_last_c_pos = _rl_col_width (&visible_line[pos], 0, nleft);
tx = _rl_col_width (&visible_line[pos], 0, nleft) - visible_wrap_offset;
else
_rl_last_c_pos = nleft;
tx = nleft;
if (_rl_last_c_pos > tx)
{
_rl_backspace (_rl_last_c_pos - tx); /* XXX */
_rl_last_c_pos = tx;
}
}
/* We need to note that in a multibyte locale we are dealing with
_rl_last_c_pos as an absolute cursor position, but moving to a
point specified by a buffer position (NLEFT) that doesn't take
invisible characters into account. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
_rl_move_cursor_relative (nleft, &invisible_line[pos]);
else if (nleft != _rl_last_c_pos)
......@@ -966,11 +1065,11 @@ rl_redisplay ()
will be LMARGIN. */
/* The number of characters that will be displayed before the cursor. */
ndisp = c_pos - wrap_offset;
ndisp = cpos_buffer_position - wrap_offset;
nleft = prompt_visible_length + wrap_offset;
/* Where the new cursor position will be on the screen. This can be
longer than SCREENWIDTH; if it is, lmargin will be adjusted. */
phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset);
phys_c_pos = cpos_buffer_position - (last_lmargin ? last_lmargin : wrap_offset);
t = _rl_screenwidth / 3;
/* If the number of characters had already exceeded the screenwidth,
......@@ -981,7 +1080,7 @@ rl_redisplay ()
two-thirds of the way across the screen. */
if (phys_c_pos > _rl_screenwidth - 2)
{
lmargin = c_pos - (2 * t);
lmargin = cpos_buffer_position - (2 * t);
if (lmargin < 0)
lmargin = 0;
/* If the left margin would be in the middle of a prompt with
......@@ -995,7 +1094,7 @@ rl_redisplay ()
{
/* If we are moving back towards the beginning of the line and
the last margin is no longer correct, compute a new one. */
lmargin = ((c_pos - 1) / t) * t; /* XXX */
lmargin = ((cpos_buffer_position - 1) / t) * t; /* XXX */
if (wrap_offset && lmargin > 0 && lmargin < nleft)
lmargin = nleft;
}
......@@ -1040,7 +1139,7 @@ rl_redisplay ()
if (visible_first_line_len > _rl_screenwidth)
visible_first_line_len = _rl_screenwidth;
_rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]);
_rl_move_cursor_relative (cpos_buffer_position - lmargin, &invisible_line[lmargin]);
last_lmargin = lmargin;
}
}
......@@ -1106,6 +1205,9 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
the exact cursor position and cut-and-paste with certain terminal
emulators. In this calculation, TEMP is the physical screen
position of the cursor. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
temp = _rl_last_c_pos;
else
temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
if (temp == _rl_screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
&& _rl_last_v_pos == current_line - 1)
......@@ -1171,7 +1273,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
putc (new[0], rl_outstream);
else
putc (' ', rl_outstream);
_rl_last_c_pos = 1; /* XXX */
_rl_last_c_pos = 1;
_rl_last_v_pos++;
if (old[0] && new[0])
old[0] = new[0];
......@@ -1312,7 +1414,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
if (_rl_last_v_pos != current_line)
{
_rl_move_vert (current_line);
if (current_line == 0 && visible_wrap_offset)
if ((MB_CUR_MAX == 1 || rl_byte_oriented) && current_line == 0 && visible_wrap_offset)
_rl_last_c_pos += visible_wrap_offset;
}
......@@ -1328,11 +1430,11 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
sequences (like drawing the `unbold' sequence without a corresponding
`bold') that manifests itself on certain terminals. */
lendiff = local_prompt ? strlen (local_prompt) : 0;
lendiff = local_prompt_len;
od = ofd - old; /* index of first difference in visible line */
if (current_line == 0 && !_rl_horizontal_scroll_mode &&
_rl_term_cr && lendiff > prompt_visible_length && _rl_last_c_pos > 0 &&
od >= lendiff && _rl_last_c_pos <= prompt_last_invisible)
od >= lendiff && _rl_last_c_pos < PROMPT_ENDING_INDEX)
{
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
......@@ -1341,12 +1443,29 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
#endif
_rl_output_some_chars (local_prompt, lendiff);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
_rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff);
{
/* We take wrap_offset into account here so we can pass correct
information to _rl_move_cursor_relative. */
_rl_last_c_pos = _rl_col_width (local_prompt, 0, lendiff) - wrap_offset;
cpos_adjusted = 1;
}
else
_rl_last_c_pos = lendiff;
}
/* When this function returns, _rl_last_c_pos is correct, and an absolute
cursor postion in multibyte mode, but a buffer index when not in a
multibyte locale. */
_rl_move_cursor_relative (od, old);
#if 1
#if defined (HANDLE_MULTIBYTE)
/* We need to indicate that the cursor position is correct in the presence of
invisible characters in the prompt string. Let's see if setting this when
we make sure we're at the end of the drawn prompt string works. */
if (current_line == 0 && MB_CUR_MAX > 1 && rl_byte_oriented == 0 && _rl_last_c_pos == prompt_physical_chars)
cpos_adjusted = 1;
#endif
#endif
/* if (len (new) > len (old))
lendiff == difference in buffer
......@@ -1403,7 +1522,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
insert_some_chars (nfd, lendiff, col_lendiff);
_rl_last_c_pos += col_lendiff;
}
else if (*ols == 0 && lendiff > 0)
else if ((MB_CUR_MAX == 1 || rl_byte_oriented != 0) && *ols == 0 && lendiff > 0)
{
/* At the end of a line the characters do not have to
be "inserted". They can just be placed on the screen. */
......@@ -1442,6 +1561,10 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
/* cannot insert chars, write to EOL */
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += col_temp;
/* If we're in a multibyte locale and were before the last invisible
char in the current line (which implies we just output some invisible
characters) we need to adjust _rl_last_c_pos, since it represents
a physical character position. */
}
}
else /* Delete characters from line. */
......@@ -1473,7 +1596,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
if (temp > 0)
{
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += col_temp;
_rl_last_c_pos += col_temp; /* XXX */
}
lendiff = (oe - old) - (ne - new);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
......@@ -1535,7 +1658,7 @@ rl_on_new_line_with_prompt ()
l = strlen (prompt_last_line);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
_rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l);
_rl_last_c_pos = _rl_col_width (prompt_last_line, 0, l); /* XXX */
else
_rl_last_c_pos = l;
......@@ -1570,10 +1693,11 @@ rl_on_new_line_with_prompt ()
int
rl_forced_update_display ()
{
register char *temp;
if (visible_line)
{
register char *temp = visible_line;
temp = visible_line;
while (*temp)
*temp++ = '\0';
}
......@@ -1584,6 +1708,8 @@ rl_forced_update_display ()
}
/* Move the cursor from _rl_last_c_pos to NEW, which are buffer indices.
(Well, when we don't have multibyte characters, _rl_last_c_pos is a
buffer index.)
DATA is the contents of the screen line of interest; i.e., where
the movement is being done. */
void
......@@ -1592,29 +1718,47 @@ _rl_move_cursor_relative (new, data)
const char *data;
{
register int i;
int woff; /* number of invisible chars on current line */
int cpos, dpos; /* current and desired cursor positions */
/* If we don't have to do anything, then return. */
woff = W_OFFSET (_rl_last_v_pos, wrap_offset);
cpos = _rl_last_c_pos;
#if defined (HANDLE_MULTIBYTE)
/* If we have multibyte characters, NEW is indexed by the buffer point in
a multibyte string, but _rl_last_c_pos is the display position. In
this case, NEW's display position is not obvious and must be
calculated. */
if (MB_CUR_MAX == 1 || rl_byte_oriented)
calculated. We need to account for invisible characters in this line,
as long as we are past them and they are counted by _rl_col_width. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
if (_rl_last_c_pos == new)
return;
dpos = _rl_col_width (data, 0, new);
if (dpos > prompt_last_invisible) /* XXX - don't use woff here */
{
dpos -= woff;
/* Since this will be assigned to _rl_last_c_pos at the end (more
precisely, _rl_last_c_pos == dpos when this function returns),
let the caller know. */
cpos_adjusted = 1;
}
else if (_rl_last_c_pos == _rl_col_width (data, 0, new))
return;
#else
if (_rl_last_c_pos == new) return;
}
else
#endif
dpos = new;
/* If we don't have to do anything, then return. */
if (cpos == dpos)
return;
/* It may be faster to output a CR, and then move forwards instead
of moving backwards. */
/* i == current physical cursor position. */
i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
i = _rl_last_c_pos;
else
#endif
i = _rl_last_c_pos - woff;
if (dpos == 0 || CR_FASTER (dpos, _rl_last_c_pos) ||
(_rl_term_autowrap && i == _rl_screenwidth))
{
#if defined (__MSDOS__)
......@@ -1622,10 +1766,10 @@ _rl_move_cursor_relative (new, data)
#else
tputs (_rl_term_cr, 1, _rl_output_character_function);
#endif /* !__MSDOS__ */
_rl_last_c_pos = 0;
cpos = _rl_last_c_pos = 0;
}
if (_rl_last_c_pos < new)
if (cpos < dpos)
{
/* Move the cursor forward. We do it by printing the command
to move the cursor forward if there is one, else print that
......@@ -1636,67 +1780,43 @@ _rl_move_cursor_relative (new, data)
sequence telling the terminal to move forward one character.
That kind of control is for people who don't know what the
data is underneath the cursor. */
#if defined (HACK_TERMCAP_MOTION)
if (_rl_term_forward_char)
{
/* However, we need a handle on where the current display position is
in the buffer for the immediately preceding comment to be true.
In multibyte locales, we don't currently have that info available.
Without it, we don't know where the data we have to display begins
in the buffer and we have to go back to the beginning of the screen
line. In this case, we can use the terminal sequence to move forward
if it's available. */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int width;
width = _rl_col_width (data, _rl_last_c_pos, new);
for (i = 0; i < width; i++)
tputs (_rl_term_forward_char, 1, _rl_output_character_function);
}
else
if (_rl_term_forward_char)
{
for (i = _rl_last_c_pos; i < new; i++)
for (i = cpos; i < dpos; i++)
tputs (_rl_term_forward_char, 1, _rl_output_character_function);
}
}
else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
tputs (_rl_term_cr, 1, _rl_output_character_function);
for (i = 0; i < new; i++)
putc (data[i], rl_outstream);
}
else
for (i = _rl_last_c_pos; i < new; i++)
putc (data[i], rl_outstream);
#else /* !HACK_TERMCAP_MOTION */
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
tputs (_rl_term_cr, 1, _rl_output_character_function);
for (i = 0; i < new; i++)
putc (data[i], rl_outstream);
}
}
else
for (i = _rl_last_c_pos; i < new; i++)
for (i = cpos; i < new; i++)
putc (data[i], rl_outstream);
#endif /* !HACK_TERMCAP_MOTION */
}
#if defined (HANDLE_MULTIBYTE)
/* NEW points to the buffer point, but _rl_last_c_pos is the display point.
The byte length of the string is probably bigger than the column width
of the string, which means that if NEW == _rl_last_c_pos, then NEW's
display point is less than _rl_last_c_pos. */
else if (_rl_last_c_pos >= new)
#else
else if (_rl_last_c_pos > new)
#endif
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
_rl_backspace (_rl_last_c_pos - _rl_col_width (data, 0, new));
else
_rl_backspace (_rl_last_c_pos - new);
}
else if (cpos > dpos)
_rl_backspace (cpos - dpos);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
_rl_last_c_pos = _rl_col_width (data, 0, new);
else
_rl_last_c_pos = new;
_rl_last_c_pos = dpos;
}
/* PWP: move the cursor up or down. */
......@@ -1785,9 +1905,9 @@ rl_character_len (c, pos)
return ((ISPRINT (uc)) ? 1 : 2);
}
/* How to print things in the "echo-area". The prompt is treated as a
mini-modeline. */
static int msg_saved_prompt = 0;
#if defined (USE_VARARGS)
int
......@@ -1818,8 +1938,20 @@ rl_message (va_alist)
#endif
va_end (args);
if (saved_local_prompt == 0)
{
rl_save_prompt ();
msg_saved_prompt = 1;
}
rl_display_prompt = msg_buf;
local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)NULL;
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
(*rl_redisplay_function) ();
return 0;
}
#else /* !USE_VARARGS */
......@@ -1829,8 +1961,21 @@ rl_message (format, arg1, arg2)
{
sprintf (msg_buf, format, arg1, arg2);
msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
rl_display_prompt = msg_buf;
if (saved_local_prompt == 0)
{
rl_save_prompt ();
msg_saved_prompt = 1;
}
local_prompt = expand_prompt (msg_buf, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)NULL;
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
(*rl_redisplay_function) ();
return 0;
}
#endif /* !USE_VARARGS */
......@@ -1840,6 +1985,11 @@ int
rl_clear_message ()
{
rl_display_prompt = rl_prompt;
if (msg_saved_prompt)
{
rl_restore_prompt ();
msg_saved_prompt = 0;
}
(*rl_redisplay_function) ();
return 0;
}
......@@ -1849,32 +1999,26 @@ rl_reset_line_state ()
{
rl_on_new_line ();
rl_display_prompt = rl_prompt ? rl_prompt : (char*) "";
rl_display_prompt = rl_prompt ? rl_prompt : "";
forced_display = 1;
return 0;
}
/* These are getting numerous enough that it's time to create a struct. */
static char *saved_local_prompt;
static char *saved_local_prefix;
static int saved_last_invisible;
static int saved_visible_length;
static int saved_invis_chars_first_line;
static int saved_physical_chars;
void
rl_save_prompt ()
{
saved_local_prompt = local_prompt;
saved_local_prefix = local_prompt_prefix;
saved_prefix_length = prompt_prefix_length;
saved_local_length = local_prompt_len;
saved_last_invisible = prompt_last_invisible;
saved_visible_length = prompt_visible_length;
saved_invis_chars_first_line = prompt_invis_chars_first_line;
saved_physical_chars = prompt_physical_chars;
local_prompt = local_prompt_prefix = (char *)0;
prompt_last_invisible = prompt_visible_length = 0;
local_prompt_len = 0;
prompt_last_invisible = prompt_visible_length = prompt_prefix_length = 0;
prompt_invis_chars_first_line = prompt_physical_chars = 0;
}
......@@ -1886,10 +2030,18 @@ rl_restore_prompt ()
local_prompt = saved_local_prompt;
local_prompt_prefix = saved_local_prefix;
local_prompt_len = saved_local_length;
prompt_prefix_length = saved_prefix_length;
prompt_last_invisible = saved_last_invisible;
prompt_visible_length = saved_visible_length;
prompt_invis_chars_first_line = saved_invis_chars_first_line;
prompt_physical_chars = saved_physical_chars;
/* can test saved_local_prompt to see if prompt info has been saved. */
saved_local_prompt = saved_local_prefix = (char *)0;
saved_local_length = 0;
saved_last_invisible = saved_visible_length = saved_prefix_length = 0;
saved_invis_chars_first_line = saved_physical_chars = 0;
}
char *
......@@ -1897,11 +2049,15 @@ _rl_make_prompt_for_search (pchar)
int pchar;
{
int len;
char *pmt;
char *pmt, *p;
rl_save_prompt ();
if (saved_local_prompt == 0)
/* We've saved the prompt, and can do anything with the various prompt
strings we need before they're restored. We want the unexpanded
portion of the prompt string after any final newline. */
p = rl_prompt ? strrchr (rl_prompt, '\n') : 0;
if (p == 0)
{
len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
pmt = (char *)xmalloc (len + 2);
......@@ -1912,17 +2068,17 @@ _rl_make_prompt_for_search (pchar)
}
else
{
len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
p++;
len = strlen (p);
pmt = (char *)xmalloc (len + 2);
if (len)
strcpy (pmt, saved_local_prompt);
strcpy (pmt, p);
pmt[len] = pchar;
pmt[len+1] = '\0';
local_prompt = savestring (pmt);
prompt_last_invisible = saved_last_invisible;
prompt_visible_length = saved_visible_length + 1;
}
/* will be overwritten by expand_prompt, called from rl_message */
prompt_physical_chars = saved_physical_chars + 1;
return pmt;
}
......@@ -1983,6 +2139,9 @@ insert_some_chars (string, count, col)
char *string;
int count, col;
{
#if defined (__MSDOS__) || defined (__MINGW32__)
_rl_output_some_chars (string, count);
#else
/* DEBUGGING */
if (MB_CUR_MAX == 1 || rl_byte_oriented)
if (count != col)
......@@ -2021,6 +2180,7 @@ insert_some_chars (string, count, col)
if (_rl_term_ei && *_rl_term_ei)
tputs (_rl_term_ei, 1, _rl_output_character_function);
}
#endif /* __MSDOS__ || __MINGW32__ */
}
/* Delete COUNT characters from the display line. */
......@@ -2031,6 +2191,7 @@ delete_chars (count)
if (count > _rl_screenwidth) /* XXX */
return;
#if !defined (__MSDOS__) && !defined (__MINGW32__)
if (_rl_term_DC && *_rl_term_DC)
{
char *buffer;
......@@ -2043,6 +2204,7 @@ delete_chars (count)
while (count--)
tputs (_rl_term_dc, 1, _rl_output_character_function);
}
#endif /* !__MSDOS__ && !__MINGW32__ */
}
void
......@@ -2066,7 +2228,8 @@ _rl_update_final ()
char *last_line;
last_line = &visible_line[vis_lbreaks[_rl_vis_botlin]];
_rl_move_cursor_relative (_rl_screenwidth - 1, last_line);
cpos_buffer_position = -1; /* don't know where we are in buffer */
_rl_move_cursor_relative (_rl_screenwidth - 1, last_line); /* XXX */
_rl_clear_to_eol (0);
putc (last_line[_rl_screenwidth - 1], rl_outstream);
}
......@@ -2098,18 +2261,10 @@ static void
redraw_prompt (t)
char *t;
{
char *oldp, *oldl, *oldlprefix;
int oldlen, oldlast, oldplen, oldninvis, oldphyschars;
char *oldp;
/* Geez, I should make this a struct. */
oldp = rl_display_prompt;
oldl = local_prompt;
oldlprefix = local_prompt_prefix;
oldlen = prompt_visible_length;
oldplen = prompt_prefix_length;
oldlast = prompt_last_invisible;
oldninvis = prompt_invis_chars_first_line;
oldphyschars = prompt_physical_chars;
rl_save_prompt ();
rl_display_prompt = t;
local_prompt = expand_prompt (t, &prompt_visible_length,
......@@ -2117,16 +2272,12 @@ redraw_prompt (t)
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)NULL;
local_prompt_len = local_prompt ? strlen (local_prompt) : 0;
rl_forced_update_display ();
rl_display_prompt = oldp;
local_prompt = oldl;
local_prompt_prefix = oldlprefix;
prompt_visible_length = oldlen;
prompt_prefix_length = oldplen;
prompt_last_invisible = oldlast;
prompt_invis_chars_first_line = oldninvis;
prompt_physical_chars = oldphyschars;
rl_restore_prompt();
}
/* Redisplay the current line after a SIGWINCH is received. */
......@@ -2230,10 +2381,11 @@ _rl_col_width (str, start, end)
if (end <= start)
return 0;
memset (&ps, 0, sizeof (mbstate_t));
point = 0;
max = end;
memset (&ps, 0, sizeof(ps));
while (point < start)
{
tmp = mbrlen (str + point, max, &ps);
......
......@@ -21,7 +21,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if !defined (BUFSIZ)
#include <stdio.h>
......@@ -174,6 +176,7 @@ static FUNMAP default_funmap[] = {
{ "vi-put", rl_vi_put },
{ "vi-redo", rl_vi_redo },
{ "vi-replace", rl_vi_replace },
{ "vi-rubout", rl_vi_rubout },
{ "vi-search", rl_vi_search },
{ "vi-search-again", rl_vi_search_again },
{ "vi-set-mark", rl_vi_set_mark },
......
......@@ -22,7 +22,9 @@
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
......@@ -54,8 +56,6 @@
typedef int _hist_search_func_t PARAMS((const char *, int));
extern int rl_byte_oriented; /* declared in mbutil.c */
static char error_pointer;
static char *subst_lhs;
......@@ -87,14 +87,14 @@ char history_comment_char = '\0';
/* The list of characters which inhibit the expansion of text if found
immediately following history_expansion_char. */
char *history_no_expand_chars = (char*) " \t\n\r=";
char *history_no_expand_chars = " \t\n\r=";
/* If set to a non-zero value, single quotes inhibit history expansion.
The default is 0. */
int history_quotes_inhibit_expansion = 0;
/* Used to split words by history_tokenize_internal. */
char *history_word_delimiters = (char*) HISTORY_WORD_DELIMITERS;
char *history_word_delimiters = HISTORY_WORD_DELIMITERS;
/* If set, this points to a function that is called to verify that a
particular history expansion should be performed. */
......@@ -203,7 +203,8 @@ get_history_event (string, caller_index, delimiting_quote)
}
/* Only a closing `?' or a newline delimit a substring search string. */
for (local_index = i; (c = string[i]); i++)
for (local_index = i; c = string[i]; i++)
{
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
......@@ -220,7 +221,7 @@ get_history_event (string, caller_index, delimiting_quote)
continue;
}
}
else
#endif /* HANDLE_MULTIBYTE */
if ((!substring_okay && (whitespace (c) || c == ':' ||
(history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
......@@ -228,6 +229,7 @@ get_history_event (string, caller_index, delimiting_quote)
string[i] == '\n' ||
(substring_okay && string[i] == '?'))
break;
}
which = i - local_index;
temp = (char *)xmalloc (1 + which);
......@@ -560,12 +562,12 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int chr, l;
int ch, l;
l = _rl_find_prev_mbchar (string, i, MB_FIND_ANY);
chr = string[l];
ch = string[l];
/* XXX - original patch had i - 1 ??? If i == 0 it would fail. */
if (i && (chr == '\'' || chr == '"'))
quoted_search_delimiter = chr;
if (i && (ch == '\'' || ch == '"'))
quoted_search_delimiter = ch;
}
else
#endif /* HANDLE_MULTIBYTE */
......@@ -1426,6 +1428,8 @@ history_tokenize_word (string, ind)
{
if (peek == '<' && string[i + 2] == '-')
i++;
else if (peek == '<' && string[i + 2] == '<')
i++;
i += 2;
return i;
}
......
......@@ -30,7 +30,9 @@
# include <floss.h>
#endif
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
......@@ -184,8 +186,7 @@ read_history_range (filename, from, to)
file_size = (size_t)finfo.st_size;
/* check for overflow on very large files */
if ((long long) file_size != (long long) finfo.st_size ||
file_size + 1 < file_size)
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
errno = overflow_errno;
goto error_and_exit;
......@@ -255,6 +256,10 @@ read_history_range (filename, from, to)
for (line_end = line_start; line_end < bufend; line_end++)
if (*line_end == '\n')
{
/* Change to allow Windows-like \r\n end of line delimiter. */
if (line_end > line_start && line_end[-1] == '\r')
line_end[-1] = '\0';
else
*line_end = '\0';
if (*line_start)
......@@ -334,8 +339,7 @@ history_truncate_file (fname, lines)
file_size = (size_t)finfo.st_size;
/* check for overflow on very large files */
if ((long long) file_size != (long long) finfo.st_size ||
file_size + 1 < file_size)
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
close (file);
#if defined (EFBIG)
......
/* history.c -- standalone history library */
/* Copyright (C) 1989-2003 Free Software Foundation, Inc.
/* Copyright (C) 1989-2005 Free Software Foundation, Inc.
This file contains the GNU History Library (the Library), a set of
routines for managing the text of previously typed lines.
......@@ -25,7 +25,9 @@
you can call. I think I have done that. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
......@@ -202,11 +204,27 @@ history_get (offset)
int local_index;
local_index = offset - history_base;
return (local_index >= history_length || local_index < 0 || !the_history)
return (local_index >= history_length || local_index < 0 || the_history == 0)
? (HIST_ENTRY *)NULL
: the_history[local_index];
}
HIST_ENTRY *
alloc_history_entry (string, ts)
char *string;
char *ts;
{
HIST_ENTRY *temp;
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
temp->line = string ? savestring (string) : string;
temp->data = (char *)NULL;
temp->timestamp = ts;
return temp;
}
time_t
history_get_time (hist)
HIST_ENTRY *hist;
......@@ -288,11 +306,7 @@ add_history (string)
}
}
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
temp->line = savestring (string);
temp->data = (char *)NULL;
temp->timestamp = hist_inittime ();
temp = alloc_history_entry (string, hist_inittime ());
the_history[history_length] = (HIST_ENTRY *)NULL;
the_history[history_length - 1] = temp;
......@@ -327,6 +341,26 @@ free_history_entry (hist)
return (x);
}
HIST_ENTRY *
copy_history_entry (hist)
HIST_ENTRY *hist;
{
HIST_ENTRY *ret;
char *ts;
if (hist == 0)
return hist;
ret = alloc_history_entry (hist->line, (char *)NULL);
ts = hist->timestamp ? savestring (hist->timestamp) : hist->timestamp;
ret->timestamp = ts;
ret->data = hist->data;
return ret;
}
/* Make the history entry at WHICH have LINE and DATA. This returns
the old entry so you can dispose of the data. In the case of an
invalid WHICH, a NULL pointer is returned. */
......@@ -338,7 +372,7 @@ replace_history_entry (which, line, data)
{
HIST_ENTRY *temp, *old_value;
if (which >= history_length)
if (which < 0 || which >= history_length)
return ((HIST_ENTRY *)NULL);
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
......@@ -352,6 +386,51 @@ replace_history_entry (which, line, data)
return (old_value);
}
/* Replace the DATA in the specified history entries, replacing OLD with
NEW. WHICH says which one(s) to replace: WHICH == -1 means to replace
all of the history entries where entry->data == OLD; WHICH == -2 means
to replace the `newest' history entry where entry->data == OLD; and
WHICH >= 0 means to replace that particular history entry's data, as
long as it matches OLD. */
void
replace_history_data (which,old, new)
int which;
histdata_t *old, *new;
{
HIST_ENTRY *entry;
register int i, last;
if (which < -2 || which >= history_length || history_length == 0 || the_history == 0)
return;
if (which >= 0)
{
entry = the_history[which];
if (entry && entry->data == old)
entry->data = new;
return;
}
last = -1;
for (i = 0; i < history_length; i++)
{
entry = the_history[i];
if (entry == 0)
continue;
if (entry->data == old)
{
last = i;
if (which == -1)
entry->data = new;
}
}
if (which == -2 && last >= 0)
{
entry = the_history[last];
entry->data = new; /* XXX - we don't check entry->old */
}
}
/* Remove history element WHICH from the history. The removed
element is returned to you so you can free the line, data,
and containing structure. */
......@@ -362,17 +441,15 @@ remove_history (which)
HIST_ENTRY *return_value;
register int i;
if (which >= history_length || !history_length)
return_value = (HIST_ENTRY *)NULL;
else
{
if (which < 0 || which >= history_length || history_length == 0 || the_history == 0)
return ((HIST_ENTRY *)NULL);
return_value = the_history[which];
for (i = which; i < history_length; i++)
the_history[i] = the_history[i + 1];
history_length--;
}
return (return_value);
}
......
......@@ -22,7 +22,9 @@
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#if defined (HAVE_STDLIB_H)
......
/* input.c -- character input functions for readline. */
/* Copyright (C) 1994 Free Software Foundation, Inc.
/* Copyright (C) 1994-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -25,7 +25,9 @@
# include <floss.h>
#endif
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
......@@ -177,6 +179,7 @@ rl_gather_tyi ()
struct timeval timeout;
#endif
chars_avail = 0;
tty = fileno (rl_instream);
#if defined (HAVE_SELECT)
......@@ -218,6 +221,13 @@ rl_gather_tyi ()
}
#endif /* O_NDELAY */
#if defined (__MINGW32__)
/* Use getch/_kbhit to check for available console input, in the same way
that we read it normally. */
chars_avail = isatty (tty) ? _kbhit () : 0;
result = 0;
#endif
/* If there's nothing available, don't waste time trying to read
something. */
if (chars_avail <= 0)
......@@ -261,7 +271,7 @@ rl_set_keyboard_input_timeout (u)
int o;
o = _keyboard_input_timeout;
if (u > 0)
if (u >= 0)
_keyboard_input_timeout = u;
return (o);
}
......@@ -301,6 +311,11 @@ _rl_input_available ()
return (chars_avail);
#endif
#endif
#if defined (__MINGW32__)
if (isatty (tty))
return (_kbhit ());
#endif
return 0;
......@@ -405,7 +420,7 @@ rl_read_key ()
else
{
/* If input is coming from a macro, then use that. */
if ((c= _rl_next_macro_key ()))
if (c = _rl_next_macro_key ())
return (c);
/* If the user has an event function, then call it periodically. */
......@@ -442,6 +457,10 @@ rl_getc (stream)
while (1)
{
#if defined (__MINGW32__)
if (isatty (fileno (stream)))
return (getch ());
#endif
result = read (fileno (stream), &c, sizeof (unsigned char));
if (result == sizeof (unsigned char))
......@@ -483,7 +502,7 @@ rl_getc (stream)
this is simply an interrupted system call to read ().
Otherwise, some error ocurred, also signifying EOF. */
if (errno != EINTR)
return (EOF);
return (RL_ISSTATE (RL_STATE_READCMD) ? READERR : EOF);
}
}
......@@ -517,6 +536,12 @@ _rl_read_mbchar (mbchar, size)
ps = ps_back;
continue;
}
else if (mbchar_bytes_length == 0)
{
mbchar[0] = '\0'; /* null wide character */
mb_len = 1;
break;
}
else if (mbchar_bytes_length > (size_t)(0))
break;
}
......@@ -525,21 +550,21 @@ _rl_read_mbchar (mbchar, size)
}
/* Read a multibyte-character string whose first character is FIRST into
the buffer MB of length MBLEN. Returns the last character read, which
the buffer MB of length MLEN. Returns the last character read, which
may be FIRST. Used by the search functions, among others. Very similar
to _rl_read_mbchar. */
int
_rl_read_mbstring (first, mb, mb_len)
_rl_read_mbstring (first, mb, mlen)
int first;
char *mb;
int mb_len;
int mlen;
{
int i, c;
mbstate_t ps;
c = first;
memset (mb, 0, mb_len);
for (i = 0; i < mb_len; i++)
memset (mb, 0, mlen);
for (i = 0; i < mlen; i++)
{
mb[i] = (char)c;
memset (&ps, 0, sizeof (mbstate_t));
......
......@@ -4,7 +4,7 @@
/* */
/* **************************************************************** */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file contains the Readline Library (the Library), a set of
routines for providing Emacs style line input to programs that ask
......@@ -26,7 +26,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
......@@ -54,21 +56,77 @@
/* Variables exported to other files in the readline library. */
char *_rl_isearch_terminators = (char *)NULL;
_rl_search_cxt *_rl_iscxt = 0;
/* Variables imported from other files in the readline library. */
extern HIST_ENTRY *_rl_saved_line_for_history;
/* Forward declarations */
static int rl_search_history PARAMS((int, int));
static _rl_search_cxt *_rl_isearch_init PARAMS((int));
static void _rl_isearch_fini PARAMS((_rl_search_cxt *));
static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
/* Last line found by the current incremental search, so we don't `find'
identical lines many times in a row. */
static char *prev_line_found;
identical lines many times in a row. Now part of isearch context. */
/* static char *prev_line_found; */
/* Last search string and its length. */
static char *last_isearch_string;
static int last_isearch_string_len;
static char *default_isearch_terminators = (char*) "\033\012";
static char *default_isearch_terminators = "\033\012";
_rl_search_cxt *
_rl_scxt_alloc (type, flags)
int type, flags;
{
_rl_search_cxt *cxt;
cxt = (_rl_search_cxt *)xmalloc (sizeof (_rl_search_cxt));
cxt->type = type;
cxt->sflags = flags;
cxt->search_string = 0;
cxt->search_string_size = cxt->search_string_index = 0;
cxt->lines = 0;
cxt->allocated_line = 0;
cxt->hlen = cxt->hindex = 0;
cxt->save_point = rl_point;
cxt->save_mark = rl_mark;
cxt->save_line = where_history ();
cxt->last_found_line = cxt->save_line;
cxt->prev_line_found = 0;
cxt->save_undo_list = 0;
cxt->history_pos = 0;
cxt->direction = 0;
cxt->lastc = 0;
cxt->sline = 0;
cxt->sline_len = cxt->sline_index = 0;
cxt->search_terminators = 0;
return cxt;
}
void
_rl_scxt_dispose (cxt, flags)
_rl_search_cxt *cxt;
int flags;
{
FREE (cxt->search_string);
FREE (cxt->allocated_line);
FREE (cxt->lines);
free (cxt);
}
/* Search backwards through the history looking for a string which is typed
interactively. Start with the current line. */
......@@ -90,12 +148,13 @@ rl_forward_search_history (sign, key)
/* Display the current state of the search in the echo-area.
SEARCH_STRING contains the string that is being searched for,
DIRECTION is zero for forward, or 1 for reverse,
DIRECTION is zero for forward, or non-zero for reverse,
WHERE is the history list number of the current line. If it is
-1, then this line is the starting one. */
static void
rl_display_search (char *search_string, int reverse_p,
int where __attribute__((unused)))
rl_display_search (search_string, reverse_p, where)
char *search_string;
int reverse_p, where;
{
char *message;
int msglen, searchlen;
......@@ -137,65 +196,23 @@ rl_display_search (char *search_string, int reverse_p,
(*rl_redisplay_function) ();
}
/* Search through the history looking for an interactively typed string.
This is analogous to i-search. We start the search in the current line.
DIRECTION is which direction to search; >= 0 means forward, < 0 means
backwards. */
static int
rl_search_history (int direction, int invoking_key __attribute__((unused)))
static _rl_search_cxt *
_rl_isearch_init (direction)
int direction;
{
/* The string that the user types in to search for. */
char *search_string;
/* The current length of SEARCH_STRING. */
int search_string_index;
/* The amount of space that SEARCH_STRING has allocated to it. */
int search_string_size;
/* The list of lines to search through. */
char **lines, *allocated_line;
/* The length of LINES. */
int hlen;
/* Where we get LINES from. */
HIST_ENTRY **hlist;
_rl_search_cxt *cxt;
register int i;
int orig_point, orig_mark, orig_line, last_found_line;
int c, found, failed, sline_len;
int n, wstart, wlen;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
#endif
/* The line currently being searched. */
char *sline;
/* Offset in that line. */
int line_index;
/* Non-zero if we are doing a reverse search. */
int reverse;
HIST_ENTRY **hlist;
/* The list of characters which terminate the search, but are not
subsequently executed. If the variable isearch-terminators has
been set, we use that value, otherwise we use ESC and C-J. */
char *isearch_terminators;
cxt = _rl_scxt_alloc (RL_SEARCH_ISEARCH, 0);
if (direction < 0)
cxt->sflags |= SF_REVERSE;
RL_SETSTATE(RL_STATE_ISEARCH);
orig_point = rl_point;
orig_mark = rl_mark;
last_found_line = orig_line = where_history ();
reverse = direction < 0;
hlist = history_list ();
allocated_line = (char *)NULL;
isearch_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
cxt->search_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
: default_isearch_terminators;
/* Create an arrary of pointers to the lines that we want to search. */
hlist = history_list ();
rl_maybe_replace_line ();
i = 0;
if (hlist)
......@@ -203,81 +220,138 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
/* Allocate space for this many lines, +1 for the current input line,
and remember those lines. */
lines = (char **)xmalloc ((1 + (hlen = i)) * sizeof (char *));
for (i = 0; i < hlen; i++)
lines[i] = hlist[i]->line;
cxt->lines = (char **)xmalloc ((1 + (cxt->hlen = i)) * sizeof (char *));
for (i = 0; i < cxt->hlen; i++)
cxt->lines[i] = hlist[i]->line;
if (_rl_saved_line_for_history)
lines[i] = _rl_saved_line_for_history->line;
cxt->lines[i] = _rl_saved_line_for_history->line;
else
{
/* Keep track of this so we can free it. */
allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
strcpy (allocated_line, &rl_line_buffer[0]);
lines[i] = allocated_line;
cxt->allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
strcpy (cxt->allocated_line, &rl_line_buffer[0]);
cxt->lines[i] = cxt->allocated_line;
}
hlen++;
cxt->hlen++;
/* The line where we start the search. */
i = orig_line;
cxt->history_pos = cxt->save_line;
rl_save_prompt ();
/* Initialize search parameters. */
search_string = (char *)xmalloc (search_string_size = 128);
*search_string = '\0';
search_string_index = 0;
prev_line_found = (char *)0; /* XXX */
cxt->search_string = (char *)xmalloc (cxt->search_string_size = 128);
cxt->search_string[cxt->search_string_index = 0] = '\0';
/* Normalize DIRECTION into 1 or -1. */
direction = (direction >= 0) ? 1 : -1;
cxt->direction = (direction >= 0) ? 1 : -1;
rl_display_search (search_string, reverse, -1);
cxt->sline = rl_line_buffer;
cxt->sline_len = strlen (cxt->sline);
cxt->sline_index = rl_point;
sline = rl_line_buffer;
sline_len = strlen (sline);
line_index = rl_point;
_rl_iscxt = cxt; /* save globally */
found = failed = 0;
for (;;)
return cxt;
}
static void
_rl_isearch_fini (cxt)
_rl_search_cxt *cxt;
{
/* First put back the original state. */
strcpy (rl_line_buffer, cxt->lines[cxt->save_line]);
rl_restore_prompt ();
/* Save the search string for possible later use. */
FREE (last_isearch_string);
last_isearch_string = cxt->search_string;
last_isearch_string_len = cxt->search_string_index;
cxt->search_string = 0;
if (cxt->last_found_line < cxt->save_line)
rl_get_previous_history (cxt->save_line - cxt->last_found_line, 0);
else
rl_get_next_history (cxt->last_found_line - cxt->save_line, 0);
/* If the string was not found, put point at the end of the last matching
line. If last_found_line == orig_line, we didn't find any matching
history lines at all, so put point back in its original position. */
if (cxt->sline_index < 0)
{
rl_command_func_t *f = (rl_command_func_t *)NULL;
if (cxt->last_found_line == cxt->save_line)
cxt->sline_index = cxt->save_point;
else
cxt->sline_index = strlen (rl_line_buffer);
rl_mark = cxt->save_mark;
}
rl_point = cxt->sline_index;
/* Don't worry about where to put the mark here; rl_get_previous_history
and rl_get_next_history take care of it. */
rl_clear_message ();
}
int
_rl_search_getchar (cxt)
_rl_search_cxt *cxt;
{
int c;
/* Read a key and decide how to proceed. */
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
c = cxt->lastc = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX);
#endif
return c;
}
/* Process just-read character C according to isearch context CXT. Return
-1 if the caller should just free the context and return, 0 if we should
break out of the loop, and 1 if we should continue to read characters. */
int
_rl_isearch_dispatch (cxt, c)
_rl_search_cxt *cxt;
int c;
{
int n, wstart, wlen, limit, cval;
rl_command_func_t *f;
f = (rl_command_func_t *)NULL;
/* Translate the keys we do something with to opcodes. */
if (c >= 0 && _rl_keymap[c].type == ISFUNC)
{
f = _rl_keymap[c].function;
if (f == rl_reverse_search_history)
c = reverse ? -1 : -2;
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
else if (f == rl_forward_search_history)
c = !reverse ? -1 : -2;
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -2 : -1;
else if (f == rl_rubout)
c = -3;
cxt->lastc = -3;
else if (c == CTRL ('G'))
c = -4;
cxt->lastc = -4;
else if (c == CTRL ('W')) /* XXX */
c = -5;
cxt->lastc = -5;
else if (c == CTRL ('Y')) /* XXX */
c = -6;
cxt->lastc = -6;
}
/* The characters in isearch_terminators (set from the user-settable
variable isearch-terminators) are used to terminate the search but
not subsequently execute the character as a command. The default
value is "\033\012" (ESC and C-J). */
if (strchr (isearch_terminators, c))
if (strchr (cxt->search_terminators, cxt->lastc))
{
/* ESC still terminates the search, but if there is pending
input or if input arrives within 0.1 seconds (on systems
......@@ -288,9 +362,9 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
XXX - since _rl_input_available depends on the application-
settable keyboard timeout value, this could alternatively
use _rl_input_queued(100000) */
if (c == ESC && _rl_input_available ())
if (cxt->lastc == ESC && _rl_input_available ())
rl_execute_next (ESC);
break;
return (0);
}
#define ENDSRCH_CHAR(c) \
......@@ -299,52 +373,58 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
if (c >= 0 && strlen (mb) == 1 && ENDSRCH_CHAR (c))
if (cxt->lastc >= 0 && (cxt->mb[0] && cxt->mb[1] == '\0') && ENDSRCH_CHAR (cxt->lastc))
{
/* This sets rl_pending_input to c; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (c);
break;
rl_execute_next (cxt->lastc);
return (0);
}
}
else
#endif
if (c >= 0 && ENDSRCH_CHAR (c))
if (cxt->lastc >= 0 && ENDSRCH_CHAR (cxt->lastc))
{
/* This sets rl_pending_input to c; it will be picked up the next
/* This sets rl_pending_input to LASTC; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (c);
break;
rl_execute_next (cxt->lastc);
return (0);
}
switch (c)
/* Now dispatch on the character. `Opcodes' affect the search string or
state. Other characters are added to the string. */
switch (cxt->lastc)
{
/* search again */
case -1:
if (search_string_index == 0)
if (cxt->search_string_index == 0)
{
if (last_isearch_string)
{
search_string_size = 64 + last_isearch_string_len;
search_string = (char *)xrealloc (search_string, search_string_size);
strcpy (search_string, last_isearch_string);
search_string_index = last_isearch_string_len;
rl_display_search (search_string, reverse, -1);
cxt->search_string_size = 64 + last_isearch_string_len;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
strcpy (cxt->search_string, last_isearch_string);
cxt->search_string_index = last_isearch_string_len;
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
break;
}
continue;
return (1);
}
else if (reverse)
--line_index;
else if (line_index != sline_len)
++line_index;
else if (cxt->sflags & SF_REVERSE)
cxt->sline_index--;
else if (cxt->sline_index != cxt->sline_len)
cxt->sline_index++;
else
rl_ding ();
break;
/* switch directions */
case -2:
direction = -direction;
reverse = direction < 0;
cxt->direction = -cxt->direction;
if (cxt->direction < 0)
cxt->sflags |= SF_REVERSE;
else
cxt->sflags &= ~SF_REVERSE;
break;
/* delete character from search string. */
......@@ -353,28 +433,24 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
stack of search positions for the current search, with
sentinels marking the beginning and end. But this will
do until we have a real isearch-undo. */
if (search_string_index == 0)
if (cxt->search_string_index == 0)
rl_ding ();
else
search_string[--search_string_index] = '\0';
cxt->search_string[--cxt->search_string_index] = '\0';
break;
case -4: /* C-G */
rl_replace_line (lines[orig_line], 0);
rl_point = orig_point;
rl_mark = orig_mark;
case -4: /* C-G, abort */
rl_replace_line (cxt->lines[cxt->save_line], 0);
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
rl_restore_prompt();
rl_clear_message ();
if (allocated_line)
free (allocated_line);
free (lines);
RL_UNSETSTATE(RL_STATE_ISEARCH);
return 0;
return -1;
case -5: /* C-W */
/* skip over portion of line we already matched */
wstart = rl_point + search_string_index;
/* skip over portion of line we already matched and yank word */
wstart = rl_point + cxt->search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
......@@ -382,81 +458,87 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
}
/* if not in a word, move to one. */
if (rl_alphabetic(rl_line_buffer[wstart]) == 0)
cval = _rl_char_value (rl_line_buffer, wstart);
if (_rl_walphabetic (cval) == 0)
{
rl_ding ();
break;
}
n = wstart;
while (n < rl_end && rl_alphabetic(rl_line_buffer[n]))
n++;
n = MB_NEXTCHAR (rl_line_buffer, wstart, 1, MB_FIND_NONZERO);;
while (n < rl_end)
{
cval = _rl_char_value (rl_line_buffer, n);
if (_rl_walphabetic (cval) == 0)
break;
n = MB_NEXTCHAR (rl_line_buffer, n, 1, MB_FIND_NONZERO);;
}
wlen = n - wstart + 1;
if (search_string_index + wlen + 1 >= search_string_size)
if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size)
{
search_string_size += wlen + 1;
search_string = (char *)xrealloc (search_string, search_string_size);
cxt->search_string_size += wlen + 1;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
for (; wstart < n; wstart++)
search_string[search_string_index++] = rl_line_buffer[wstart];
search_string[search_string_index] = '\0';
cxt->search_string[cxt->search_string_index++] = rl_line_buffer[wstart];
cxt->search_string[cxt->search_string_index] = '\0';
break;
case -6: /* C-Y */
/* skip over portion of line we already matched */
wstart = rl_point + search_string_index;
/* skip over portion of line we already matched and yank rest */
wstart = rl_point + cxt->search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
n = rl_end - wstart + 1;
if (search_string_index + n + 1 >= search_string_size)
if (cxt->search_string_index + n + 1 >= cxt->search_string_size)
{
search_string_size += n + 1;
search_string = (char *)xrealloc (search_string, search_string_size);
cxt->search_string_size += n + 1;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
for (n = wstart; n < rl_end; n++)
search_string[search_string_index++] = rl_line_buffer[n];
search_string[search_string_index] = '\0';
cxt->search_string[cxt->search_string_index++] = rl_line_buffer[n];
cxt->search_string[cxt->search_string_index] = '\0';
break;
default:
/* Add character to search string and continue search. */
if (search_string_index + 2 >= search_string_size)
default:
if (cxt->search_string_index + 2 >= cxt->search_string_size)
{
search_string_size += 128;
search_string = (char *)xrealloc (search_string, search_string_size);
cxt->search_string_size += 128;
cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int j, l;
for (j = 0, l = strlen (mb); j < l; )
search_string[search_string_index++] = mb[j++];
for (j = 0, l = strlen (cxt->mb); j < l; )
cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
}
else
#endif
search_string[search_string_index++] = c;
search_string[search_string_index] = '\0';
cxt->search_string[cxt->search_string_index++] = c;
cxt->search_string[cxt->search_string_index] = '\0';
break;
}
for (found = failed = 0;;)
for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; )
{
int limit = sline_len - search_string_index + 1;
limit = cxt->sline_len - cxt->search_string_index + 1;
/* Search the current line. */
while (reverse ? (line_index >= 0) : (line_index < limit))
while ((cxt->sflags & SF_REVERSE) ? (cxt->sline_index >= 0) : (cxt->sline_index < limit))
{
if (STREQN (search_string, sline + line_index, search_string_index))
if (STREQN (cxt->search_string, cxt->sline + cxt->sline_index, cxt->search_string_index))
{
found++;
cxt->sflags |= SF_FOUND;
break;
}
else
line_index += direction;
cxt->sline_index += cxt->direction;
}
if (found)
if (cxt->sflags & SF_FOUND)
break;
/* Move to the next line, but skip new copies of the line
......@@ -465,92 +547,120 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
do
{
/* Move to the next line. */
i += direction;
cxt->history_pos += cxt->direction;
/* At limit for direction? */
if (reverse ? (i < 0) : (i == hlen))
if ((cxt->sflags & SF_REVERSE) ? (cxt->history_pos < 0) : (cxt->history_pos == cxt->hlen))
{
failed++;
cxt->sflags |= SF_FAILED;
break;
}
/* We will need these later. */
sline = lines[i];
sline_len = strlen (sline);
cxt->sline = cxt->lines[cxt->history_pos];
cxt->sline_len = strlen (cxt->sline);
}
while ((prev_line_found && STREQ (prev_line_found, lines[i])) ||
(search_string_index > sline_len));
while ((cxt->prev_line_found && STREQ (cxt->prev_line_found, cxt->lines[cxt->history_pos])) ||
(cxt->search_string_index > cxt->sline_len));
if (failed)
if (cxt->sflags & SF_FAILED)
break;
/* Now set up the line for searching... */
line_index = reverse ? sline_len - search_string_index : 0;
cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0;
}
if (failed)
if (cxt->sflags & SF_FAILED)
{
/* We cannot find the search string. Ding the bell. */
rl_ding ();
i = last_found_line;
continue; /* XXX - was break */
cxt->history_pos = cxt->last_found_line;
return 1;
}
/* We have found the search string. Just display it. But don't
actually move there in the history list until the user accepts
the location. */
if (found)
if (cxt->sflags & SF_FOUND)
{
prev_line_found = lines[i];
rl_replace_line (lines[i], 0);
rl_point = line_index;
last_found_line = i;
rl_display_search (search_string, reverse, (i == orig_line) ? -1 : i);
}
cxt->prev_line_found = cxt->lines[cxt->history_pos];
rl_replace_line (cxt->lines[cxt->history_pos], 0);
rl_point = cxt->sline_index;
cxt->last_found_line = cxt->history_pos;
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
}
/* The searching is over. The user may have found the string that she
was looking for, or else she may have exited a failing search. If
LINE_INDEX is -1, then that shows that the string searched for was
not found. We use this to determine where to place rl_point. */
return 1;
}
/* First put back the original state. */
strcpy (rl_line_buffer, lines[orig_line]);
static int
_rl_isearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;
{
if (r >= 0)
_rl_isearch_fini (cxt);
_rl_scxt_dispose (cxt, 0);
_rl_iscxt = 0;
rl_restore_prompt ();
RL_UNSETSTATE(RL_STATE_ISEARCH);
/* Save the search string for possible later use. */
FREE (last_isearch_string);
last_isearch_string = search_string;
last_isearch_string_len = search_string_index;
return (r != 0);
}
if (last_found_line < orig_line)
rl_get_previous_history (orig_line - last_found_line, 0);
else
rl_get_next_history (last_found_line - orig_line, 0);
/* Search through the history looking for an interactively typed string.
This is analogous to i-search. We start the search in the current line.
DIRECTION is which direction to search; >= 0 means forward, < 0 means
backwards. */
static int
rl_search_history (direction, invoking_key)
int direction, invoking_key;
{
_rl_search_cxt *cxt; /* local for now, but saved globally */
int c, r;
/* If the string was not found, put point at the end of the last matching
line. If last_found_line == orig_line, we didn't find any matching
history lines at all, so put point back in its original position. */
if (line_index < 0)
RL_SETSTATE(RL_STATE_ISEARCH);
cxt = _rl_isearch_init (direction);
rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
/* If we are using the callback interface, all we do is set up here and
return. The key is that we leave RL_STATE_ISEARCH set. */
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
r = -1;
for (;;)
{
if (last_found_line == orig_line)
line_index = orig_point;
else
line_index = strlen (rl_line_buffer);
rl_mark = orig_mark;
c = _rl_search_getchar (cxt);
/* We might want to handle EOF here (c == 0) */
r = _rl_isearch_dispatch (cxt, cxt->lastc);
if (r <= 0)
break;
}
rl_point = line_index;
/* Don't worry about where to put the mark here; rl_get_previous_history
and rl_get_next_history take care of it. */
rl_clear_message ();
/* The searching is over. The user may have found the string that she
was looking for, or else she may have exited a failing search. If
LINE_INDEX is -1, then that shows that the string searched for was
not found. We use this to determine where to place rl_point. */
return (_rl_isearch_cleanup (cxt, r));
}
FREE (allocated_line);
free (lines);
#if defined (READLINE_CALLBACKS)
/* Called from the callback functions when we are ready to read a key. The
callback functions know to call this because RL_ISSTATE(RL_STATE_ISEARCH).
If _rl_isearch_dispatch finishes searching, this function is responsible
for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */
int
_rl_isearch_callback (cxt)
_rl_search_cxt *cxt;
{
int c, r;
RL_UNSETSTATE(RL_STATE_ISEARCH);
c = _rl_search_getchar (cxt);
/* We might want to handle EOF here */
r = _rl_isearch_dispatch (cxt, cxt->lastc);
return 0;
return (r <= 0) ? _rl_isearch_cleanup (cxt, r) : 0;
}
#endif
......@@ -20,7 +20,9 @@
Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
......
......@@ -21,7 +21,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
......@@ -76,7 +78,8 @@ static int rl_yank_nth_arg_internal PARAMS((int, int, int));
/* How to say that you only want to save a certain amount
of kill material. */
int
rl_set_retained_kills (int num __attribute__((unused)))
rl_set_retained_kills (num)
int num;
{
return 0;
}
......@@ -292,8 +295,8 @@ rl_backward_kill_line (direction, ignore)
/* Kill the whole line, no matter where point is. */
int
rl_kill_full_line (int count __attribute__((unused)),
int ignore __attribute__((unused)))
rl_kill_full_line (count, ignore)
int count, ignore;
{
rl_begin_undo_group ();
rl_point = 0;
......@@ -310,7 +313,8 @@ rl_kill_full_line (int count __attribute__((unused)),
/* This does what C-w does in Unix. We can't prevent people from
using behaviour that they expect. */
int
rl_unix_word_rubout (int count, int key __attribute__((unused)))
rl_unix_word_rubout (count, key)
int count, key;
{
int orig_point;
......@@ -342,7 +346,8 @@ rl_unix_word_rubout (int count, int key __attribute__((unused)))
/* This deletes one filename component in a Unix pathname. That is, it
deletes backward to directory separator (`/') or whitespace. */
int
rl_unix_filename_rubout (int count, int key __attribute__((unused)))
rl_unix_filename_rubout (count, key)
int count, key;
{
int orig_point, c;
......@@ -385,8 +390,8 @@ rl_unix_filename_rubout (int count, int key __attribute__((unused)))
into the line at all, and if you aren't, then you know what you are
doing. */
int
rl_unix_line_discard (int count __attribute__((unused)),
int key __attribute__((unused)))
rl_unix_line_discard (count, key)
int count, key;
{
if (rl_point == 0)
rl_ding ();
......@@ -422,16 +427,16 @@ region_kill_internal (delete)
/* Copy the text in the region to the kill ring. */
int
rl_copy_region_to_kill (int count __attribute__((unused)),
int key __attribute__((unused)))
rl_copy_region_to_kill (count, ignore)
int count, ignore;
{
return (region_kill_internal (0));
}
/* Kill the text between the point and mark. */
int
rl_kill_region (int count __attribute__((unused)),
int ignore __attribute__((unused)))
rl_kill_region (count, ignore)
int count, ignore;
{
int r, npoint;
......@@ -495,7 +500,8 @@ rl_copy_backward_word (count, key)
/* Yank back the last killed text. This ignores arguments. */
int
rl_yank (int count __attribute__((unused)), int ignore __attribute__((unused)))
rl_yank (count, ignore)
int count, ignore;
{
if (rl_kill_ring == 0)
{
......@@ -513,7 +519,8 @@ rl_yank (int count __attribute__((unused)), int ignore __attribute__((unused)))
delete that text from the line, rotate the index down, and
yank back some other text. */
int
rl_yank_pop (int count __attribute__((unused)), int key __attribute__((unused)))
rl_yank_pop (count, key)
int count, key;
{
int l, n;
......@@ -575,6 +582,7 @@ rl_yank_nth_arg_internal (count, ignore, history_skip)
if (!arg || !*arg)
{
rl_ding ();
FREE (arg);
return -1;
}
......
......@@ -21,7 +21,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
......@@ -98,6 +100,8 @@ _rl_with_macro_input (string)
int
_rl_next_macro_key ()
{
int c;
if (rl_executing_macro == 0)
return (0);
......@@ -107,7 +111,14 @@ _rl_next_macro_key ()
return (_rl_next_macro_key ());
}
#if defined (READLINE_CALLBACKS)
c = rl_executing_macro[executing_macro_index++];
if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_READCMD|RL_STATE_MOREINPUT) && rl_executing_macro[executing_macro_index] == 0)
_rl_pop_executing_macro ();
return c;
#else
return (rl_executing_macro[executing_macro_index++]);
#endif
}
/* Save the currently executing macro on a stack of saved macros. */
......@@ -189,8 +200,8 @@ _rl_kill_kbd_macro ()
definition to the end of the existing macro, and start by
re-executing the existing macro. */
int
rl_start_kbd_macro (int ignore1 __attribute__((unused)),
int ignore2 __attribute__((unused)))
rl_start_kbd_macro (ignore1, ignore2)
int ignore1, ignore2;
{
if (RL_ISSTATE (RL_STATE_MACRODEF))
{
......@@ -214,7 +225,8 @@ rl_start_kbd_macro (int ignore1 __attribute__((unused)),
A numeric argument says to execute the macro right now,
that many times, counting the definition as the first time. */
int
rl_end_kbd_macro (int count, int ignore __attribute__((unused)))
rl_end_kbd_macro (count, ignore)
int count, ignore;
{
if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
{
......@@ -233,7 +245,8 @@ rl_end_kbd_macro (int count, int ignore __attribute__((unused)))
/* Execute the most recently defined keyboard macro.
COUNT says how many times to execute it. */
int
rl_call_last_kbd_macro (int count, int ignore __attribute__((unused)))
rl_call_last_kbd_macro (count, ignore)
int count, ignore;
{
if (current_macro == 0)
_rl_abort_internal ();
......
/* mbutil.c -- readline multibyte character utility functions */
/* Copyright (C) 2001-2004 Free Software Foundation, Inc.
/* Copyright (C) 2001-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -21,16 +21,11 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE 500
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include "config_readline.h"
#include <sys/types.h>
/* To get SuSE 9.3 to define wcwidth() (in wchar.h) */
#include <fcntl.h>
#include "posixjmp.h"
......@@ -82,18 +77,20 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
char *string;
int seed, count, find_non_zero;
{
size_t tmp = 0;
size_t tmp;
mbstate_t ps;
int point = 0;
int point;
wchar_t wc;
tmp = 0;
memset(&ps, 0, sizeof (mbstate_t));
if (seed < 0)
seed = 0;
if (count <= 0)
return seed;
point = seed + _rl_adjust_point(string, seed, &ps);
point = seed + _rl_adjust_point (string, seed, &ps);
/* if this is true, means that seed was not pointed character
started byte. So correct the point and consume count */
if (seed < point)
......@@ -131,14 +128,15 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
if (find_non_zero)
{
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
while (wcwidth (wc) == 0)
while (tmp > 0 && wcwidth (wc) == 0)
{
point += tmp;
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
if (tmp == (size_t)(0) || tmp == (size_t)(-1) || tmp == (size_t)(-2))
if (MB_NULLWCH (tmp) || MB_INVALIDCH (tmp))
break;
}
}
return point;
}
......@@ -318,6 +316,28 @@ _rl_is_mbchar_matched (string, seed, end, mbchar, length)
return 0;
return 1;
}
wchar_t
_rl_char_value (buf, ind)
char *buf;
int ind;
{
size_t tmp;
wchar_t wc;
mbstate_t ps;
int l;
if (MB_LEN_MAX == 1 || rl_byte_oriented)
return ((wchar_t) buf[ind]);
l = strlen (buf);
if (ind >= l - 1)
return ((wchar_t) buf[ind]);
memset (&ps, 0, sizeof (mbstate_t));
tmp = mbrtowc (&wc, buf + ind, l - ind, &ps);
if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))
return ((wchar_t) buf[ind]);
return wc;
}
#endif /* HANDLE_MULTIBYTE */
/* Find next `count' characters started byte point of the specified seed.
......
/* misc.c -- miscellaneous bindable readline functions. */
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -21,7 +21,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
......@@ -61,6 +63,8 @@ void _rl_free_history_entry PARAMS((HIST_ENTRY *));
to preserve the value of rl_point from line to line. */
int _rl_history_preserve_point = 0;
_rl_arg_cxt _rl_argcxt;
/* Saved target point for when _rl_history_preserve_point is set. Special
value of -1 means that point is at the end of the line. */
int _rl_history_saved_point = -1;
......@@ -71,47 +75,68 @@ int _rl_history_saved_point = -1;
/* */
/* **************************************************************** */
/* Handle C-u style numeric args, as well as M--, and M-digits. */
static int
rl_digit_loop ()
int
_rl_arg_overflow ()
{
int key, c, sawminus, sawdigits;
rl_save_prompt ();
RL_SETSTATE(RL_STATE_NUMERICARG);
sawminus = sawdigits = 0;
while (1)
{
if (rl_numeric_arg > 1000000)
{
sawdigits = rl_explicit_arg = rl_numeric_arg = 0;
_rl_argcxt = 0;
rl_explicit_arg = rl_numeric_arg = 0;
rl_ding ();
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return 1;
}
return 0;
}
void
_rl_arg_init ()
{
rl_save_prompt ();
_rl_argcxt = 0;
RL_SETSTATE(RL_STATE_NUMERICARG);
}
int
_rl_arg_getchar ()
{
int c;
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
RL_SETSTATE(RL_STATE_MOREINPUT);
key = c = rl_read_key ();
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (c < 0)
{
_rl_abort_internal ();
return -1;
}
return c;
}
/* Process C as part of the current numeric argument. Return -1 if the
argument should be aborted, 0 if we should not read any more chars, and
1 if we should continue to read chars. */
int
_rl_arg_dispatch (cxt, c)
_rl_arg_cxt cxt;
int c;
{
int key, r;
key = c;
/* If we see a key bound to `universal-argument' after seeing digits,
it ends the argument but is otherwise ignored. */
if (_rl_keymap[c].type == ISFUNC &&
_rl_keymap[c].function == rl_universal_argument)
if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
{
if (sawdigits == 0)
if ((cxt & NUM_SAWDIGITS) == 0)
{
rl_numeric_arg *= 4;
continue;
return 1;
}
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_argcxt |= NUM_READONE;
return 0; /* XXX */
}
else
{
......@@ -129,65 +154,140 @@ rl_digit_loop ()
if (_rl_digit_p (c))
{
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0';
sawdigits = rl_explicit_arg = 1;
r = _rl_digit_value (c);
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + r : r;
rl_explicit_arg = 1;
_rl_argcxt |= NUM_SAWDIGITS;
}
else if (c == '-' && rl_explicit_arg == 0)
{
rl_numeric_arg = sawminus = 1;
rl_numeric_arg = 1;
_rl_argcxt |= NUM_SAWMINUS;
rl_arg_sign = -1;
}
else
{
/* Make M-- command equivalent to M--1 command. */
if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0)
if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
rl_explicit_arg = 1;
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return (_rl_dispatch (key, _rl_keymap));
r = _rl_dispatch (key, _rl_keymap);
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
/* At worst, this will cause an extra redisplay. Otherwise,
we have to wait until the next character comes in. */
if (rl_done == 0)
(*rl_redisplay_function) ();
r = 0;
}
return r;
}
/*NOTREACHED*/
return 1;
}
/* Add the current digit to the argument in progress. */
int
rl_digit_argument (int ignore __attribute__((unused)), int key)
/* Handle C-u style numeric args, as well as M--, and M-digits. */
static int
rl_digit_loop ()
{
rl_execute_next (key);
return (rl_digit_loop ());
}
int c, r;
/* What to do when you abort reading an argument. */
int
rl_discard_argument ()
{
rl_ding ();
rl_clear_message ();
_rl_init_argument ();
return 0;
while (1)
{
if (_rl_arg_overflow ())
return 1;
c = _rl_arg_getchar ();
if (c < 0)
{
_rl_abort_internal ();
return -1;
}
r = _rl_arg_dispatch (_rl_argcxt, c);
if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
break;
}
return r;
}
/* Create a default argument. */
int
_rl_init_argument ()
void
_rl_reset_argument ()
{
rl_numeric_arg = rl_arg_sign = 1;
rl_explicit_arg = 0;
_rl_argcxt = 0;
}
/* Start a numeric argument with initial value KEY */
int
rl_digit_argument (ignore, key)
int ignore, key;
{
_rl_arg_init ();
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_arg_dispatch (_rl_argcxt, key);
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
return 0;
}
else
{
rl_execute_next (key);
return (rl_digit_loop ());
}
}
/* C-u, universal argument. Multiply the current argument by 4.
Read a key. If the key has nothing to do with arguments, then
dispatch on it. If the key is the abort character then abort. */
int
rl_universal_argument (int count __attribute__((unused)),
int key __attribute__((unused)))
rl_universal_argument (count, key)
int count, key;
{
_rl_arg_init ();
rl_numeric_arg *= 4;
return (rl_digit_loop ());
return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
}
int
_rl_arg_callback (cxt)
_rl_arg_cxt cxt;
{
int c, r;
c = _rl_arg_getchar ();
if (_rl_argcxt & NUM_READONE)
{
_rl_argcxt &= ~NUM_READONE;
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
rl_execute_next (c);
return 0;
}
r = _rl_arg_dispatch (cxt, c);
return (r != 1);
}
/* What to do when you abort reading an argument. */
int
rl_discard_argument ()
{
rl_ding ();
rl_clear_message ();
_rl_reset_argument ();
return 0;
}
/* **************************************************************** */
......@@ -222,8 +322,10 @@ _rl_free_history_entry (entry)
{
if (entry == 0)
return;
if (entry->line)
free (entry->line);
FREE (entry->line);
FREE (entry->timestamp);
free (entry);
}
......@@ -239,6 +341,7 @@ rl_maybe_replace_line ()
{
temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
free (temp->line);
FREE (temp->timestamp);
free (temp);
}
return 0;
......@@ -271,14 +374,9 @@ rl_maybe_save_line ()
{
_rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
_rl_saved_line_for_history->timestamp = (char *)NULL;
_rl_saved_line_for_history->data = (char *)rl_undo_list;
}
else if (STREQ (rl_line_buffer, _rl_saved_line_for_history->line) == 0)
{
free (_rl_saved_line_for_history->line);
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
_rl_saved_line_for_history->data = (char *)rl_undo_list; /* XXX possible memleak */
}
return 0;
}
......@@ -313,7 +411,9 @@ _rl_history_set_point ()
}
void
rl_replace_from_history (HIST_ENTRY *entry, int flags __attribute__((unused)))
rl_replace_from_history (entry, flags)
HIST_ENTRY *entry;
int flags; /* currently unused */
{
/* Can't call with `1' because rl_undo_list might point to an undo list
from a history entry, just like we're setting up here. */
......@@ -339,15 +439,16 @@ rl_replace_from_history (HIST_ENTRY *entry, int flags __attribute__((unused)))
/* Meta-< goes to the start of the history. */
int
rl_beginning_of_history (int count __attribute__((unused)), int key)
rl_beginning_of_history (count, key)
int count, key;
{
return (rl_get_previous_history (1 + where_history (), key));
}
/* Meta-> goes to the end of the history. (The current line). */
int
rl_end_of_history (int count __attribute__((unused)),
int key __attribute__((unused)))
rl_end_of_history (count, key)
int count, key;
{
rl_maybe_replace_line ();
using_history ();
......@@ -451,7 +552,8 @@ rl_get_previous_history (count, key)
/* **************************************************************** */
/* How to toggle back and forth between editing modes. */
int
rl_vi_editing_mode (int count __attribute__((unused)), int key)
rl_vi_editing_mode (count, key)
int count, key;
{
#if defined (VI_MODE)
_rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
......@@ -463,8 +565,8 @@ rl_vi_editing_mode (int count __attribute__((unused)), int key)
}
int
rl_emacs_editing_mode (int count __attribute__((unused)),
int key __attribute__((unused)))
rl_emacs_editing_mode (count, key)
int count, key;
{
rl_editing_mode = emacs_mode;
_rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
......@@ -474,7 +576,8 @@ rl_emacs_editing_mode (int count __attribute__((unused)),
/* Function for the rest of the library to use to set insert/overwrite mode. */
void
_rl_set_insert_mode (int im, int force __attribute__((unused)))
_rl_set_insert_mode (im, force)
int im, force;
{
#ifdef CURSOR_MODE
_rl_set_cursor (im, force);
......@@ -486,7 +589,8 @@ _rl_set_insert_mode (int im, int force __attribute__((unused)))
/* Toggle overwrite mode. A positive explicit argument selects overwrite
mode. A negative or zero explicit argument selects insert mode. */
int
rl_overwrite_mode (int count, int key __attribute__((unused)))
rl_overwrite_mode (count, key)
int count, key;
{
if (rl_explicit_arg == 0)
_rl_set_insert_mode (rl_insert_mode ^ 1, 0);
......
......@@ -21,7 +21,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
......@@ -111,7 +113,7 @@ _rl_init_eightbit ()
if (lspec == 0 || *lspec == 0)
lspec = setlocale (LC_CTYPE, (char *)NULL);
if (lspec == 0)
lspec = (char*) "";
lspec = "";
t = setlocale (LC_CTYPE, lspec);
if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0))
......
......@@ -27,7 +27,9 @@
#include "rlconf.h"
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
......
/* readline.c -- a general facility for reading lines of input
with emacs style editing and completion. */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -22,7 +22,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include "posixstat.h"
......@@ -47,6 +49,11 @@
#include <stdio.h>
#include "posixjmp.h"
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
/* System-specific feature definitions and include files. */
#include "rldefs.h"
......@@ -66,11 +73,11 @@
#include "xmalloc.h"
#ifndef RL_LIBRARY_VERSION
# define RL_LIBRARY_VERSION "5.0"
# define RL_LIBRARY_VERSION "5.1"
#endif
#ifndef RL_READLINE_VERSION
# define RL_READLINE_VERSION 0x0500
# define RL_READLINE_VERSION 0x0501
#endif
extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
......@@ -83,9 +90,10 @@ static void bind_arrow_keys_internal PARAMS((Keymap));
static void bind_arrow_keys PARAMS((void));
static void readline_default_bindings PARAMS((void));
#ifdef NOT_USED
static void reset_default_bindings PARAMS((void));
#endif
static int _rl_subseq_result PARAMS((int, Keymap, int, int));
static int _rl_subseq_getchar PARAMS((int));
/* **************************************************************** */
/* */
......@@ -104,6 +112,7 @@ int rl_gnu_readline_p = 1;
By default, it is the standard emacs keymap. */
Keymap _rl_keymap = emacs_standard_keymap;
/* The current style of editing. */
int rl_editing_mode = emacs_mode;
......@@ -219,6 +228,9 @@ char *_rl_comment_begin;
/* Keymap holding the function currently being executed. */
Keymap rl_executing_keymap;
/* Keymap we're currently using to dispatch. */
Keymap _rl_dispatching_keymap;
/* Non-zero means to erase entire line, including prompt, on empty input lines. */
int rl_erase_empty_line = 0;
......@@ -230,6 +242,9 @@ int rl_num_chars_to_read;
char *rl_line_buffer = (char *)NULL;
int rl_line_buffer_len = 0;
/* Key sequence `contexts' */
_rl_keyseq_cxt *_rl_kscxt = 0;
/* Forward declarations used by the display, termcap, and history code. */
/* **************************************************************** */
......@@ -251,6 +266,10 @@ int _rl_convert_meta_chars_to_ascii = 1;
rather than as a meta-prefixed escape sequence. */
int _rl_output_meta_chars = 0;
/* Non-zero means to look at the termios special characters and bind
them to equivalent readline functions at startup. */
int _rl_bind_stty_chars = 1;
/* **************************************************************** */
/* */
/* Top Level Functions */
......@@ -268,6 +287,7 @@ rl_set_prompt (prompt)
{
FREE (rl_prompt);
rl_prompt = prompt ? savestring (prompt) : (char *)NULL;
rl_display_prompt = rl_prompt ? rl_prompt : "";
rl_visible_prompt_length = rl_expand_prompt (rl_prompt);
return 0;
......@@ -291,6 +311,7 @@ readline (prompt)
rl_set_prompt (prompt);
rl_initialize ();
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
#if defined (HANDLE_SIGNALS)
......@@ -298,6 +319,7 @@ readline (prompt)
#endif
value = readline_internal ();
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS)
......@@ -388,6 +410,36 @@ readline_internal_teardown (eof)
return (eof ? (char *)NULL : savestring (the_line));
}
void
_rl_internal_char_cleanup ()
{
#if defined (VI_MODE)
/* In vi mode, when you exit insert mode, the cursor moves back
over the previous character. We explicitly check for that here. */
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
rl_vi_check ();
#endif /* VI_MODE */
if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
rl_newline (1, '\n');
}
if (rl_done == 0)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
}
/* If the application writer has told us to erase the entire line if
the only character typed was something bound to rl_newline, do so. */
if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline &&
rl_point == 0 && rl_end == 0)
_rl_erase_entire_line ();
}
STATIC_CALLBACK int
#if defined (READLINE_CALLBACKS)
readline_internal_char ()
......@@ -410,12 +462,21 @@ readline_internal_charloop ()
code = setjmp (readline_top_level);
if (code)
{
(*rl_redisplay_function) ();
_rl_want_redisplay = 0;
/* If we get here, we're not being called from something dispatched
from _rl_callback_read_char(), which sets up its own value of
readline_top_level (saving and restoring the old, of course), so
we can just return here. */
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
}
if (rl_pending_input == 0)
{
/* Then initialize the argument and number of keys read. */
_rl_init_argument ();
_rl_reset_argument ();
rl_key_sequence_length = 0;
}
......@@ -423,6 +484,20 @@ readline_internal_charloop ()
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_READCMD);
/* look at input.c:rl_getc() for the circumstances under which this will
be returned; punt immediately on read error without converting it to
a newline. */
if (c == READERR)
{
#if defined (READLINE_CALLBACKS)
RL_SETSTATE(RL_STATE_DONE);
return (rl_done = 1);
#else
eof_found = 1;
break;
#endif
}
/* EOF typed to a non-blank line is a <NL>. */
if (c == EOF && rl_end)
c = NEWLINE;
......@@ -449,27 +524,7 @@ readline_internal_charloop ()
if (rl_pending_input == 0 && lk == _rl_last_command_was_kill)
_rl_last_command_was_kill = 0;
#if defined (VI_MODE)
/* In vi mode, when you exit insert mode, the cursor moves back
over the previous character. We explicitly check for that here. */
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap)
rl_vi_check ();
#endif /* VI_MODE */
if (rl_num_chars_to_read && rl_end >= rl_num_chars_to_read)
{
(*rl_redisplay_function) ();
rl_newline (1, '\n');
}
if (rl_done == 0)
(*rl_redisplay_function) ();
/* If the application writer has told us to erase the entire line if
the only character typed was something bound to rl_newline, do so. */
if (rl_erase_empty_line && rl_done && rl_last_func == rl_newline &&
rl_point == 0 && rl_end == 0)
_rl_erase_entire_line ();
_rl_internal_char_cleanup ();
#if defined (READLINE_CALLBACKS)
return 0;
......@@ -519,6 +574,107 @@ _rl_set_the_line ()
the_line = rl_line_buffer;
}
#if defined (READLINE_CALLBACKS)
_rl_keyseq_cxt *
_rl_keyseq_cxt_alloc ()
{
_rl_keyseq_cxt *cxt;
cxt = (_rl_keyseq_cxt *)xmalloc (sizeof (_rl_keyseq_cxt));
cxt->flags = cxt->subseq_arg = cxt->subseq_retval = 0;
cxt->okey = 0;
cxt->ocxt = _rl_kscxt;
cxt->childval = 42; /* sentinel value */
return cxt;
}
void
_rl_keyseq_cxt_dispose (cxt)
_rl_keyseq_cxt *cxt;
{
free (cxt);
}
void
_rl_keyseq_chain_dispose ()
{
_rl_keyseq_cxt *cxt;
while (_rl_kscxt)
{
cxt = _rl_kscxt;
_rl_kscxt = _rl_kscxt->ocxt;
_rl_keyseq_cxt_dispose (cxt);
}
}
#endif
static int
_rl_subseq_getchar (key)
int key;
{
int k;
if (key == ESC)
RL_SETSTATE(RL_STATE_METANEXT);
RL_SETSTATE(RL_STATE_MOREINPUT);
k = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (key == ESC)
RL_UNSETSTATE(RL_STATE_METANEXT);
return k;
}
#if defined (READLINE_CALLBACKS)
int
_rl_dispatch_callback (cxt)
_rl_keyseq_cxt *cxt;
{
int nkey, r;
/* For now */
#if 1
/* The first time this context is used, we want to read input and dispatch
on it. When traversing the chain of contexts back `up', we want to use
the value from the next context down. We're simulating recursion using
a chain of contexts. */
if ((cxt->flags & KSEQ_DISPATCHED) == 0)
{
nkey = _rl_subseq_getchar (cxt->okey);
r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg);
cxt->flags |= KSEQ_DISPATCHED;
}
else
r = cxt->childval;
#else
r = _rl_dispatch_subseq (nkey, cxt->dmap, cxt->subseq_arg);
#endif
/* For now */
r = _rl_subseq_result (r, cxt->oldmap, cxt->okey, (cxt->flags & KSEQ_SUBSEQ));
if (r == 0) /* success! */
{
_rl_keyseq_chain_dispose ();
RL_UNSETSTATE (RL_STATE_MULTIKEY);
return r;
}
if (r != -3) /* magic value that says we added to the chain */
_rl_kscxt = cxt->ocxt;
if (_rl_kscxt)
_rl_kscxt->childval = r;
if (r != -3)
_rl_keyseq_cxt_dispose (cxt);
return r;
}
#endif /* READLINE_CALLBACKS */
/* Do the command associated with KEY in MAP.
If the associated command is really a keymap, then read
another key, and dispatch into that map. */
......@@ -527,6 +683,7 @@ _rl_dispatch (key, map)
register int key;
Keymap map;
{
_rl_dispatching_keymap = map;
return _rl_dispatch_subseq (key, map, 0);
}
......@@ -539,6 +696,9 @@ _rl_dispatch_subseq (key, map, got_subseq)
int r, newkey;
char *macro;
rl_command_func_t *func;
#if defined (READLINE_CALLBACKS)
_rl_keyseq_cxt *cxt;
#endif
if (META_CHAR (key) && _rl_convert_meta_chars_to_ascii)
{
......@@ -572,13 +732,9 @@ _rl_dispatch_subseq (key, map, got_subseq)
rl_executing_keymap = map;
#if 0
_rl_suppress_redisplay = (map[key].function == rl_insert) && _rl_input_available ();
#endif
rl_dispatching = 1;
RL_SETSTATE(RL_STATE_DISPATCHING);
r = (*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
(*map[key].function)(rl_numeric_arg * rl_arg_sign, key);
RL_UNSETSTATE(RL_STATE_DISPATCHING);
rl_dispatching = 0;
......@@ -607,6 +763,10 @@ _rl_dispatch_subseq (key, map, got_subseq)
}
else
{
#if defined (READLINE_CALLBACKS)
RL_UNSETSTATE (RL_STATE_MULTIKEY);
_rl_keyseq_chain_dispose ();
#endif
_rl_abort_internal ();
return -1;
}
......@@ -628,22 +788,79 @@ _rl_dispatch_subseq (key, map, got_subseq)
#endif
rl_key_sequence_length++;
_rl_dispatching_keymap = FUNCTION_TO_KEYMAP (map, key);
if (key == ESC)
RL_SETSTATE(RL_STATE_METANEXT);
RL_SETSTATE(RL_STATE_MOREINPUT);
newkey = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (key == ESC)
RL_UNSETSTATE(RL_STATE_METANEXT);
/* Allocate new context here. Use linked contexts (linked through
cxt->ocxt) to simulate recursion */
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
/* Return 0 only the first time, to indicate success to
_rl_callback_read_char. The rest of the time, we're called
from _rl_dispatch_callback, so we return 3 to indicate
special handling is necessary. */
r = RL_ISSTATE (RL_STATE_MULTIKEY) ? -3 : 0;
cxt = _rl_keyseq_cxt_alloc ();
if (got_subseq)
cxt->flags |= KSEQ_SUBSEQ;
cxt->okey = key;
cxt->oldmap = map;
cxt->dmap = _rl_dispatching_keymap;
cxt->subseq_arg = got_subseq || cxt->dmap[ANYOTHERKEY].function;
RL_SETSTATE (RL_STATE_MULTIKEY);
_rl_kscxt = cxt;
return r; /* don't indicate immediate success */
}
#endif
newkey = _rl_subseq_getchar (key);
if (newkey < 0)
{
_rl_abort_internal ();
return -1;
}
r = _rl_dispatch_subseq (newkey, FUNCTION_TO_KEYMAP (map, key), got_subseq || map[ANYOTHERKEY].function);
r = _rl_dispatch_subseq (newkey, _rl_dispatching_keymap, got_subseq || map[ANYOTHERKEY].function);
return _rl_subseq_result (r, map, key, got_subseq);
}
else
{
_rl_abort_internal ();
return -1;
}
break;
case ISMACR:
if (map[key].function != 0)
{
macro = savestring ((char *)map[key].function);
_rl_with_macro_input (macro);
return 0;
}
break;
}
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
key != ANYOTHERKEY &&
_rl_vi_textmod_command (key))
_rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
#endif
return (r);
}
static int
_rl_subseq_result (r, map, key, got_subseq)
int r;
Keymap map;
int key, got_subseq;
{
Keymap m;
int type, nt;
rl_command_func_t *func, *nf;
if (r == -2)
/* We didn't match anything, and the keymap we're indexed into
......@@ -652,19 +869,27 @@ _rl_dispatch_subseq (key, map, got_subseq)
already taken care of pushing any necessary input back onto
the input queue with _rl_unget_char. */
{
#if 0
r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key));
#else
/* XXX - experimental code -- might never be executed. Save
for later. */
Keymap m = FUNCTION_TO_KEYMAP (map, key);
int type = m[ANYOTHERKEY].type;
m = _rl_dispatching_keymap;
type = m[ANYOTHERKEY].type;
func = m[ANYOTHERKEY].function;
if (type == ISFUNC && func == rl_do_lowercase_version)
r = _rl_dispatch (_rl_to_lower (key), map);
else if (type == ISFUNC && func == rl_insert)
{
/* If the function that was shadowed was self-insert, we
somehow need a keymap with map[key].func == self-insert.
Let's use this one. */
nt = m[key].type;
nf = m[key].function;
m[key].type = type;
m[key].function = func;
r = _rl_dispatch (key, m);
m[key].type = nt;
m[key].function = nf;
}
else
r = _rl_dispatch (ANYOTHERKEY, m);
#endif
}
else if (r && map[ANYOTHERKEY].function)
{
......@@ -672,38 +897,18 @@ _rl_dispatch_subseq (key, map, got_subseq)
tell the caller that it should try ANYOTHERKEY for an
overridden function. */
_rl_unget_char (key);
_rl_dispatching_keymap = map;
return -2;
}
else if (r && got_subseq)
{
/* OK, back up the chain. */
_rl_unget_char (key);
_rl_dispatching_keymap = map;
return -1;
}
}
else
{
_rl_abort_internal ();
return -1;
}
break;
case ISMACR:
if (map[key].function != 0)
{
macro = savestring ((char *)map[key].function);
_rl_with_macro_input (macro);
return 0;
}
break;
}
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
key != ANYOTHERKEY &&
_rl_vi_textmod_command (key))
_rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
#endif
return (r);
return r;
}
/* **************************************************************** */
......@@ -863,19 +1068,21 @@ readline_initialize_everything ()
static void
readline_default_bindings ()
{
if (_rl_bind_stty_chars)
rl_tty_set_default_bindings (_rl_keymap);
}
/* Reset the default bindings for the terminal special characters we're
interested in back to rl_insert and read the new ones. */
#ifdef NOT_USED
static void
reset_default_bindings ()
{
if (_rl_bind_stty_chars)
{
rl_tty_unset_default_bindings (_rl_keymap);
rl_tty_set_default_bindings (_rl_keymap);
}
}
#endif
/* Bind some common arrow key sequences in MAP. */
static void
......@@ -908,6 +1115,13 @@ bind_arrow_keys_internal (map)
rl_bind_keyseq_if_unbound ("\033OH", rl_beg_of_line);
rl_bind_keyseq_if_unbound ("\033OF", rl_end_of_line);
#if defined (__MINGW32__)
rl_bind_keyseq_if_unbound ("\340H", rl_get_previous_history);
rl_bind_keyseq_if_unbound ("\340P", rl_get_next_history);
rl_bind_keyseq_if_unbound ("\340M", rl_forward_char);
rl_bind_keyseq_if_unbound ("\340K", rl_backward_char);
#endif
_rl_keymap = xkeymap;
}
......
/* Readline.h -- the names of functions callable from within readline. */
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -40,9 +40,9 @@ extern "C" {
#endif
/* Hex-encoded Readline version number. */
#define RL_READLINE_VERSION 0x0500 /* Readline 5.0 */
#define RL_READLINE_VERSION 0x0502 /* Readline 5.2 */
#define RL_VERSION_MAJOR 5
#define RL_VERSION_MINOR 0
#define RL_VERSION_MINOR 2
/* Readline data structures. */
......@@ -241,6 +241,7 @@ extern int rl_vi_column PARAMS((int, int));
extern int rl_vi_delete_to PARAMS((int, int));
extern int rl_vi_change_to PARAMS((int, int));
extern int rl_vi_yank_to PARAMS((int, int));
extern int rl_vi_rubout PARAMS((int, int));
extern int rl_vi_delete PARAMS((int, int));
extern int rl_vi_back_to_indent PARAMS((int, int));
extern int rl_vi_first_print PARAMS((int, int));
......@@ -302,6 +303,8 @@ extern int rl_bind_keyseq_in_map PARAMS((const char *, rl_command_func_t *, Keym
extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *));
extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap));
extern char *rl_variable_value PARAMS((const char *));
extern int rl_variable_bind PARAMS((const char *, const char *));
/* Backwards compatibility, use rl_bind_keyseq_in_map instead. */
......@@ -401,6 +404,7 @@ extern int rl_reset_terminal PARAMS((const char *));
extern void rl_resize_terminal PARAMS((void));
extern void rl_set_screen_size PARAMS((int, int));
extern void rl_get_screen_size PARAMS((int *, int *));
extern void rl_reset_screen_size PARAMS((void));
extern char *rl_get_termcap PARAMS((const char *));
......@@ -528,6 +532,11 @@ extern const char *rl_terminal_name;
extern FILE *rl_instream;
extern FILE *rl_outstream;
/* If non-zero, Readline gives values of LINES and COLUMNS from the environment
greater precedence than values fetched from the kernel when computing the
screen dimensions. */
extern int rl_prefer_env_winsize;
/* If non-zero, then this is the address of a function to call just
before readline_internal () prints the first prompt. */
extern rl_hook_func_t *rl_startup_hook;
......@@ -748,6 +757,10 @@ extern int rl_ignore_completion_duplicates;
completion character will be inserted as any other. */
extern int rl_inhibit_completion;
/* Input error; can be returned by (*rl_getc_function) if readline is reading
a top-level command (RL_ISSTATE (RL_STATE_READCMD)). */
#define READERR (-2)
/* Definitions available for use by readline clients. */
#define RL_PROMPT_START_IGNORE '\001'
#define RL_PROMPT_END_IGNORE '\002'
......@@ -759,29 +772,33 @@ extern int rl_inhibit_completion;
#define MULT_MATCH 2
/* Possible state values for rl_readline_state */
#define RL_STATE_NONE 0x00000 /* no state; before first call */
#define RL_STATE_INITIALIZING 0x00001 /* initializing */
#define RL_STATE_INITIALIZED 0x00002 /* initialization done */
#define RL_STATE_TERMPREPPED 0x00004 /* terminal is prepped */
#define RL_STATE_READCMD 0x00008 /* reading a command key */
#define RL_STATE_METANEXT 0x00010 /* reading input after ESC */
#define RL_STATE_DISPATCHING 0x00020 /* dispatching to a command */
#define RL_STATE_MOREINPUT 0x00040 /* reading more input in a command function */
#define RL_STATE_ISEARCH 0x00080 /* doing incremental search */
#define RL_STATE_NSEARCH 0x00100 /* doing non-inc search */
#define RL_STATE_SEARCH 0x00200 /* doing a history search */
#define RL_STATE_NUMERICARG 0x00400 /* reading numeric argument */
#define RL_STATE_MACROINPUT 0x00800 /* getting input from a macro */
#define RL_STATE_MACRODEF 0x01000 /* defining keyboard macro */
#define RL_STATE_OVERWRITE 0x02000 /* overwrite mode */
#define RL_STATE_COMPLETING 0x04000 /* doing completion */
#define RL_STATE_SIGHANDLER 0x08000 /* in readline sighandler */
#define RL_STATE_UNDOING 0x10000 /* doing an undo */
#define RL_STATE_INPUTPENDING 0x20000 /* rl_execute_next called */
#define RL_STATE_TTYCSAVED 0x40000 /* tty special chars saved */
#define RL_STATE_DONE 0x80000 /* done; accepted line */
#define RL_STATE_NONE 0x000000 /* no state; before first call */
#define RL_STATE_INITIALIZING 0x000001 /* initializing */
#define RL_STATE_INITIALIZED 0x000002 /* initialization done */
#define RL_STATE_TERMPREPPED 0x000004 /* terminal is prepped */
#define RL_STATE_READCMD 0x000008 /* reading a command key */
#define RL_STATE_METANEXT 0x000010 /* reading input after ESC */
#define RL_STATE_DISPATCHING 0x000020 /* dispatching to a command */
#define RL_STATE_MOREINPUT 0x000040 /* reading more input in a command function */
#define RL_STATE_ISEARCH 0x000080 /* doing incremental search */
#define RL_STATE_NSEARCH 0x000100 /* doing non-inc search */
#define RL_STATE_SEARCH 0x000200 /* doing a history search */
#define RL_STATE_NUMERICARG 0x000400 /* reading numeric argument */
#define RL_STATE_MACROINPUT 0x000800 /* getting input from a macro */
#define RL_STATE_MACRODEF 0x001000 /* defining keyboard macro */
#define RL_STATE_OVERWRITE 0x002000 /* overwrite mode */
#define RL_STATE_COMPLETING 0x004000 /* doing completion */
#define RL_STATE_SIGHANDLER 0x008000 /* in readline sighandler */
#define RL_STATE_UNDOING 0x010000 /* doing an undo */
#define RL_STATE_INPUTPENDING 0x020000 /* rl_execute_next called */
#define RL_STATE_TTYCSAVED 0x040000 /* tty special chars saved */
#define RL_STATE_CALLBACK 0x080000 /* using the callback interface */
#define RL_STATE_VIMOTION 0x100000 /* reading vi motion arg */
#define RL_STATE_MULTIKEY 0x200000 /* reading multiple-key command */
#define RL_STATE_VICMDONCE 0x400000 /* entered vi command mode at least once */
#define RL_STATE_DONE 0x800000 /* done; accepted line */
#define RL_SETSTATE(x) (rl_readline_state |= (x))
#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
......
......@@ -37,9 +37,12 @@
/* Ugly but working hack for binding prefix meta. */
#define PREFIX_META_HACK
/* The final, last-ditch effort file name for an init file. */
/* The next-to-last-ditch effort file name for a user-specific init file. */
#define DEFAULT_INPUTRC "~/.inputrc"
/* The ultimate last-ditch filenname for an init file -- system-wide. */
#define SYS_INPUTRC "/etc/inputrc"
/* If defined, expand tabs to spaces. */
#define DISPLAY_TABS
......
......@@ -2,7 +2,7 @@
for readline. This should be included after any files that define
system-specific constants like _POSIX_VERSION or USG. */
/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file contains the Readline Library (the Library), a set of
routines for providing Emacs style line input to programs that ask
......@@ -38,7 +38,11 @@
# if defined (HAVE_TERMIO_H)
# define TERMIO_TTY_DRIVER
# else
# if !defined (__MINGW32__)
# define NEW_TTY_DRIVER
# else
# define NO_TTY_DRIVER
# endif
# endif
#endif
......
......@@ -32,10 +32,19 @@
/* For platforms which support the ISO C amendement 1 functionality we
support user defined character classes. */
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H)
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) && defined (HAVE_LOCALE_H)
# include <wchar.h>
# include <wctype.h>
# if defined (HAVE_MBSRTOWCS) && defined (HAVE_MBRTOWC) && defined (HAVE_MBRLEN) && defined (HAVE_WCWIDTH)
# if defined (HAVE_ISWCTYPE) && \
defined (HAVE_ISWLOWER) && \
defined (HAVE_ISWUPPER) && \
defined (HAVE_MBSRTOWCS) && \
defined (HAVE_MBRTOWC) && \
defined (HAVE_MBRLEN) && \
defined (HAVE_TOWLOWER) && \
defined (HAVE_TOWUPPER) && \
defined (HAVE_WCHAR_T) && \
defined (HAVE_WCWIDTH)
/* system is supposed to support XPG5 */
# define HANDLE_MULTIBYTE 1
# endif
......@@ -97,6 +106,21 @@ extern int _rl_read_mbstring PARAMS((int, char *, int));
extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
extern wchar_t _rl_char_value PARAMS((char *, int));
extern int _rl_walphabetic PARAMS((wchar_t));
#define _rl_to_wupper(wc) (iswlower (wc) ? towupper (wc) : (wc))
#define _rl_to_wlower(wc) (iswupper (wc) ? towlower (wc) : (wc))
#define MB_NEXTCHAR(b,s,c,f) \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \
? _rl_find_next_mbchar ((b), (s), (c), (f)) \
: ((s) + (c)))
#define MB_PREVCHAR(b,s,f) \
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \
? _rl_find_prev_mbchar ((b), (s), (f)) \
: ((s) - 1))
#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
#define MB_NULLWCH(x) ((x) == 0)
......@@ -111,6 +135,16 @@ extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1))
#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2))
#define _rl_char_value(buf,ind) ((buf)[(ind)])
#define _rl_walphabetic(c) (rl_alphabetic (c))
#define _rl_to_wupper(c) (_rl_to_upper (c))
#define _rl_to_wlower(c) (_rl_to_lower (c))
#define MB_NEXTCHAR(b,s,c,f) ((s) + (c))
#define MB_PREVCHAR(b,s,f) ((s) - 1)
#define MB_INVALIDCH(x) (0)
#define MB_NULLWCH(x) (0)
......
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
/* Copyright (C) 1999-2004 Free Software Foundation, Inc.
/* Copyright (C) 1999-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -28,6 +28,95 @@
#include "rlstdc.h"
#include "posixjmp.h" /* defines procenv_t */
/*************************************************************************
* *
* Global structs undocumented in texinfo manual and not in readline.h *
* *
*************************************************************************/
/* search types */
#define RL_SEARCH_ISEARCH 0x01 /* incremental search */
#define RL_SEARCH_NSEARCH 0x02 /* non-incremental search */
#define RL_SEARCH_CSEARCH 0x04 /* intra-line char search */
/* search flags */
#define SF_REVERSE 0x01
#define SF_FOUND 0x02
#define SF_FAILED 0x04
typedef struct __rl_search_context
{
int type;
int sflags;
char *search_string;
int search_string_index;
int search_string_size;
char **lines;
char *allocated_line;
int hlen;
int hindex;
int save_point;
int save_mark;
int save_line;
int last_found_line;
char *prev_line_found;
UNDO_LIST *save_undo_list;
int history_pos;
int direction;
int lastc;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
#endif
char *sline;
int sline_len;
int sline_index;
char *search_terminators;
} _rl_search_cxt;
/* Callback data for reading numeric arguments */
#define NUM_SAWMINUS 0x01
#define NUM_SAWDIGITS 0x02
#define NUM_READONE 0x04
typedef int _rl_arg_cxt;
/* A context for reading key sequences longer than a single character when
using the callback interface. */
#define KSEQ_DISPATCHED 0x01
#define KSEQ_SUBSEQ 0x02
#define KSEQ_RECURSIVE 0x04
typedef struct __rl_keyseq_context
{
int flags;
int subseq_arg;
int subseq_retval; /* XXX */
Keymap dmap;
Keymap oldmap;
int okey;
struct __rl_keyseq_context *ocxt;
int childval;
} _rl_keyseq_cxt;
/* fill in more as needed */
/* `Generic' callback data and functions */
typedef struct __rl_callback_generic_arg
{
int count;
int i1, i2;
/* add here as needed */
} _rl_callback_generic_arg;
typedef int _rl_callback_func_t PARAMS((_rl_callback_generic_arg *));
/*************************************************************************
* *
* Global functions undocumented in texinfo manual and not in readline.h *
......@@ -54,6 +143,8 @@ extern int readline_echoing_p;
extern int rl_key_sequence_length;
extern int rl_byte_oriented;
extern _rl_keyseq_cxt *_rl_kscxt;
/* display.c */
extern int rl_display_fixed;
......@@ -100,6 +191,16 @@ extern void readline_internal_setup PARAMS((void));
extern char *readline_internal_teardown PARAMS((int));
extern int readline_internal_char PARAMS((void));
extern _rl_keyseq_cxt *_rl_keyseq_cxt_alloc PARAMS((void));
extern void _rl_keyseq_cxt_dispose PARAMS((_rl_keyseq_cxt *));
extern void _rl_keyseq_chain_dispose PARAMS((void));
extern int _rl_dispatch_callback PARAMS((_rl_keyseq_cxt *));
/* callback.c */
extern _rl_callback_generic_arg *_rl_callback_data_alloc PARAMS((int));
extern void _rl_callback_data_dispose PARAMS((_rl_callback_generic_arg *));
#endif /* READLINE_CALLBACKS */
/* bind.c */
......@@ -132,6 +233,15 @@ extern void _rl_insert_typein PARAMS((int));
extern int _rl_unget_char PARAMS((int));
extern int _rl_pushed_input_available PARAMS((void));
/* isearch.c */
extern _rl_search_cxt *_rl_scxt_alloc PARAMS((int, int));
extern void _rl_scxt_dispose PARAMS((_rl_search_cxt *, int));
extern int _rl_isearch_dispatch PARAMS((_rl_search_cxt *, int));
extern int _rl_isearch_callback PARAMS((_rl_search_cxt *));
extern int _rl_search_getchar PARAMS((_rl_search_cxt *));
/* macro.c */
extern void _rl_with_macro_input PARAMS((char *));
extern int _rl_next_macro_key PARAMS((void));
......@@ -141,7 +251,12 @@ extern void _rl_add_macro_char PARAMS((int));
extern void _rl_kill_kbd_macro PARAMS((void));
/* misc.c */
extern int _rl_init_argument PARAMS((void));
extern int _rl_arg_overflow PARAMS((void));
extern void _rl_arg_init PARAMS((void));
extern int _rl_arg_getchar PARAMS((void));
extern int _rl_arg_callback PARAMS((_rl_arg_cxt));
extern void _rl_reset_argument PARAMS((void));
extern void _rl_start_using_history PARAMS((void));
extern int _rl_free_saved_history_line PARAMS((void));
extern void _rl_set_insert_mode PARAMS((int, int));
......@@ -157,11 +272,15 @@ extern void _rl_init_line_state PARAMS((void));
extern void _rl_set_the_line PARAMS((void));
extern int _rl_dispatch PARAMS((int, Keymap));
extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
extern void _rl_internal_char_cleanup PARAMS((void));
/* rltty.c */
extern int _rl_disable_tty_signals PARAMS((void));
extern int _rl_restore_tty_signals PARAMS((void));
/* search.c */
extern int _rl_nsearch_callback PARAMS((_rl_search_cxt *));
/* terminal.c */
extern void _rl_get_screen_size PARAMS((int, int));
extern int _rl_init_terminal_io PARAMS((const char *));
......@@ -190,6 +309,10 @@ extern int _rl_char_search_internal PARAMS((int, int, int));
#endif
extern int _rl_set_mark_at_pos PARAMS((int));
/* undo.c */
extern UNDO_LIST *_rl_copy_undo_entry PARAMS((UNDO_LIST *));
extern UNDO_LIST *_rl_copy_undo_list PARAMS((UNDO_LIST *));
/* util.c */
extern int _rl_abort_internal PARAMS((void));
extern char *_rl_strindex PARAMS((const char *, const char *));
......@@ -217,6 +340,10 @@ extern void _rl_vi_done_inserting PARAMS((void));
extern const char *_rl_possible_control_prefixes[];
extern const char *_rl_possible_meta_prefixes[];
/* callback.c */
extern _rl_callback_func_t *_rl_callback_func;
extern _rl_callback_generic_arg *_rl_callback_data;
/* complete.c */
extern int _rl_complete_show_all;
extern int _rl_complete_show_unmodified;
......@@ -231,11 +358,14 @@ extern int _rl_page_completions;
extern int _rl_vis_botlin;
extern int _rl_last_c_pos;
extern int _rl_suppress_redisplay;
extern int _rl_want_redisplay;
extern char *rl_display_prompt;
/* isearch.c */
extern char *_rl_isearch_terminators;
extern _rl_search_cxt *_rl_iscxt;
/* macro.c */
extern char *_rl_executing_macro;
......@@ -243,6 +373,8 @@ extern char *_rl_executing_macro;
extern int _rl_history_preserve_point;
extern int _rl_history_saved_point;
extern _rl_arg_cxt _rl_argcxt;
/* readline.c */
extern int _rl_horizontal_scroll_mode;
extern int _rl_mark_modified_lines;
......@@ -250,6 +382,7 @@ extern int _rl_bell_preference;
extern int _rl_meta_flag;
extern int _rl_convert_meta_chars_to_ascii;
extern int _rl_output_meta_chars;
extern int _rl_bind_stty_chars;
extern char *_rl_comment_begin;
extern unsigned char _rl_parsing_conditionalized_out;
extern Keymap _rl_keymap;
......@@ -259,6 +392,9 @@ extern int _rl_last_command_was_kill;
extern int _rl_eof_char;
extern procenv_t readline_top_level;
/* search.c */
extern _rl_search_cxt *_rl_nscxt;
/* terminal.c */
extern int _rl_enable_keypad;
extern int _rl_enable_meta;
......@@ -272,6 +408,7 @@ extern char *_rl_term_up;
extern char *_rl_term_dc;
extern char *_rl_term_cr;
extern char *_rl_term_IC;
extern char *_rl_term_forward_char;
extern int _rl_screenheight;
extern int _rl_screenwidth;
extern int _rl_screenchars;
......
/* rltty.c -- functions to prepare and restore the terminal for readline's
use. */
/* Copyright (C) 1992 Free Software Foundation, Inc.
/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -22,7 +22,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <signal.h>
......@@ -150,7 +152,9 @@ set_winsize (tty)
#endif /* TIOCGWINSZ */
}
#if defined (NEW_TTY_DRIVER)
#if defined (NO_TTY_DRIVER)
/* Nothing */
#elif defined (NEW_TTY_DRIVER)
/* Values for the `flags' field of a struct bsdtty. This tells which
elements of the struct bsdtty have been fetched from the system and
......@@ -231,6 +235,7 @@ get_tty_settings (tty, tiop)
tiop->flags = tiop->lflag = 0;
errno = 0;
if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
return -1;
tiop->flags |= SGTTY_SET;
......@@ -516,6 +521,7 @@ get_tty_settings (tty, tiop)
{
set_winsize (tty);
errno = 0;
if (_get_tty_settings (tty, tiop) < 0)
return -1;
......@@ -629,9 +635,23 @@ prepare_terminal_settings (meta_flag, oldtio, tiop)
#endif /* TERMIOS_TTY_DRIVER && _POSIX_VDISABLE */
}
#endif /* NEW_TTY_DRIVER */
#endif /* !NEW_TTY_DRIVER */
/* Put the terminal in CBREAK mode so that we can detect key presses. */
#if defined (NO_TTY_DRIVER)
void
rl_prep_terminal (meta_flag)
int meta_flag;
{
readline_echoing_p = 1;
}
void
rl_deprep_terminal ()
{
}
#else /* ! NO_TTY_DRIVER */
void
rl_prep_terminal (meta_flag)
int meta_flag;
......@@ -649,16 +669,43 @@ rl_prep_terminal (meta_flag)
if (get_tty_settings (tty, &tio) < 0)
{
#if defined (ENOTSUP)
/* MacOS X, at least, lies about the value of errno if tcgetattr fails. */
if (errno == ENOTTY || errno == ENOTSUP)
#else
if (errno == ENOTTY)
#endif
readline_echoing_p = 1; /* XXX */
release_sigint ();
return;
}
otio = tio;
if (_rl_bind_stty_chars)
{
#if defined (VI_MODE)
/* If editing in vi mode, make sure we restore the bindings in the
insertion keymap no matter what keymap we ended up in. */
if (rl_editing_mode == vi_mode)
rl_tty_unset_default_bindings (vi_insertion_keymap);
else
#endif
rl_tty_unset_default_bindings (_rl_keymap);
}
save_tty_chars (&otio);
RL_SETSTATE(RL_STATE_TTYCSAVED);
if (_rl_bind_stty_chars)
{
#if defined (VI_MODE)
/* If editing in vi mode, make sure we set the bindings in the
insertion keymap no matter what keymap we ended up in. */
if (rl_editing_mode == vi_mode)
_rl_bind_tty_special_chars (vi_insertion_keymap, tio);
else
#endif
_rl_bind_tty_special_chars (_rl_keymap, tio);
}
prepare_terminal_settings (meta_flag, otio, &tio);
......@@ -708,6 +755,7 @@ rl_deprep_terminal ()
release_sigint ();
}
#endif /* !NO_TTY_DRIVER */
/* **************************************************************** */
/* */
......@@ -716,8 +764,13 @@ rl_deprep_terminal ()
/* **************************************************************** */
int
rl_restart_output(int count __attribute__((unused)), int key __attribute__((unused)))
rl_restart_output (count, key)
int count, key;
{
#if defined (__MINGW32__)
return 0;
#else /* !__MING32__ */
int fildes = fileno (rl_outstream);
#if defined (TIOCSTART)
#if defined (apollo)
......@@ -745,11 +798,17 @@ rl_restart_output(int count __attribute__((unused)), int key __attribute__((unus
#endif /* !TIOCSTART */
return 0;
#endif /* !__MINGW32__ */
}
int
rl_stop_output(int count __attribute__((unused)), int key __attribute__((unused)))
rl_stop_output (count, key)
int count, key;
{
#if defined (__MINGW32__)
return 0;
#else
int fildes = fileno (rl_instream);
#if defined (TIOCSTOP)
......@@ -772,6 +831,7 @@ rl_stop_output(int count __attribute__((unused)), int key __attribute__((unused)
#endif /* !TIOCSTOP */
return 0;
#endif /* !__MINGW32__ */
}
/* **************************************************************** */
......@@ -780,9 +840,16 @@ rl_stop_output(int count __attribute__((unused)), int key __attribute__((unused)
/* */
/* **************************************************************** */
#if !defined (NO_TTY_DRIVER)
#define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func)
#endif
#if defined (NO_TTY_DRIVER)
#if defined (NEW_TTY_DRIVER)
#define SET_SPECIAL(sc, func)
#define RESET_SPECIAL(c)
#elif defined (NEW_TTY_DRIVER)
static void
set_special_char (kmap, tiop, sc, func)
Keymap kmap;
......@@ -863,6 +930,7 @@ void
rltty_set_default_bindings (kmap)
Keymap kmap;
{
#if !defined (NO_TTY_DRIVER)
TIOTYPE ttybuff;
int tty;
......@@ -870,6 +938,7 @@ rltty_set_default_bindings (kmap)
if (get_tty_settings (tty, &ttybuff) == 0)
_rl_bind_tty_special_chars (kmap, ttybuff);
#endif
}
/* New public way to set the system default editing chars to their readline
......@@ -907,7 +976,7 @@ rl_tty_unset_default_bindings (kmap)
#if defined (HANDLE_SIGNALS)
#if defined (NEW_TTY_DRIVER)
#if defined (NEW_TTY_DRIVER) || defined (NO_TTY_DRIVER)
int
_rl_disable_tty_signals ()
{
......
......@@ -21,8 +21,7 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#include <config.h>
#ifdef HAVE_STRING_H
# include <string.h>
#endif
......
/* search.c - code for non-incremental searching in emacs and vi modes. */
/* Copyright (C) 1992 Free Software Foundation, Inc.
/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
This file is part of the Readline Library (the Library), a set of
routines for providing Emacs style line input to programs that ask
......@@ -22,7 +22,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <stdio.h>
......@@ -51,6 +53,8 @@
#endif
#define abs(x) (((x) >= 0) ? (x) : -(x))
_rl_search_cxt *_rl_nscxt = 0;
extern HIST_ENTRY *_rl_saved_line_for_history;
/* Functions imported from the rest of the library. */
......@@ -68,11 +72,16 @@ static int history_string_size;
static void make_history_line_current PARAMS((HIST_ENTRY *));
static int noninc_search_from_pos PARAMS((char *, int, int));
static void noninc_dosearch PARAMS((char *, int));
static void noninc_search PARAMS((int, int));
static int noninc_dosearch PARAMS((char *, int));
static int noninc_search PARAMS((int, int));
static int rl_history_search_internal PARAMS((int, int));
static void rl_history_search_reinit PARAMS((void));
static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
/* Make the data from the history entry ENTRY be the contents of the
current line. This doesn't do anything with rl_point; the caller
must set it. */
......@@ -80,12 +89,15 @@ static void
make_history_line_current (entry)
HIST_ENTRY *entry;
{
#if 0
rl_replace_line (entry->line, 1);
rl_undo_list = (UNDO_LIST *)entry->data;
#else
_rl_replace_text (entry->line, 0, rl_end);
_rl_fix_point (1);
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
/* POSIX.2 says that the `U' command doesn't affect the copy of any
command lines to the edit line. We're going to implement that by
making the undo list start after the matching line is copied to the
current editing buffer. */
rl_free_undo_list ();
#endif
if (_rl_saved_line_for_history)
......@@ -128,8 +140,8 @@ noninc_search_from_pos (string, pos, dir)
/* Search for a line in the history containing STRING. If DIR is < 0, the
search is backwards through previous entries, else through subsequent
entries. */
static void
entries. Returns 1 if the search was successful, 0 otherwise. */
static int
noninc_dosearch (string, dir)
char *string;
int dir;
......@@ -140,7 +152,7 @@ noninc_dosearch (string, dir)
if (string == 0 || *string == '\0' || noninc_history_pos < 0)
{
rl_ding ();
return;
return 0;
}
pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
......@@ -151,7 +163,7 @@ noninc_dosearch (string, dir)
rl_clear_message ();
rl_point = 0;
rl_ding ();
return;
return 0;
}
noninc_history_pos = pos;
......@@ -170,27 +182,24 @@ noninc_dosearch (string, dir)
rl_mark = rl_end;
rl_clear_message ();
return 1;
}
/* Search non-interactively through the history list. DIR < 0 means to
search backwards through the history of previous commands; otherwise
the search is for commands subsequent to the current position in the
history list. PCHAR is the character to use for prompting when reading
the search string; if not specified (0), it defaults to `:'. */
static void
noninc_search (dir, pchar)
int dir;
int pchar;
static _rl_search_cxt *
_rl_nsearch_init (dir, pchar)
int dir, pchar;
{
int saved_point, saved_mark, c;
_rl_search_cxt *cxt;
char *p;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
#endif
cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
if (dir < 0)
cxt->sflags |= SF_REVERSE; /* not strictly needed */
cxt->direction = dir;
cxt->history_pos = cxt->save_line;
rl_maybe_save_line ();
saved_point = rl_point;
saved_mark = rl_mark;
/* Clear the undo list, since reading the search string should create its
own undo list, and the whole list will end up being freed when we
......@@ -202,42 +211,52 @@ noninc_search (dir, pchar)
rl_end = rl_point = 0;
p = _rl_make_prompt_for_search (pchar ? pchar : ':');
rl_message (p, 0, 0);
rl_message ("%s", p, 0);
free (p);
#define SEARCH_RETURN rl_restore_prompt (); RL_UNSETSTATE(RL_STATE_NSEARCH); return
RL_SETSTATE(RL_STATE_NSEARCH);
/* Read the search string. */
while (1)
{
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
#endif
_rl_nscxt = cxt;
if (c == 0)
break;
return cxt;
}
switch (c)
{
case CTRL('H'):
case RUBOUT:
if (rl_point == 0)
{
static int
_rl_nsearch_cleanup (cxt, r)
_rl_search_cxt *cxt;
int r;
{
_rl_scxt_dispose (cxt, 0);
_rl_nscxt = 0;
RL_UNSETSTATE(RL_STATE_NSEARCH);
return (r != 1);
}
static void
_rl_nsearch_abort (cxt)
_rl_search_cxt *cxt;
{
rl_maybe_unsave_line ();
rl_clear_message ();
rl_point = saved_point;
rl_mark = saved_mark;
SEARCH_RETURN;
}
_rl_rubout_char (1, c);
break;
rl_point = cxt->save_point;
rl_mark = cxt->save_mark;
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
}
/* Process just-read character C according to search context CXT. Return -1
if the caller should abort the search, 0 if we should break out of the
loop, and 1 if we should continue to read characters. */
static int
_rl_nsearch_dispatch (cxt, c)
_rl_search_cxt *cxt;
int c;
{
switch (c)
{
case CTRL('W'):
rl_unix_word_rubout (1, c);
break;
......@@ -248,106 +267,187 @@ noninc_search (dir, pchar)
case RETURN:
case NEWLINE:
goto dosearch;
/* NOTREACHED */
return 0;
case CTRL('H'):
case RUBOUT:
if (rl_point == 0)
{
_rl_nsearch_abort (cxt);
return -1;
}
_rl_rubout_char (1, c);
break;
case CTRL('C'):
case CTRL('G'):
rl_maybe_unsave_line ();
rl_clear_message ();
rl_point = saved_point;
rl_mark = saved_mark;
rl_ding ();
SEARCH_RETURN;
_rl_nsearch_abort (cxt);
return -1;
default:
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (mb);
rl_insert_text (cxt->mb);
else
#endif
_rl_insert_char (1, c);
break;
}
(*rl_redisplay_function) ();
}
return 1;
}
dosearch:
rl_mark = saved_mark;
/* Perform one search according to CXT, using NONINC_SEARCH_STRING. Return
-1 if the search should be aborted, any other value means to clean up
using _rl_nsearch_cleanup (). Returns 1 if the search was successful,
0 otherwise. */
static int
_rl_nsearch_dosearch (cxt)
_rl_search_cxt *cxt;
{
rl_mark = cxt->save_mark;
/* If rl_point == 0, we want to re-use the previous search string and
start from the saved history position. If there's no previous search
string, punt. */
if (rl_point == 0)
{
if (!noninc_search_string)
if (noninc_search_string == 0)
{
rl_ding ();
SEARCH_RETURN;
rl_restore_prompt ();
RL_UNSETSTATE (RL_STATE_NSEARCH);
return -1;
}
}
else
{
/* We want to start the search from the current history position. */
noninc_history_pos = where_history ();
noninc_history_pos = cxt->save_line;
FREE (noninc_search_string);
noninc_search_string = savestring (rl_line_buffer);
/* If we don't want the subsequent undo list generated by the search
matching a history line to include the contents of the search string,
we need to clear rl_line_buffer here. For now, we just clear the
undo list generated by reading the search string. (If the search
fails, the old undo list will be restored by rl_maybe_unsave_line.) */
rl_free_undo_list ();
}
rl_restore_prompt ();
noninc_dosearch (noninc_search_string, dir);
RL_UNSETSTATE(RL_STATE_NSEARCH);
return (noninc_dosearch (noninc_search_string, cxt->direction));
}
/* Search non-interactively through the history list. DIR < 0 means to
search backwards through the history of previous commands; otherwise
the search is for commands subsequent to the current position in the
history list. PCHAR is the character to use for prompting when reading
the search string; if not specified (0), it defaults to `:'. */
static int
noninc_search (dir, pchar)
int dir;
int pchar;
{
_rl_search_cxt *cxt;
int c, r;
cxt = _rl_nsearch_init (dir, pchar);
if (RL_ISSTATE (RL_STATE_CALLBACK))
return (0);
/* Read the search string. */
r = 0;
while (1)
{
c = _rl_search_getchar (cxt);
if (c == 0)
break;
r = _rl_nsearch_dispatch (cxt, c);
if (r < 0)
return 1;
else if (r == 0)
break;
}
r = _rl_nsearch_dosearch (cxt);
return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
}
/* Search forward through the history list for a string. If the vi-mode
code calls this, KEY will be `?'. */
int
rl_noninc_forward_search (int count __attribute__((unused)), int key)
rl_noninc_forward_search (count, key)
int count, key;
{
noninc_search (1, (key == '?') ? '?' : 0);
return 0;
return noninc_search (1, (key == '?') ? '?' : 0);
}
/* Reverse search the history list for a string. If the vi-mode code
calls this, KEY will be `/'. */
int
rl_noninc_reverse_search (int count __attribute__((unused)), int key)
rl_noninc_reverse_search (count, key)
int count, key;
{
noninc_search (-1, (key == '/') ? '/' : 0);
return 0;
return noninc_search (-1, (key == '/') ? '/' : 0);
}
/* Search forward through the history list for the last string searched
for. If there is no saved search string, abort. */
int
rl_noninc_forward_search_again (int count __attribute__((unused)),
int key __attribute__((unused)))
rl_noninc_forward_search_again (count, key)
int count, key;
{
int r;
if (!noninc_search_string)
{
rl_ding ();
return (-1);
}
noninc_dosearch (noninc_search_string, 1);
return 0;
r = noninc_dosearch (noninc_search_string, 1);
return (r != 1);
}
/* Reverse search in the history list for the last string searched
for. If there is no saved search string, abort. */
int
rl_noninc_reverse_search_again (int count __attribute__((unused)),
int key __attribute__((unused)))
rl_noninc_reverse_search_again (count, key)
int count, key;
{
int r;
if (!noninc_search_string)
{
rl_ding ();
return (-1);
}
noninc_dosearch (noninc_search_string, -1);
return 0;
r = noninc_dosearch (noninc_search_string, -1);
return (r != 1);
}
#if defined (READLINE_CALLBACKS)
int
_rl_nsearch_callback (cxt)
_rl_search_cxt *cxt;
{
int c, r;
c = _rl_search_getchar (cxt);
r = _rl_nsearch_dispatch (cxt, c);
if (r != 0)
return 1;
r = _rl_nsearch_dosearch (cxt);
return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
}
#endif
static int
rl_history_search_internal (count, dir)
int count, dir;
......
......@@ -22,7 +22,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
......@@ -46,8 +48,12 @@
# include <limits.h>
#endif
#if defined (HAVE_FCNTL_H)
#include <fcntl.h>
#endif
#if defined (HAVE_PWD_H)
#include <pwd.h>
#endif
#include <stdio.h>
......@@ -55,9 +61,9 @@
#include "rlshell.h"
#include "xmalloc.h"
#if !defined (HAVE_GETPW_DECLS)
#if defined (HAVE_GETPWUID) && !defined (HAVE_GETPW_DECLS)
extern struct passwd *getpwuid PARAMS((uid_t));
#endif /* !HAVE_GETPW_DECLS */
#endif /* HAVE_GETPWUID && !HAVE_GETPW_DECLS */
#ifndef NULL
# define NULL 0
......@@ -120,16 +126,7 @@ sh_set_lines_and_columns (lines, cols)
{
char *b;
#if defined (HAVE_PUTENV)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
sprintf (b, "LINES=%d", lines);
putenv (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
sprintf (b, "COLUMNS=%d", cols);
putenv (b);
#else /* !HAVE_PUTENV */
# if defined (HAVE_SETENV)
#if defined (HAVE_SETENV)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", lines);
setenv ("LINES", b, 1);
......@@ -139,8 +136,17 @@ sh_set_lines_and_columns (lines, cols)
sprintf (b, "%d", cols);
setenv ("COLUMNS", b, 1);
free (b);
# endif /* HAVE_SETENV */
#endif /* !HAVE_PUTENV */
#else /* !HAVE_SETENV */
# if defined (HAVE_PUTENV)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
sprintf (b, "LINES=%d", lines);
putenv (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
sprintf (b, "COLUMNS=%d", cols);
putenv (b);
# endif /* HAVE_PUTENV */
#endif /* !HAVE_SETENV */
}
char *
......@@ -157,9 +163,11 @@ sh_get_home_dir ()
struct passwd *entry;
home_dir = (char *)NULL;
#if defined (HAVE_GETPWUID)
entry = getpwuid (getuid ());
if (entry)
home_dir = entry->pw_dir;
#endif
return (home_dir);
}
......@@ -173,6 +181,7 @@ int
sh_unset_nodelay_mode (fd)
int fd;
{
#if defined (HAVE_FCNTL)
int flags, bflags;
if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
......@@ -193,6 +202,7 @@ sh_unset_nodelay_mode (fd)
flags &= ~bflags;
return (fcntl (fd, F_SETFL, flags));
}
#endif
return 0;
}
/* signals.c -- signal handling support for readline. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -21,7 +21,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h> /* Just for NULL. Yuck. */
#include <sys/types.h>
......@@ -129,7 +131,11 @@ rl_signal_handler (sig)
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
/* Since the signal will not be blocked while we are in the signal
handler, ignore it until rl_clear_signals resets the catcher. */
# if defined (SIGALRM)
if (sig == SIGINT || sig == SIGALRM)
# else
if (sig == SIGINT)
# endif
rl_set_sighandler (sig, SIG_IGN, &dummy_cxt);
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
......@@ -139,17 +145,22 @@ rl_signal_handler (sig)
rl_free_line_state ();
/* FALLTHROUGH */
case SIGTERM:
#if defined (SIGTSTP)
case SIGTSTP:
case SIGTTOU:
case SIGTTIN:
#endif /* SIGTSTP */
#if defined (SIGALRM)
case SIGALRM:
case SIGTERM:
#endif
#if defined (SIGQUIT)
case SIGQUIT:
#endif
rl_cleanup_after_signal ();
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&set);
sigprocmask (SIG_BLOCK, (sigset_t *)NULL, &set);
sigdelset (&set, sig);
#else /* !HAVE_POSIX_SIGNALS */
......@@ -162,7 +173,11 @@ rl_signal_handler (sig)
signal (sig, SIG_ACK);
#endif
#if defined (HAVE_KILL)
kill (getpid (), sig);
#else
raise (sig); /* assume we have raise */
#endif
/* Let the signal that we just sent through. */
#if defined (HAVE_POSIX_SIGNALS)
......@@ -274,13 +289,51 @@ rl_set_signals ()
{
sighandler_cxt dummy;
SigHandler *oh;
#if defined (HAVE_POSIX_SIGNALS)
static int sigmask_set = 0;
static sigset_t bset, oset;
#endif
#if defined (HAVE_POSIX_SIGNALS)
if (rl_catch_signals && sigmask_set == 0)
{
sigemptyset (&bset);
sigaddset (&bset, SIGINT);
sigaddset (&bset, SIGINT);
#if defined (SIGQUIT)
sigaddset (&bset, SIGQUIT);
#endif
#if defined (SIGALRM)
sigaddset (&bset, SIGALRM);
#endif
#if defined (SIGTSTP)
sigaddset (&bset, SIGTSTP);
#endif
#if defined (SIGTTIN)
sigaddset (&bset, SIGTTIN);
#endif
#if defined (SIGTTOU)
sigaddset (&bset, SIGTTOU);
#endif
sigmask_set = 1;
}
#endif /* HAVE_POSIX_SIGNALS */
if (rl_catch_signals && signals_set_flag == 0)
{
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&oset);
sigprocmask (SIG_BLOCK, &bset, &oset);
#endif
rl_maybe_set_sighandler (SIGINT, rl_signal_handler, &old_int);
rl_maybe_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
#if defined (SIGQUIT)
rl_maybe_set_sighandler (SIGQUIT, rl_signal_handler, &old_quit);
#endif
#if defined (SIGALRM)
oh = rl_set_sighandler (SIGALRM, rl_signal_handler, &old_alrm);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (SIGALRM, &old_alrm, &dummy);
......@@ -292,6 +345,7 @@ rl_set_signals ()
if (oh != (SigHandler *)SIG_DFL && (old_alrm.sa_flags & SA_RESTART))
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#endif /* HAVE_POSIX_SIGNALS */
#endif /* SIGALRM */
#if defined (SIGTSTP)
rl_maybe_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
......@@ -306,6 +360,10 @@ rl_set_signals ()
#endif /* SIGTTIN */
signals_set_flag = 1;
#if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
#endif
}
#if defined (SIGWINCH)
......@@ -330,8 +388,12 @@ rl_clear_signals ()
rl_sigaction (SIGINT, &old_int, &dummy);
rl_sigaction (SIGTERM, &old_term, &dummy);
#if defined (SIGQUIT)
rl_sigaction (SIGQUIT, &old_quit, &dummy);
#endif
#if defined (SIGALRM)
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#endif
#if defined (SIGTSTP)
rl_sigaction (SIGTSTP, &old_tstp, &dummy);
......@@ -366,15 +428,17 @@ void
rl_cleanup_after_signal ()
{
_rl_clean_up_for_exit ();
if (rl_deprep_term_function)
(*rl_deprep_term_function) ();
rl_clear_signals ();
rl_clear_pending_input ();
rl_clear_signals ();
}
/* Reset the terminal and readline state after a signal handler returns. */
void
rl_reset_after_signal ()
{
if (rl_prep_term_function)
(*rl_prep_term_function) (_rl_meta_flag);
rl_set_signals ();
}
......@@ -396,7 +460,7 @@ rl_free_line_state ()
_rl_kill_kbd_macro ();
rl_clear_message ();
_rl_init_argument ();
_rl_reset_argument ();
}
#endif /* HANDLE_SIGNALS */
/* terminal.c -- controlling the terminal with termcap. */
/* Copyright (C) 1996 Free Software Foundation, Inc.
/* Copyright (C) 1996-2006 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -21,7 +21,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include "posixstat.h"
......@@ -64,9 +66,25 @@
#include "rlshell.h"
#include "xmalloc.h"
#if defined (__MINGW32__)
# include <windows.h>
# include <wincon.h>
static void _win_get_screensize PARAMS((int *, int *));
#endif
#if defined (__EMX__)
static void _emx_get_screensize PARAMS((int *, int *));
#endif
#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
/* If the calling application sets this to a non-zero value, readline will
use the $LINES and $COLUMNS environment variables to set its idea of the
window size before interrogating the kernel. */
int rl_prefer_env_winsize = 0;
/* **************************************************************** */
/* */
/* Terminal and Termcap */
......@@ -107,9 +125,7 @@ char *_rl_term_IC;
char *_rl_term_dc;
char *_rl_term_DC;
#if defined (HACK_TERMCAP_MOTION)
char *_rl_term_forward_char;
#endif /* HACK_TERMCAP_MOTION */
/* How to go up a line. */
char *_rl_term_up;
......@@ -118,7 +134,7 @@ char *_rl_term_up;
static char *_rl_visible_bell;
/* Non-zero means the terminal can auto-wrap lines. */
int _rl_term_autowrap;
int _rl_term_autowrap = -1;
/* Non-zero means that this terminal has a meta key. */
static int term_has_meta;
......@@ -143,6 +159,9 @@ static char *_rl_term_kh;
static char *_rl_term_kH;
static char *_rl_term_at7; /* @7 */
/* Delete key */
static char *_rl_term_kD;
/* Insert key */
static char *_rl_term_kI;
......@@ -177,6 +196,26 @@ _emx_get_screensize (swp, shp)
}
#endif
#if defined (__MINGW32__)
static void
_win_get_screensize (swp, shp)
int *swp, *shp;
{
HANDLE hConOut;
CONSOLE_SCREEN_BUFFER_INFO scr;
hConOut = GetStdHandle (STD_OUTPUT_HANDLE);
if (hConOut != INVALID_HANDLE_VALUE)
{
if (GetConsoleScreenBufferInfo (hConOut, &scr))
{
*swp = scr.dwSize.X;
*shp = scr.srWindow.Bottom - scr.srWindow.Top + 1;
}
}
}
#endif
/* Get readline's idea of the screen size. TTY is a file descriptor open
to the terminal. If IGNORE_ENV is true, we do not pay attention to the
values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
......@@ -189,26 +228,42 @@ _rl_get_screen_size (tty, ignore_env)
#if defined (TIOCGWINSZ)
struct winsize window_size;
#endif /* TIOCGWINSZ */
int wr, wc;
wr = wc = -1;
#if defined (TIOCGWINSZ)
if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
{
_rl_screenwidth = (int) window_size.ws_col;
_rl_screenheight = (int) window_size.ws_row;
wc = (int) window_size.ws_col;
wr = (int) window_size.ws_row;
}
#endif /* TIOCGWINSZ */
#if defined (__EMX__)
_emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
_emx_get_screensize (&wc, &wr);
#elif defined (__MINGW32__)
_win_get_screensize (&wc, &wr);
#endif
if (ignore_env || rl_prefer_env_winsize == 0)
{
_rl_screenwidth = wc;
_rl_screenheight = wr;
}
else
_rl_screenwidth = _rl_screenheight = -1;
/* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
is unset. */
is unset. If we prefer the environment, check it first before
assigning the value returned by the kernel. */
if (_rl_screenwidth <= 0)
{
if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
_rl_screenwidth = atoi (ss);
if (_rl_screenwidth <= 0)
_rl_screenwidth = wc;
#if !defined (__DJGPP__)
if (_rl_screenwidth <= 0 && term_string_buffer)
_rl_screenwidth = tgetnum ("co");
......@@ -222,6 +277,9 @@ _rl_get_screen_size (tty, ignore_env)
if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
_rl_screenheight = atoi (ss);
if (_rl_screenheight <= 0)
_rl_screenheight = wr;
#if !defined (__DJGPP__)
if (_rl_screenheight <= 0 && term_string_buffer)
_rl_screenheight = tgetnum ("li");
......@@ -250,15 +308,19 @@ void
_rl_set_screen_size (rows, cols)
int rows, cols;
{
if (rows == 0 || cols == 0)
return;
if (_rl_term_autowrap == -1)
_rl_init_terminal_io (rl_terminal_name);
if (rows > 0)
_rl_screenheight = rows;
if (cols > 0)
{
_rl_screenwidth = cols;
if (_rl_term_autowrap == 0)
_rl_screenwidth--;
}
if (rows > 0 || cols > 0)
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
}
......@@ -279,6 +341,12 @@ rl_get_screen_size (rows, cols)
*cols = _rl_screenwidth;
}
void
rl_reset_screen_size ()
{
_rl_get_screen_size (fileno (rl_instream), 0);
}
void
rl_resize_terminal ()
{
......@@ -311,6 +379,7 @@ static struct _tc_string tc_strings[] =
{ "ei", &_rl_term_ei },
{ "ic", &_rl_term_ic },
{ "im", &_rl_term_im },
{ "kD", &_rl_term_kD }, /* delete */
{ "kH", &_rl_term_kH }, /* home down ?? */
{ "kI", &_rl_term_kI }, /* insert */
{ "kd", &_rl_term_kd },
......@@ -323,9 +392,7 @@ static struct _tc_string tc_strings[] =
{ "le", &_rl_term_backspace },
{ "mm", &_rl_term_mm },
{ "mo", &_rl_term_mo },
#if defined (HACK_TERMCAP_MOTION)
{ "nd", &_rl_term_forward_char },
#endif
{ "pc", &_rl_term_pc },
{ "up", &_rl_term_up },
{ "vb", &_rl_visible_bell },
......@@ -344,7 +411,7 @@ get_term_capabilities (bp)
#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
register int i;
for (i = 0; i < (int) NUM_TC_STRINGS; i++)
for (i = 0; i < NUM_TC_STRINGS; i++)
*(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
#endif
tcap_initialized = 1;
......@@ -361,7 +428,6 @@ _rl_init_terminal_io (terminal_name)
term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
_rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
tty = rl_instream ? fileno (rl_instream) : 0;
_rl_screenwidth = _rl_screenheight = 0;
if (term == 0)
term = "dumb";
......@@ -394,12 +460,17 @@ _rl_init_terminal_io (terminal_name)
_rl_term_autowrap = 0; /* used by _rl_get_screen_size */
/* Allow calling application to set default height and width, using
rl_set_screen_size */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
{
#if defined (__EMX__)
_emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
_rl_screenwidth--;
#else /* !__EMX__ */
_rl_get_screen_size (tty, 0);
#endif /* !__EMX__ */
}
/* Defaults. */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
......@@ -410,24 +481,22 @@ _rl_init_terminal_io (terminal_name)
/* Everything below here is used by the redisplay code (tputs). */
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
_rl_term_cr = (char*) "\r";
_rl_term_cr = "\r";
_rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
_rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
_rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
_rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL;
_rl_term_kh = _rl_term_kH = _rl_term_kI = _rl_term_kD = (char *)NULL;
_rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
_rl_term_mm = _rl_term_mo = (char *)NULL;
_rl_term_ve = _rl_term_vs = (char *)NULL;
#if defined (HACK_TERMCAP_MOTION)
term_forward_char = (char *)NULL;
#endif
_rl_term_forward_char = (char *)NULL;
_rl_terminal_can_insert = term_has_meta = 0;
/* Reasonable defaults for tgoto(). Readline currently only uses
tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
change that later... */
PC = '\0';
BC = _rl_term_backspace = (char*) "\b";
BC = _rl_term_backspace = "\b";
UP = _rl_term_up;
return 0;
......@@ -442,10 +511,13 @@ _rl_init_terminal_io (terminal_name)
UP = _rl_term_up;
if (!_rl_term_cr)
_rl_term_cr = (char*) "\r";
_rl_term_cr = "\r";
_rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
/* Allow calling application to set default height and width, using
rl_set_screen_size */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
_rl_get_screen_size (tty, 0);
/* "An application program can assume that the terminal can do
......@@ -491,6 +563,8 @@ bind_termcap_arrow_keys (map)
rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete);
_rl_keymap = xkeymap;
}
......@@ -502,7 +576,7 @@ rl_get_termcap (cap)
if (tcap_initialized == 0)
return ((char *)NULL);
for (i = 0; i < (int) NUM_TC_STRINGS; i++)
for (i = 0; i < NUM_TC_STRINGS; i++)
{
if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
return *(tc_strings[i].tc_value);
......@@ -516,6 +590,7 @@ int
rl_reset_terminal (terminal_name)
const char *terminal_name;
{
_rl_screenwidth = _rl_screenheight = 0;
_rl_init_terminal_io (terminal_name);
return 0;
}
......
/* text.c -- text handling commands for readline. */
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -21,7 +21,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
......@@ -60,6 +62,11 @@
static int rl_change_case PARAMS((int, int));
static int _rl_char_search PARAMS((int, int, int));
#if defined (READLINE_CALLBACKS)
static int _rl_insert_next_callback PARAMS((_rl_callback_generic_arg *));
static int _rl_char_search_callback PARAMS((_rl_callback_generic_arg *));
#endif
/* **************************************************************** */
/* */
/* Insert and Delete */
......@@ -402,7 +409,8 @@ rl_backward (count, key)
/* Move to the beginning of the line. */
int
rl_beg_of_line (int count __attribute__((unused)), int key __attribute__((unused)))
rl_beg_of_line (count, key)
int count, key;
{
rl_point = 0;
return 0;
......@@ -410,14 +418,14 @@ rl_beg_of_line (int count __attribute__((unused)), int key __attribute__((unused
/* Move to the end of the line. */
int
rl_end_of_line (int count __attribute__((unused)), int key __attribute__((unused)))
rl_end_of_line (count, key)
int count, key;
{
rl_point = rl_end;
return 0;
}
/* XXX - these might need changes for multibyte characters */
/* Move forward a word. We do what Emacs does. */
/* Move forward a word. We do what Emacs does. Handles multibyte chars. */
int
rl_forward_word (count, key)
int count, key;
......@@ -434,68 +442,80 @@ rl_forward_word (count, key)
/* If we are not in a word, move forward until we are in one.
Then, move forward until we hit a non-alphabetic character. */
c = rl_line_buffer[rl_point];
if (rl_alphabetic (c) == 0)
c = _rl_char_value (rl_line_buffer, rl_point);
if (_rl_walphabetic (c) == 0)
{
while (++rl_point < rl_end)
rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
while (rl_point < rl_end)
{
c = rl_line_buffer[rl_point];
if (rl_alphabetic (c))
c = _rl_char_value (rl_line_buffer, rl_point);
if (_rl_walphabetic (c))
break;
rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
}
}
if (rl_point == rl_end)
return 0;
while (++rl_point < rl_end)
rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
while (rl_point < rl_end)
{
c = rl_line_buffer[rl_point];
if (rl_alphabetic (c) == 0)
c = _rl_char_value (rl_line_buffer, rl_point);
if (_rl_walphabetic (c) == 0)
break;
rl_point = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
}
--count;
}
return 0;
}
/* Move backward a word. We do what Emacs does. */
/* Move backward a word. We do what Emacs does. Handles multibyte chars. */
int
rl_backward_word (count, key)
int count, key;
{
int c;
int c, p;
if (count < 0)
return (rl_forward_word (-count, key));
while (count)
{
if (!rl_point)
if (rl_point == 0)
return 0;
/* Like rl_forward_word (), except that we look at the characters
just before point. */
c = rl_line_buffer[rl_point - 1];
if (rl_alphabetic (c) == 0)
p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
c = _rl_char_value (rl_line_buffer, p);
if (_rl_walphabetic (c) == 0)
{
while (--rl_point)
rl_point = p;
while (rl_point > 0)
{
c = rl_line_buffer[rl_point - 1];
if (rl_alphabetic (c))
p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
c = _rl_char_value (rl_line_buffer, p);
if (_rl_walphabetic (c))
break;
rl_point = p;
}
}
while (rl_point)
{
c = rl_line_buffer[rl_point - 1];
if (rl_alphabetic (c) == 0)
p = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
c = _rl_char_value (rl_line_buffer, p);
if (_rl_walphabetic (c) == 0)
break;
else
--rl_point;
rl_point = p;
}
--count;
......@@ -506,7 +526,8 @@ rl_backward_word (count, key)
/* Clear the current line. Numeric argument to C-l does this. */
int
rl_refresh_line (int count __attribute__((unused)), int key __attribute__((unused)))
rl_refresh_line (ignore1, ignore2)
int ignore1, ignore2;
{
int curr_line;
......@@ -544,7 +565,8 @@ rl_clear_screen (count, key)
}
int
rl_arrow_keys (int count, int c __attribute__((unused)))
rl_arrow_keys (count, c)
int count, c;
{
int ch;
......@@ -592,7 +614,7 @@ rl_arrow_keys (int count, int c __attribute__((unused)))
#ifdef HANDLE_MULTIBYTE
static char pending_bytes[MB_LEN_MAX];
static int pending_bytes_length = 0;
static mbstate_t ps;
static mbstate_t ps = {0};
#endif
/* Insert the character C at the current location, moving point forward.
......@@ -750,10 +772,8 @@ _rl_insert_char (count, c)
return 0;
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX == 1 || rl_byte_oriented)
{
#endif
/* We are inserting a single character.
If there is pending input, then make a string of all of the
pending characters that are bound to rl_insert, and insert
......@@ -769,8 +789,8 @@ _rl_insert_char (count, c)
str[0] = c;
rl_insert_text (str);
}
#if defined (HANDLE_MULTIBYTE)
}
#if defined (HANDLE_MULTIBYTE)
else
{
rl_insert_text (incoming);
......@@ -827,29 +847,67 @@ rl_insert (count, c)
}
/* Insert the next typed character verbatim. */
int
rl_quoted_insert (int count, int key __attribute__((unused)))
static int
_rl_insert_next (count)
int count;
{
int c;
#if defined (HANDLE_SIGNALS)
_rl_disable_tty_signals ();
#endif
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_SIGNALS)
if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
_rl_restore_tty_signals ();
#endif
return (_rl_insert_char (count, c));
}
#if defined (READLINE_CALLBACKS)
static int
_rl_insert_next_callback (data)
_rl_callback_generic_arg *data;
{
int count;
count = data->count;
/* Deregister function, let rl_callback_read_char deallocate data */
_rl_callback_func = 0;
_rl_want_redisplay = 1;
return _rl_insert_next (count);
}
#endif
int
rl_quoted_insert (count, key)
int count, key;
{
/* Let's see...should the callback interface futz with signal handling? */
#if defined (HANDLE_SIGNALS)
if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
_rl_disable_tty_signals ();
#endif
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_func = _rl_insert_next_callback;
return (0);
}
#endif
return _rl_insert_next (count);
}
/* Insert a tab character. */
int
rl_tab_insert (int count, int key __attribute__((unused)))
rl_tab_insert (count, key)
int count, key;
{
return (_rl_insert_char (count, '\t'));
}
......@@ -858,7 +916,8 @@ rl_tab_insert (int count, int key __attribute__((unused)))
KEY is the key that invoked this command. I guess it could have
meaning in the future. */
int
rl_newline (int count __attribute__((unused)), int key __attribute__((unused)))
rl_newline (count, key)
int count, key;
{
rl_done = 1;
......@@ -891,8 +950,8 @@ rl_newline (int count __attribute__((unused)), int key __attribute__((unused)))
is just a stub, you bind keys to it and the code in _rl_dispatch ()
is special cased. */
int
rl_do_lowercase_version (int count __attribute__((unused)),
int key __attribute__((unused)))
rl_do_lowercase_version (ignore1, ignore2)
int ignore1, ignore2;
{
return 0;
}
......@@ -979,43 +1038,17 @@ _rl_rubout_char (count, key)
return -1;
}
orig_point = rl_point;
if (count > 1 || rl_explicit_arg)
{
orig_point = rl_point;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_backward_char (count, key);
else
#endif
rl_backward_byte (count, key);
rl_kill_text (orig_point, rl_point);
}
else
else if (MB_CUR_MAX == 1 || rl_byte_oriented)
{
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX == 1 || rl_byte_oriented)
{
#endif
c = rl_line_buffer[--rl_point];
rl_delete_text (rl_point, rl_point + 1);
#if defined (HANDLE_MULTIBYTE)
}
else
{
int orig_point2;
orig_point2 = rl_point;
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
c = rl_line_buffer[rl_point];
rl_delete_text (rl_point, orig_point2);
}
#endif /* HANDLE_MULTIBYTE */
/* I don't think that the hack for end of line is needed for
multibyte chars. */
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX == 1 || rl_byte_oriented)
#endif
rl_delete_text (rl_point, orig_point);
/* The erase-at-end-of-line hack is of questionable merit now. */
if (rl_point == rl_end && ISPRINT (c) && _rl_last_c_pos)
{
int l;
......@@ -1023,6 +1056,11 @@ _rl_rubout_char (count, key)
_rl_erase_at_end_of_line (l);
}
}
else
{
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
rl_delete_text (rl_point, orig_point);
}
return 0;
}
......@@ -1033,7 +1071,7 @@ int
rl_delete (count, key)
int count, key;
{
int r;
int xpoint;
if (count < 0)
return (_rl_rubout_char (-count, key));
......@@ -1046,28 +1084,21 @@ rl_delete (count, key)
if (count > 1 || rl_explicit_arg)
{
int orig_point = rl_point;
#if defined (HANDLE_MULTIBYTE)
xpoint = rl_point;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_forward_char (count, key);
else
#endif
rl_forward_byte (count, key);
r = rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
return r;
rl_kill_text (xpoint, rl_point);
rl_point = xpoint;
}
else
{
int new_point;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
new_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
else
new_point = rl_point + 1;
return (rl_delete_text (rl_point, new_point));
xpoint = MB_NEXTCHAR (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
rl_delete_text (rl_point, xpoint);
}
return 0;
}
/* Delete the character under the cursor, unless the insertion
......@@ -1086,8 +1117,8 @@ rl_rubout_or_delete (count, key)
/* Delete all spaces and tabs around point. */
int
rl_delete_horizontal_space (int count __attribute__((unused)),
int key __attribute__((unused)))
rl_delete_horizontal_space (count, ignore)
int count, ignore;
{
int start = rl_point;
......@@ -1104,6 +1135,10 @@ rl_delete_horizontal_space (int count __attribute__((unused)),
rl_delete_text (start, rl_point);
rl_point = start;
}
if (rl_point < 0)
rl_point = 0;
return 0;
}
......@@ -1127,13 +1162,14 @@ rl_delete_or_show_completions (count, key)
/* Turn the current line into a comment in shell history.
A K*rn shell style function. */
int
rl_insert_comment (int count __attribute__((unused)), int key)
rl_insert_comment (count, key)
int count, key;
{
char *rl_comment_text;
int rl_comment_len;
rl_beg_of_line (1, key);
rl_comment_text = _rl_comment_begin ? _rl_comment_begin : (char*) RL_COMMENT_BEGIN_DEFAULT;
rl_comment_text = _rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT;
if (rl_explicit_arg == 0)
rl_insert_text (rl_comment_text);
......@@ -1165,21 +1201,24 @@ rl_insert_comment (int count __attribute__((unused)), int key)
/* Uppercase the word at point. */
int
rl_upcase_word (int count, int key __attribute__((unused)))
rl_upcase_word (count, key)
int count, key;
{
return (rl_change_case (count, UpCase));
}
/* Lowercase the word at point. */
int
rl_downcase_word (int count, int key __attribute__((unused)))
rl_downcase_word (count, key)
int count, key;
{
return (rl_change_case (count, DownCase));
}
/* Upcase the first letter, downcase the rest. */
int
rl_capitalize_word (int count, int key __attribute__((unused)))
rl_capitalize_word (count, key)
int count, key;
{
return (rl_change_case (count, CapCase));
}
......@@ -1193,42 +1232,80 @@ static int
rl_change_case (count, op)
int count, op;
{
register int start, end;
int inword, c;
int start, next, end;
int inword, c, nc, nop;
#if defined (HANDLE_MULTIBYTE)
wchar_t wc, nwc;
char mb[MB_LEN_MAX+1];
int mlen;
mbstate_t mps;
#endif
start = rl_point;
rl_forward_word (count, 0);
end = rl_point;
if (op != UpCase && op != DownCase && op != CapCase)
{
rl_ding ();
return -1;
}
if (count < 0)
SWAP (start, end);
#if defined (HANDLE_MULTIBYTE)
memset (&mps, 0, sizeof (mbstate_t));
#endif
/* We are going to modify some text, so let's prepare to undo it. */
rl_modifying (start, end);
for (inword = 0; start < end; start++)
inword = 0;
while (start < end)
{
c = rl_line_buffer[start];
switch (op)
{
case UpCase:
rl_line_buffer[start] = _rl_to_upper (c);
break;
c = _rl_char_value (rl_line_buffer, start);
/* This assumes that the upper and lower case versions are the same width. */
next = MB_NEXTCHAR (rl_line_buffer, start, 1, MB_FIND_NONZERO);
case DownCase:
rl_line_buffer[start] = _rl_to_lower (c);
break;
case CapCase:
rl_line_buffer[start] = (inword == 0) ? _rl_to_upper (c) : _rl_to_lower (c);
inword = rl_alphabetic (rl_line_buffer[start]);
break;
if (_rl_walphabetic (c) == 0)
{
inword = 0;
start = next;
continue;
}
default:
rl_ding ();
return -1;
if (op == CapCase)
{
nop = inword ? DownCase : UpCase;
inword = 1;
}
else
nop = op;
if (MB_CUR_MAX == 1 || rl_byte_oriented || isascii (c))
{
nc = (nop == UpCase) ? _rl_to_upper (c) : _rl_to_lower (c);
rl_line_buffer[start] = nc;
}
#if defined (HANDLE_MULTIBYTE)
else
{
mbrtowc (&wc, rl_line_buffer + start, end - start, &mps);
nwc = (nop == UpCase) ? _rl_to_wupper (wc) : _rl_to_wlower (wc);
if (nwc != wc) /* just skip unchanged characters */
{
mlen = wcrtomb (mb, nwc, &mps);
if (mlen > 0)
mb[mlen] = '\0';
/* Assume the same width */
strncpy (rl_line_buffer + start, mb, mlen);
}
}
#endif
start = next;
}
rl_point = end;
return 0;
}
......@@ -1303,15 +1380,16 @@ rl_transpose_words (count, key)
/* Transpose the characters at point. If point is at the end of the line,
then transpose the characters before point. */
int
rl_transpose_chars (int count, int key __attribute__((unused)))
rl_transpose_chars (count, key)
int count, key;
{
#if defined (HANDLE_MULTIBYTE)
char *dummy;
int i, prev_point;
int i;
#else
char dummy[2];
#endif
int char_length;
int char_length, prev_point;
if (count == 0)
return 0;
......@@ -1326,20 +1404,12 @@ rl_transpose_chars (int count, int key __attribute__((unused)))
if (rl_point == rl_end)
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
--rl_point;
rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
count = 1;
}
#if defined (HANDLE_MULTIBYTE)
prev_point = rl_point;
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
#endif
rl_point--;
rl_point = MB_PREVCHAR (rl_line_buffer, rl_point, MB_FIND_NONZERO);
#if defined (HANDLE_MULTIBYTE)
char_length = prev_point - rl_point;
......@@ -1473,15 +1543,51 @@ _rl_char_search (count, fdir, bdir)
}
#endif /* !HANDLE_MULTIBYTE */
#if defined (READLINE_CALLBACKS)
static int
_rl_char_search_callback (data)
_rl_callback_generic_arg *data;
{
_rl_callback_func = 0;
_rl_want_redisplay = 1;
return (_rl_char_search (data->count, data->i1, data->i2));
}
#endif
int
rl_char_search (int count, int key __attribute__((unused)))
rl_char_search (count, key)
int count, key;
{
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_data->i1 = FFIND;
_rl_callback_data->i2 = BFIND;
_rl_callback_func = _rl_char_search_callback;
return (0);
}
#endif
return (_rl_char_search (count, FFIND, BFIND));
}
int
rl_backward_char_search (int count, int key __attribute__((unused)))
rl_backward_char_search (count, key)
int count, key;
{
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_data->i1 = BFIND;
_rl_callback_data->i2 = FFIND;
_rl_callback_func = _rl_char_search_callback;
return (0);
}
#endif
return (_rl_char_search (count, BFIND, FFIND));
}
......@@ -1505,15 +1611,16 @@ _rl_set_mark_at_pos (position)
/* A bindable command to set the mark. */
int
rl_set_mark (int count, int key __attribute__((unused)))
rl_set_mark (count, key)
int count, key;
{
return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
}
/* Exchange the position of mark and point. */
int
rl_exchange_point_and_mark (int count __attribute__((unused)),
int key __attribute__((unused)))
rl_exchange_point_and_mark (count, key)
int count, key;
{
if (rl_mark > rl_end)
rl_mark = -1;
......
......@@ -19,9 +19,9 @@
along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_UNISTD_H)
# ifdef _MINIX
......@@ -43,7 +43,9 @@
#endif /* HAVE_STDLIB_H */
#include <sys/types.h>
#if defined (HAVE_PWD_H)
#include <pwd.h>
#endif
#include "tilde.h"
......@@ -54,8 +56,12 @@ static void *xmalloc (), *xrealloc ();
#endif /* TEST || STATIC_MALLOC */
#if !defined (HAVE_GETPW_DECLS)
# if defined (HAVE_GETPWUID)
extern struct passwd *getpwuid PARAMS((uid_t));
# endif
# if defined (HAVE_GETPWNAM)
extern struct passwd *getpwnam PARAMS((const char *));
# endif
#endif /* !HAVE_GETPW_DECLS */
#if !defined (savestring)
......@@ -190,7 +196,7 @@ tilde_expand (string)
int result_size, result_index;
result_index = result_size = 0;
if ((result = strchr (string, '~')))
if (result = strchr (string, '~'))
result = (char *)xmalloc (result_size = (strlen (string) + 16));
else
result = (char *)xmalloc (result_size = (strlen (string) + 1));
......@@ -277,6 +283,39 @@ isolate_tilde_prefix (fname, lenp)
return ret;
}
#if 0
/* Public function to scan a string (FNAME) beginning with a tilde and find
the portion of the string that should be passed to the tilde expansion
function. Right now, it just calls tilde_find_suffix and allocates new
memory, but it can be expanded to do different things later. */
char *
tilde_find_word (fname, flags, lenp)
const char *fname;
int flags, *lenp;
{
int x;
char *r;
x = tilde_find_suffix (fname);
if (x == 0)
{
r = savestring (fname);
if (lenp)
*lenp = 0;
}
else
{
r = (char *)xmalloc (1 + x);
strncpy (r, fname, x);
r[x] = '\0';
if (lenp)
*lenp = x;
}
return r;
}
#endif
/* Return a string that is PREFIX concatenated with SUFFIX starting at
SUFFIND. */
static char *
......@@ -347,7 +386,11 @@ tilde_expand_word (filename)
/* No preexpansion hook, or the preexpansion hook failed. Look in the
password database. */
dirname = (char *)NULL;
#if defined (HAVE_GETPWNAM)
user_entry = getpwnam (username);
#else
user_entry = 0;
#endif
if (user_entry == 0)
{
/* If the calling program has a special syntax for expanding tildes,
......@@ -361,19 +404,20 @@ tilde_expand_word (filename)
free (expansion);
}
}
free (username);
/* If we don't have a failure hook, or if the failure hook did not
expand the tilde, return a copy of what we were passed. */
if (dirname == 0)
dirname = savestring (filename);
}
#if defined (HAVE_GETPWENT)
else
{
free (username);
dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len);
}
#endif
free (username);
#if defined (HAVE_GETPWENT)
endpwent ();
#endif
return (dirname);
}
......
......@@ -71,6 +71,9 @@ extern char *tilde_expand PARAMS((const char *));
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
extern char *tilde_expand_word PARAMS((const char *));
/* Find the portion of the string beginning with ~ that should be expanded. */
extern char *tilde_find_word PARAMS((const char *, int, int *));
#ifdef __cplusplus
}
#endif
......
/* readline.c -- a general facility for reading lines of input
with emacs style editing and completion. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987, 1989, 1992, 2006 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -22,7 +22,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
......@@ -48,6 +50,8 @@
#include "rlprivate.h"
#include "xmalloc.h"
extern void replace_history_data PARAMS((int, histdata_t *, histdata_t *));
/* Non-zero tells rl_delete_text and rl_insert_text to not add to
the undo list. */
int _rl_doing_an_undo = 0;
......@@ -64,19 +68,35 @@ UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
/* */
/* **************************************************************** */
/* Remember how to undo something. Concatenate some undos if that
seems right. */
void
rl_add_undo (what, start, end, text)
static UNDO_LIST *
alloc_undo_entry (what, start, end, text)
enum undo_code what;
int start, end;
char *text;
{
UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
UNDO_LIST *temp;
temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
temp->what = what;
temp->start = start;
temp->end = end;
temp->text = text;
temp->next = (UNDO_LIST *)NULL;
return temp;
}
/* Remember how to undo something. Concatenate some undos if that
seems right. */
void
rl_add_undo (what, start, end, text)
enum undo_code what;
int start, end;
char *text;
{
UNDO_LIST *temp;
temp = alloc_undo_entry (what, start, end, text);
temp->next = rl_undo_list;
rl_undo_list = temp;
}
......@@ -85,9 +105,12 @@ rl_add_undo (what, start, end, text)
void
rl_free_undo_list ()
{
UNDO_LIST *release, *orig_list;
orig_list = rl_undo_list;
while (rl_undo_list)
{
UNDO_LIST *release = rl_undo_list;
release = rl_undo_list;
rl_undo_list = rl_undo_list->next;
if (release->what == UNDO_DELETE)
......@@ -96,6 +119,43 @@ rl_free_undo_list ()
free (release);
}
rl_undo_list = (UNDO_LIST *)NULL;
replace_history_data (-1, (histdata_t *)orig_list, (histdata_t *)NULL);
}
UNDO_LIST *
_rl_copy_undo_entry (entry)
UNDO_LIST *entry;
{
UNDO_LIST *new;
new = alloc_undo_entry (entry->what, entry->start, entry->end, (char *)NULL);
new->text = entry->text ? savestring (entry->text) : 0;
return new;
}
UNDO_LIST *
_rl_copy_undo_list (head)
UNDO_LIST *head;
{
UNDO_LIST *list, *new, *roving, *c;
list = head;
new = 0;
while (list)
{
c = _rl_copy_undo_entry (list);
if (new == 0)
roving = new = c;
else
{
roving->next = c;
roving = roving->next;
}
list = list->next;
}
roving->next = 0;
return new;
}
/* Undo the next thing in the list. Return 0 if there
......@@ -159,6 +219,8 @@ rl_do_undo ()
release = rl_undo_list;
rl_undo_list = rl_undo_list->next;
replace_history_data (-1, (histdata_t *)release, (histdata_t *)rl_undo_list);
free (release);
}
while (waiting_for_begin);
......@@ -175,7 +237,7 @@ _rl_fix_last_undo_of_type (type, start, end)
for (rl = rl_undo_list; rl; rl = rl->next)
{
if (rl->what == (unsigned int) type)
if (rl->what == type)
{
rl->start = start;
rl->end = end;
......@@ -226,7 +288,8 @@ rl_modifying (start, end)
/* Revert the current line to its previous state. */
int
rl_revert_line (int count __attribute__((unused)), int key __attribute__((unused)))
rl_revert_line (count, key)
int count, key;
{
if (!rl_undo_list)
rl_ding ();
......@@ -234,13 +297,19 @@ rl_revert_line (int count __attribute__((unused)), int key __attribute__((unuse
{
while (rl_undo_list)
rl_do_undo ();
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
rl_point = rl_mark = 0; /* rl_end should be set correctly */
#endif
}
return 0;
}
/* Do some undoing of things that were done. */
int
rl_undo_command (int count, int key __attribute__((unused)))
rl_undo_command (count, key)
int count, key;
{
if (count < 0)
return 0; /* Nothing to do. */
......
/* util.c -- readline utility functions */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -21,7 +21,9 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
......@@ -42,6 +44,7 @@
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
#if defined (TIOCSTAT_IN_SYS_IOCTL)
# include <sys/ioctl.h>
......@@ -76,13 +79,29 @@ rl_alphabetic (c)
strchr (pathname_alphabetic_chars, c) != NULL);
}
#if defined (HANDLE_MULTIBYTE)
int
_rl_walphabetic (wc)
wchar_t wc;
{
int c;
if (iswalnum (wc))
return (1);
c = wc & 0177;
return (_rl_allow_pathname_alphabetic_chars &&
strchr (pathname_alphabetic_chars, c) != NULL);
}
#endif
/* How to abort things. */
int
_rl_abort_internal ()
{
rl_ding ();
rl_clear_message ();
_rl_init_argument ();
_rl_reset_argument ();
rl_clear_pending_input ();
RL_UNSETSTATE (RL_STATE_MACRODEF);
......@@ -95,13 +114,15 @@ _rl_abort_internal ()
}
int
rl_abort (int count __attribute__((unused)), int key __attribute__((unused)))
rl_abort (count, key)
int count, key;
{
return (_rl_abort_internal ());
}
int
rl_tty_status (int count __attribute__((unused)), int key __attribute__((unused)))
rl_tty_status (count, key)
int count, key;
{
#if defined (TIOCSTAT)
ioctl (1, TIOCSTAT, (char *)0);
......@@ -150,7 +171,8 @@ rl_extend_line_buffer (len)
/* A function for simple tilde expansion. */
int
rl_tilde_expand (int ignore __attribute__((unused)), int key __attribute__((unused)))
rl_tilde_expand (ignore, key)
int ignore, key;
{
register int start, end;
char *homedir, *temp;
......
......@@ -130,7 +130,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, rl_revert_line }, /* U */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* V */
{ ISFUNC, rl_vi_next_word }, /* W */
{ ISFUNC, rl_rubout }, /* X */
{ ISFUNC, rl_vi_rubout }, /* X */
{ ISFUNC, rl_vi_yank_to }, /* Y */
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Z */
......
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
......@@ -31,7 +31,9 @@
#if defined (VI_MODE)
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
......@@ -88,6 +90,7 @@ static int _rl_vi_last_arg_sign = 1;
static int _rl_vi_last_motion;
#if defined (HANDLE_MULTIBYTE)
static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
static int _rl_vi_last_search_mblen;
#else
static int _rl_vi_last_search_char;
#endif
......@@ -105,15 +108,35 @@ static int vi_mark_chars['z' - 'a' + 1];
static void _rl_vi_stuff_insert PARAMS((int));
static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
static void _rl_vi_backup PARAMS((void));
static int _rl_vi_arg_dispatch PARAMS((int));
static int rl_digit_loop1 PARAMS((void));
static int _rl_vi_set_mark PARAMS((void));
static int _rl_vi_goto_mark PARAMS((void));
static void _rl_vi_append_forward PARAMS((int));
static int _rl_vi_callback_getchar PARAMS((char *, int));
#if defined (READLINE_CALLBACKS)
static int _rl_vi_callback_set_mark PARAMS((_rl_callback_generic_arg *));
static int _rl_vi_callback_goto_mark PARAMS((_rl_callback_generic_arg *));
static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *));
static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *));
#endif
void
_rl_vi_initialize_line ()
{
register int i;
for (i = 0; i < (int) (sizeof (vi_mark_chars) / sizeof (int)); i++)
for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
vi_mark_chars[i] = -1;
RL_UNSETSTATE(RL_STATE_VICMDONCE);
}
void
......@@ -166,7 +189,8 @@ _rl_vi_stuff_insert (count)
redo a text modification command. The default for _rl_vi_last_command
puts you back into insert mode. */
int
rl_vi_redo (int count, int c __attribute__((unused)))
rl_vi_redo (count, c)
int count, c;
{
int r;
......@@ -185,7 +209,16 @@ rl_vi_redo (int count, int c __attribute__((unused)))
_rl_vi_stuff_insert (count);
/* And back up point over the last character inserted. */
if (rl_point > 0)
rl_point--;
_rl_vi_backup ();
}
/* Ditto for redoing an insert with `a', but move forward a character first
like the `a' command does. */
else if (_rl_vi_last_command == 'a' && vi_insert_buffer && *vi_insert_buffer)
{
_rl_vi_append_forward ('a');
_rl_vi_stuff_insert (count);
if (rl_point > 0)
_rl_vi_backup ();
}
else
r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
......@@ -204,7 +237,8 @@ rl_vi_undo (count, key)
/* Yank the nth arg from the previous line into this line at point. */
int
rl_vi_yank_arg (int count, int key __attribute__((unused)))
rl_vi_yank_arg (count, key)
int count, key;
{
/* Readline thinks that the first word on a line is the 0th, while vi
thinks the first word on a line is the 1st. Compensate. */
......@@ -268,10 +302,12 @@ rl_vi_search (count, key)
switch (key)
{
case '?':
_rl_free_saved_history_line ();
rl_noninc_forward_search (count, key);
break;
case '/':
_rl_free_saved_history_line ();
rl_noninc_reverse_search (count, key);
break;
......@@ -284,7 +320,8 @@ rl_vi_search (count, key)
/* Completion, from vi's point of view. */
int
rl_vi_complete (int ignore __attribute__((unused)), int key)
rl_vi_complete (ignore, key)
int ignore, key;
{
if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
{
......@@ -310,7 +347,8 @@ rl_vi_complete (int ignore __attribute__((unused)), int key)
/* Tilde expansion for vi mode. */
int
rl_vi_tilde_expand (int ignore __attribute__((unused)), int key)
rl_vi_tilde_expand (ignore, key)
int ignore, key;
{
rl_tilde_expand (0, key);
rl_vi_start_inserting (key, 1, rl_arg_sign);
......@@ -380,7 +418,8 @@ rl_vi_end_word (count, key)
/* Move forward a word the way that 'W' does. */
int
rl_vi_fWord (int count, int ignore __attribute__((unused)))
rl_vi_fWord (count, ignore)
int count, ignore;
{
while (count-- && rl_point < (rl_end - 1))
{
......@@ -396,7 +435,8 @@ rl_vi_fWord (int count, int ignore __attribute__((unused)))
}
int
rl_vi_bWord (int count, int ignore __attribute__((unused)))
rl_vi_bWord (count, ignore)
int count, ignore;
{
while (count-- && rl_point > 0)
{
......@@ -419,7 +459,8 @@ rl_vi_bWord (int count, int ignore __attribute__((unused)))
}
int
rl_vi_eWord(int count, int ignore __attribute__((unused)))
rl_vi_eWord (count, ignore)
int count, ignore;
{
while (count-- && rl_point < (rl_end - 1))
{
......@@ -449,7 +490,8 @@ rl_vi_eWord(int count, int ignore __attribute__((unused)))
}
int
rl_vi_fword (int count, int ignore __attribute__((unused)))
rl_vi_fword (count, ignore)
int count, ignore;
{
while (count-- && rl_point < (rl_end - 1))
{
......@@ -474,7 +516,8 @@ rl_vi_fword (int count, int ignore __attribute__((unused)))
}
int
rl_vi_bword (int count, int ignore __attribute__((unused)))
rl_vi_bword (count, ignore)
int count, ignore;
{
while (count-- && rl_point > 0)
{
......@@ -512,7 +555,8 @@ rl_vi_bword (int count, int ignore __attribute__((unused)))
}
int
rl_vi_eword (int count, int ignore __attribute__((unused)))
rl_vi_eword (count, ignore)
int count, ignore;
{
while (count-- && rl_point < rl_end - 1)
{
......@@ -536,34 +580,46 @@ rl_vi_eword (int count, int ignore __attribute__((unused)))
}
int
rl_vi_insert_beg (int count __attribute__((unused)), int key)
rl_vi_insert_beg (count, key)
int count, key;
{
rl_beg_of_line (1, key);
rl_vi_insertion_mode (1, key);
return (0);
}
int
rl_vi_append_mode (int count __attribute__((unused)), int key)
static void
_rl_vi_append_forward (key)
int key;
{
int point;
if (rl_point < rl_end)
{
if (MB_CUR_MAX == 1 || rl_byte_oriented)
rl_point++;
else
{
int point = rl_point;
point = rl_point;
rl_forward_char (1, key);
if (point == rl_point)
rl_point = rl_end;
}
}
rl_vi_insertion_mode (1, key);
}
int
rl_vi_append_mode (count, key)
int count, key;
{
_rl_vi_append_forward (key);
rl_vi_start_inserting (key, 1, rl_arg_sign);
return (0);
}
int
rl_vi_append_eol (int count __attribute__((unused)), int key)
rl_vi_append_eol (count, key)
int count, key;
{
rl_end_of_line (1, key);
rl_vi_append_mode (1, key);
......@@ -572,7 +628,8 @@ rl_vi_append_eol (int count __attribute__((unused)), int key)
/* What to do in the case of C-d. */
int
rl_vi_eof_maybe (int count __attribute__((unused)), int c __attribute__((unused)))
rl_vi_eof_maybe (count, c)
int count, c;
{
return (rl_newline (1, '\n'));
}
......@@ -582,7 +639,8 @@ rl_vi_eof_maybe (int count __attribute__((unused)), int c __attribute__((unused)
/* Switching from one mode to the other really just involves
switching keymaps. */
int
rl_vi_insertion_mode (int count __attribute__((unused)), int key)
rl_vi_insertion_mode (count, key)
int count, key;
{
_rl_keymap = vi_insertion_keymap;
_rl_vi_last_key_before_insert = key;
......@@ -595,7 +653,7 @@ _rl_vi_save_insert (up)
{
int len, start, end;
if (up == 0)
if (up == 0 || up->what != UNDO_INSERT)
{
if (vi_insert_buffer_size >= 1)
vi_insert_buffer[0] = '\0';
......@@ -644,13 +702,21 @@ _rl_vi_done_inserting ()
}
int
rl_vi_movement_mode (int count __attribute__((unused)), int key)
rl_vi_movement_mode (count, key)
int count, key;
{
if (rl_point > 0)
rl_backward_char (1, key);
_rl_keymap = vi_movement_keymap;
_rl_vi_done_inserting ();
/* This is how POSIX.2 says `U' should behave -- everything up until the
first time you go into command mode should not be undone. */
if (RL_ISSTATE (RL_STATE_VICMDONCE) == 0)
rl_free_undo_list ();
RL_SETSTATE (RL_STATE_VICMDONCE);
return (0);
}
......@@ -672,7 +738,7 @@ _rl_vi_change_mbchar_case (count)
{
wchar_t wc;
char mb[MB_LEN_MAX+1];
int local_mblen;
int mlen, p;
mbstate_t ps;
memset (&ps, 0, sizeof (mbstate_t));
......@@ -695,11 +761,14 @@ _rl_vi_change_mbchar_case (count)
/* Vi is kind of strange here. */
if (wc)
{
local_mblen = wcrtomb (mb, wc, &ps);
if (local_mblen >= 0)
mb[local_mblen] = '\0';
p = rl_point;
mlen = wcrtomb (mb, wc, &ps);
if (mlen >= 0)
mb[mlen] = '\0';
rl_begin_undo_group ();
rl_delete (1, 0);
rl_vi_delete (1, 0);
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++; /* XXX - should we advance more than 1 for mbchar? */
rl_insert_text (mb);
rl_end_undo_group ();
rl_vi_check ();
......@@ -713,7 +782,8 @@ _rl_vi_change_mbchar_case (count)
#endif
int
rl_vi_change_case (int count, int ignore __attribute__((unused)))
rl_vi_change_case (count, ignore)
int count, ignore;
{
int c, p;
......@@ -772,6 +842,15 @@ rl_vi_put (count, key)
return (0);
}
static void
_rl_vi_backup ()
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
rl_point--;
}
int
rl_vi_check ()
{
......@@ -816,7 +895,9 @@ rl_vi_domove (key, nextkey)
save = rl_numeric_arg;
rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION);
rl_digit_loop1 ();
RL_UNSETSTATE (RL_STATE_VIMOTION);
rl_numeric_arg *= save;
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key (); /* real command */
......@@ -889,38 +970,24 @@ rl_vi_domove (key, nextkey)
return (0);
}
/* A simplified loop for vi. Don't dispatch key at end.
Don't recognize minus sign?
Should this do rl_save_prompt/rl_restore_prompt? */
/* Process C as part of the current numeric argument. Return -1 if the
argument should be aborted, 0 if we should not read any more chars, and
1 if we should continue to read chars. */
static int
rl_digit_loop1 ()
_rl_vi_arg_dispatch (c)
int c;
{
int key, c;
int key;
RL_SETSTATE(RL_STATE_NUMERICARG);
while (1)
{
if (rl_numeric_arg > 1000000)
{
rl_explicit_arg = rl_numeric_arg = 0;
rl_ding ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return 1;
}
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
RL_SETSTATE(RL_STATE_MOREINPUT);
key = c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (c >= 0 && _rl_keymap[c].type == ISFUNC &&
_rl_keymap[c].function == rl_universal_argument)
key = c;
if (c >= 0 && _rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
{
rl_numeric_arg *= 4;
continue;
return 1;
}
c = UNMETA (c);
if (_rl_digit_p (c))
{
if (rl_explicit_arg)
......@@ -928,13 +995,34 @@ rl_digit_loop1 ()
else
rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
return 1;
}
else
{
rl_clear_message ();
rl_stuff_char (key);
break;
return 0;
}
}
/* A simplified loop for vi. Don't dispatch key at end.
Don't recognize minus sign?
Should this do rl_save_prompt/rl_restore_prompt? */
static int
rl_digit_loop1 ()
{
int c, r;
while (1)
{
if (_rl_arg_overflow ())
return 1;
c = _rl_arg_getchar ();
r = _rl_vi_arg_dispatch (c);
if (r <= 0)
break;
}
RL_UNSETSTATE(RL_STATE_NUMERICARG);
......@@ -942,7 +1030,8 @@ rl_digit_loop1 ()
}
int
rl_vi_delete_to (int count __attribute__((unused)), int key)
rl_vi_delete_to (count, key)
int count, key;
{
int c;
......@@ -967,7 +1056,8 @@ rl_vi_delete_to (int count __attribute__((unused)), int key)
}
int
rl_vi_change_to (int count __attribute__((unused)), int key)
rl_vi_change_to (count, key)
int count, key;
{
int c, start_pos;
......@@ -1019,10 +1109,12 @@ rl_vi_change_to (int count __attribute__((unused)), int key)
}
int
rl_vi_yank_to (int count __attribute__((unused)), int key)
rl_vi_yank_to (count, key)
int count, key;
{
int c, save = rl_point;
int c, save;
save = rl_point;
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
......@@ -1046,12 +1138,46 @@ rl_vi_yank_to (int count __attribute__((unused)), int key)
return (0);
}
int
rl_vi_rubout (count, key)
int count, key;
{
int opoint;
if (count < 0)
return (rl_vi_delete (-count, key));
if (rl_point == 0)
{
rl_ding ();
return -1;
}
opoint = rl_point;
if (count > 1 && MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_backward_char (count, key);
else if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
rl_point -= count;
if (rl_point < 0)
rl_point = 0;
rl_kill_text (rl_point, opoint);
return (0);
}
int
rl_vi_delete (count, key)
int count, key;
{
int end;
if (count < 0)
return (rl_vi_rubout (-count, key));
if (rl_end == 0)
{
rl_ding ();
......@@ -1070,11 +1196,13 @@ rl_vi_delete (count, key)
if (rl_point > 0 && rl_point == rl_end)
rl_backward_char (1, key);
return (0);
}
int
rl_vi_back_to_indent (int count __attribute__((unused)), int key)
rl_vi_back_to_indent (count, key)
int count, key;
{
rl_beg_of_line (1, key);
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
......@@ -1083,75 +1211,115 @@ rl_vi_back_to_indent (int count __attribute__((unused)), int key)
}
int
rl_vi_first_print (int count __attribute__((unused)), int key)
rl_vi_first_print (count, key)
int count, key;
{
return (rl_vi_back_to_indent (1, key));
}
static int _rl_cs_dir, _rl_cs_orig_dir;
#if defined (READLINE_CALLBACKS)
static int
_rl_vi_callback_char_search (data)
_rl_callback_generic_arg *data;
{
#if defined (HANDLE_MULTIBYTE)
_rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
#else
RL_SETSTATE(RL_STATE_MOREINPUT);
_rl_vi_last_search_char = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#endif
_rl_callback_func = 0;
_rl_want_redisplay = 1;
#if defined (HANDLE_MULTIBYTE)
return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_mbchar, _rl_vi_last_search_mblen));
#else
return (_rl_char_search_internal (data->count, _rl_cs_dir, _rl_vi_last_search_char));
#endif
}
#endif
int
rl_vi_char_search (count, key)
int count, key;
{
#if defined (HANDLE_MULTIBYTE)
static char *target;
static int mb_len;
static int tlen;
#else
static char target;
#endif
static int orig_dir, dir;
if (key == ';' || key == ',')
dir = key == ';' ? orig_dir : -orig_dir;
_rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
else
{
if (vi_redoing)
#if defined (HANDLE_MULTIBYTE)
target = _rl_vi_last_search_mbchar;
#else
target = _rl_vi_last_search_char;
#endif
else
{
#if defined (HANDLE_MULTIBYTE)
mb_len = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
target = _rl_vi_last_search_mbchar;
#else
RL_SETSTATE(RL_STATE_MOREINPUT);
_rl_vi_last_search_char = target = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#endif
}
switch (key)
{
case 't':
orig_dir = dir = FTO;
_rl_cs_orig_dir = _rl_cs_dir = FTO;
break;
case 'T':
orig_dir = dir = BTO;
_rl_cs_orig_dir = _rl_cs_dir = BTO;
break;
case 'f':
orig_dir = dir = FFIND;
_rl_cs_orig_dir = _rl_cs_dir = FFIND;
break;
case 'F':
orig_dir = dir = BFIND;
_rl_cs_orig_dir = _rl_cs_dir = BFIND;
break;
}
if (vi_redoing)
{
/* set target and tlen below */
}
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_data->i1 = _rl_cs_dir;
_rl_callback_func = _rl_vi_callback_char_search;
return (0);
}
#endif
else
{
#if defined (HANDLE_MULTIBYTE)
_rl_vi_last_search_mblen = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
#else
RL_SETSTATE(RL_STATE_MOREINPUT);
_rl_vi_last_search_char = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#endif
}
}
#if defined (HANDLE_MULTIBYTE)
target = _rl_vi_last_search_mbchar;
tlen = _rl_vi_last_search_mblen;
#else
target = _rl_vi_last_search_char;
#endif
#if defined (HANDLE_MULTIBYTE)
return (_rl_char_search_internal (count, dir, target, mb_len));
return (_rl_char_search_internal (count, _rl_cs_dir, target, tlen));
#else
return (_rl_char_search_internal (count, dir, target));
return (_rl_char_search_internal (count, _rl_cs_dir, target));
#endif
}
/* Match brackets */
int
rl_vi_match (int ignore __attribute__((unused)), int key)
rl_vi_match (ignore, key)
int ignore, key;
{
int count = 1, brack, pos, tmp, pre;
......@@ -1255,24 +1423,12 @@ rl_vi_bracktype (c)
}
}
/* XXX - think about reading an entire mbchar with _rl_read_mbchar and
inserting it in one bunch instead of the loop below (like in
rl_vi_char_search or _rl_vi_change_mbchar_case). Set c to mbchar[0]
for test against 033 or ^C. Make sure that _rl_read_mbchar does
this right. */
int
rl_vi_change_char (int count, int key __attribute__((unused)))
static int
_rl_vi_change_char (count, c, mb)
int count, c;
char *mb;
{
int c, p;
if (vi_redoing)
c = _rl_vi_last_replacement;
else
{
RL_SETSTATE(RL_STATE_MOREINPUT);
_rl_vi_last_replacement = c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
}
int p;
if (c == '\033' || c == CTRL ('C'))
return -1;
......@@ -1282,27 +1438,87 @@ rl_vi_change_char (int count, int key __attribute__((unused)))
{
p = rl_point;
rl_vi_delete (1, c);
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
while (_rl_insert_char (1, c))
{
RL_SETSTATE (RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE (RL_STATE_MOREINPUT);
}
rl_insert_text (mb);
else
#endif
{
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++;
_rl_insert_char (1, c);
}
}
/* The cursor shall be left on the last character changed. */
rl_backward_char (1, c);
rl_end_undo_group ();
return (0);
}
static int
_rl_vi_callback_getchar (mb, mlen)
char *mb;
int mlen;
{
int c;
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = _rl_read_mbstring (c, mb, mlen);
#endif
return c;
}
#if defined (READLINE_CALLBACKS)
static int
_rl_vi_callback_change_char (data)
_rl_callback_generic_arg *data;
{
int c;
char mb[MB_LEN_MAX];
_rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
_rl_callback_func = 0;
_rl_want_redisplay = 1;
return (_rl_vi_change_char (data->count, c, mb));
}
#endif
int
rl_vi_change_char (count, key)
int count, key;
{
int c;
char mb[MB_LEN_MAX];
if (vi_redoing)
{
c = _rl_vi_last_replacement;
mb[0] = c;
mb[1] = '\0';
}
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_func = _rl_vi_callback_change_char;
return (0);
}
#endif
else
_rl_vi_last_replacement = c = _rl_vi_callback_getchar (mb, MB_LEN_MAX);
return (_rl_vi_change_char (count, c, mb));
}
int
rl_vi_subst (count, key)
int count, key;
......@@ -1365,7 +1581,8 @@ rl_vi_overstrike_delete (count, key)
}
int
rl_vi_replace (int count __attribute__((unused)), int key __attribute__((unused)))
rl_vi_replace (count, key)
int count, key;
{
int i;
......@@ -1424,8 +1641,8 @@ rl_vi_possible_completions()
#endif
/* Functions to save and restore marks. */
int
rl_vi_set_mark (int count __attribute__((unused)), int key __attribute__((unused)))
static int
_rl_vi_set_mark ()
{
int ch;
......@@ -1443,8 +1660,36 @@ rl_vi_set_mark (int count __attribute__((unused)), int key __attribute__((unused
return 0;
}
#if defined (READLINE_CALLBACKS)
static int
_rl_vi_callback_set_mark (data)
_rl_callback_generic_arg *data;
{
_rl_callback_func = 0;
_rl_want_redisplay = 1;
return (_rl_vi_set_mark ());
}
#endif
int
rl_vi_goto_mark (int count __attribute__((unused)), int key __attribute__((unused)))
rl_vi_set_mark (count, key)
int count, key;
{
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = 0;
_rl_callback_func = _rl_vi_callback_set_mark;
return (0);
}
#endif
return (_rl_vi_set_mark ());
}
static int
_rl_vi_goto_mark ()
{
int ch;
......@@ -1473,4 +1718,31 @@ rl_vi_goto_mark (int count __attribute__((unused)), int key __attribute__((unuse
return 0;
}
#if defined (READLINE_CALLBACKS)
static int
_rl_vi_callback_goto_mark (data)
_rl_callback_generic_arg *data;
{
_rl_callback_func = 0;
_rl_want_redisplay = 1;
return (_rl_vi_goto_mark ());
}
#endif
int
rl_vi_goto_mark (count, key)
int count, key;
{
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = 0;
_rl_callback_func = _rl_vi_callback_goto_mark;
return (0);
}
#endif
return (_rl_vi_goto_mark ());
}
#endif /* VI_MODE */
......@@ -20,7 +20,9 @@
Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif
#include <stdio.h>
......@@ -39,7 +41,8 @@
/* **************************************************************** */
static void
memory_error_and_abort(const char *fname)
memory_error_and_abort (fname)
char *fname;
{
fprintf (stderr, "%s: out of virtual memory\n", fname);
exit (2);
......@@ -56,7 +59,7 @@ xmalloc (bytes)
temp = malloc (bytes);
if (temp == 0)
memory_error_and_abort("xmalloc");
memory_error_and_abort ("xmalloc");
return (temp);
}
......@@ -70,7 +73,7 @@ xrealloc (pointer, bytes)
temp = pointer ? realloc (pointer, bytes) : malloc (bytes);
if (temp == 0)
memory_error_and_abort("xrealloc");
memory_error_and_abort ("xrealloc");
return (temp);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment