Commit af3e8cb1 authored by df@pippilotta.erinye.com's avatar df@pippilotta.erinye.com

Merge pippilotta.erinye.com:/shared/home/df/mysql/build/mysql-5.0-build-work-18431

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