Commit bb2fb2af authored by unknown's avatar unknown

Upgrade bundled readline to version 5.0.


cmd-line-utils/readline/INSTALL:
  Import readline-5.0
cmd-line-utils/readline/Makefile.am:
  Import readline-5.0
cmd-line-utils/readline/README:
  Import readline-5.0
cmd-line-utils/readline/bind.c:
  Import readline-5.0
cmd-line-utils/readline/callback.c:
  Import readline-5.0
cmd-line-utils/readline/chardefs.h:
  Import readline-5.0
cmd-line-utils/readline/complete.c:
  Import readline-5.0
cmd-line-utils/readline/configure.in:
  Import readline-5.0
cmd-line-utils/readline/display.c:
  Import readline-5.0
cmd-line-utils/readline/funmap.c:
  Import readline-5.0
cmd-line-utils/readline/histexpand.c:
  Import readline-5.0
cmd-line-utils/readline/histfile.c:
  Import readline-5.0
cmd-line-utils/readline/history.c:
  Import readline-5.0
cmd-line-utils/readline/history.h:
  Import readline-5.0
cmd-line-utils/readline/histsearch.c:
  Import readline-5.0
cmd-line-utils/readline/input.c:
  Import readline-5.0
cmd-line-utils/readline/isearch.c:
  Import readline-5.0
cmd-line-utils/readline/keymaps.c:
  Import readline-5.0
cmd-line-utils/readline/kill.c:
  Import readline-5.0
cmd-line-utils/readline/macro.c:
  Import readline-5.0
cmd-line-utils/readline/mbutil.c:
  Import readline-5.0
cmd-line-utils/readline/misc.c:
  Import readline-5.0
cmd-line-utils/readline/nls.c:
  Import readline-5.0
cmd-line-utils/readline/parens.c:
  Import readline-5.0
cmd-line-utils/readline/posixdir.h:
  Import readline-5.0
cmd-line-utils/readline/readline.c:
  Import readline-5.0
cmd-line-utils/readline/readline.h:
  Import readline-5.0
cmd-line-utils/readline/rldefs.h:
  Import readline-5.0
cmd-line-utils/readline/rlmbutil.h:
  Import readline-5.0
cmd-line-utils/readline/rlprivate.h:
  Import readline-5.0
cmd-line-utils/readline/rlstdc.h:
  Import readline-5.0
cmd-line-utils/readline/rltty.c:
  Import readline-5.0
cmd-line-utils/readline/rltty.h:
  Import readline-5.0
cmd-line-utils/readline/rltypedefs.h:
  Import readline-5.0
cmd-line-utils/readline/search.c:
  Import readline-5.0
cmd-line-utils/readline/shell.c:
  Import readline-5.0
cmd-line-utils/readline/signals.c:
  Import readline-5.0
cmd-line-utils/readline/terminal.c:
  Import readline-5.0
cmd-line-utils/readline/text.c:
  Import readline-5.0
cmd-line-utils/readline/tilde.c:
  Import readline-5.0
cmd-line-utils/readline/undo.c:
  Import readline-5.0
cmd-line-utils/readline/util.c:
  Import readline-5.0
cmd-line-utils/readline/vi_mode.c:
  Import readline-5.0
cmd-line-utils/readline/xmalloc.c:
  Import readline-5.0
parent c6825704
Basic Installation Basic Installation
================== ==================
These are installation instructions for Readline-4.3. These are installation instructions for Readline-5.0.
The simplest way to compile readline is: The simplest way to compile readline is:
......
...@@ -17,7 +17,8 @@ libreadline_a_SOURCES = readline.c funmap.c keymaps.c \ ...@@ -17,7 +17,8 @@ libreadline_a_SOURCES = readline.c funmap.c keymaps.c \
callback.c terminal.c xmalloc.c \ callback.c terminal.c xmalloc.c \
history.c histsearch.c histexpand.c \ history.c histsearch.c histexpand.c \
histfile.c nls.c search.c \ histfile.c nls.c search.c \
shell.c tilde.c misc.c text.c mbutil.c shell.c tilde.c misc.c text.c mbutil.c \
compat.c savestring.c
pkginclude_HEADERS = readline.h chardefs.h keymaps.h \ pkginclude_HEADERS = readline.h chardefs.h keymaps.h \
history.h tilde.h rlmbutil.h rltypedefs.h rlprivate.h \ history.h tilde.h rlmbutil.h rltypedefs.h rlprivate.h \
......
Introduction Introduction
============ ============
This is the Gnu Readline library, version 4.3. This is the Gnu Readline library, version 5.0.
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
......
...@@ -19,9 +19,16 @@ ...@@ -19,9 +19,16 @@
is generally kept in a file called COPYING or LICENSE. If you do not is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation, have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#include "config_readline.h" #if defined (__TANDEM)
# include <floss.h>
#endif
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -146,6 +153,34 @@ rl_bind_key_in_map (key, function, map) ...@@ -146,6 +153,34 @@ rl_bind_key_in_map (key, function, map)
return (result); return (result);
} }
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
now, this is always used to attempt to bind the arrow keys, hence the
check for rl_vi_movement_mode. */
int
rl_bind_key_if_unbound_in_map (key, default_func, kmap)
int key;
rl_command_func_t *default_func;
Keymap kmap;
{
char keyseq[2];
keyseq[0] = (unsigned char)key;
keyseq[1] = '\0';
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap));
}
int
rl_bind_key_if_unbound (key, default_func)
int key;
rl_command_func_t *default_func;
{
char keyseq[2];
keyseq[0] = (unsigned char)key;
keyseq[1] = '\0';
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
}
/* Make KEY do nothing in the currently selected keymap. /* Make KEY do nothing in the currently selected keymap.
Returns non-zero in case of error. */ Returns non-zero in case of error. */
int int
...@@ -197,10 +232,31 @@ rl_unbind_command_in_map (command, map) ...@@ -197,10 +232,31 @@ rl_unbind_command_in_map (command, map)
return (rl_unbind_function_in_map (func, map)); return (rl_unbind_function_in_map (func, map));
} }
/* Bind the key sequence represented by the string KEYSEQ to
FUNCTION, starting in the current keymap. This makes new
keymaps as necessary. */
int
rl_bind_keyseq (keyseq, function)
const char *keyseq;
rl_command_func_t *function;
{
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap));
}
/* Bind the key sequence represented by the string KEYSEQ to /* Bind the key sequence represented by the string KEYSEQ to
FUNCTION. This makes new keymaps as necessary. The initial FUNCTION. This makes new keymaps as necessary. The initial
place to do bindings is in MAP. */ place to do bindings is in MAP. */
int int
rl_bind_keyseq_in_map (keyseq, function, map)
const char *keyseq;
rl_command_func_t *function;
Keymap map;
{
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
}
/* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */
int
rl_set_key (keyseq, function, map) rl_set_key (keyseq, function, map)
const char *keyseq; const char *keyseq;
rl_command_func_t *function; rl_command_func_t *function;
...@@ -209,6 +265,40 @@ rl_set_key (keyseq, function, map) ...@@ -209,6 +265,40 @@ rl_set_key (keyseq, function, map)
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map)); return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
} }
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
now, this is always used to attempt to bind the arrow keys, hence the
check for rl_vi_movement_mode. */
int
rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)
const char *keyseq;
rl_command_func_t *default_func;
Keymap kmap;
{
rl_command_func_t *func;
if (keyseq)
{
func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL);
#if defined (VI_MODE)
if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
#else
if (!func || func == rl_do_lowercase_version)
#endif
return (rl_bind_keyseq_in_map (keyseq, default_func, kmap));
else
return 1;
}
return 0;
}
int
rl_bind_keyseq_if_unbound (keyseq, default_func)
const char *keyseq;
rl_command_func_t *default_func;
{
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
}
/* Bind the key sequence represented by the string KEYSEQ to /* Bind the key sequence represented by the string KEYSEQ to
the string of characters MACRO. This makes new keymaps as the string of characters MACRO. This makes new keymaps as
necessary. The initial place to do bindings is in MAP. */ necessary. The initial place to do bindings is in MAP. */
...@@ -346,7 +436,7 @@ rl_translate_keyseq (seq, array, len) ...@@ -346,7 +436,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 == '\\')
{ {
...@@ -678,7 +768,7 @@ _rl_read_file (filename, sizep) ...@@ -678,7 +768,7 @@ _rl_read_file (filename, sizep)
/* Re-read the current keybindings file. */ /* Re-read the current keybindings file. */
int int
rl_re_read_init_file (count, ignore) rl_re_read_init_file (count, ignore)
int count __attribute__((unused)), 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);
...@@ -900,7 +990,7 @@ parser_if (args) ...@@ -900,7 +990,7 @@ 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 (args) parser_else (args)
char *args __attribute__((unused)); char *args;
{ {
register int i; register int i;
...@@ -910,9 +1000,15 @@ parser_else (args) ...@@ -910,9 +1000,15 @@ parser_else (args)
return 0; return 0;
} }
#if 0
/* Check the previous (n - 1) levels of the stack to make sure that /* Check the previous (n - 1) levels of the stack to make sure that
we haven't previously turned off parsing. */ we haven't previously turned off parsing. */
for (i = 0; i < if_stack_depth - 1; i++) for (i = 0; i < if_stack_depth - 1; i++)
#else
/* Check the previous (n) levels of the stack to make sure that
we haven't previously turned off parsing. */
for (i = 0; i < if_stack_depth; i++)
#endif
if (if_stack[i] == 1) if (if_stack[i] == 1)
return 0; return 0;
...@@ -925,7 +1021,7 @@ parser_else (args) ...@@ -925,7 +1021,7 @@ parser_else (args)
_rl_parsing_conditionalized_out from the stack. */ _rl_parsing_conditionalized_out from the stack. */
static int static int
parser_endif (args) parser_endif (args)
char *args __attribute__((unused)); 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];
...@@ -1048,7 +1144,7 @@ rl_parse_and_bind (string) ...@@ -1048,7 +1144,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)
{ {
...@@ -1124,7 +1220,7 @@ rl_parse_and_bind (string) ...@@ -1124,7 +1220,7 @@ rl_parse_and_bind (string)
{ {
int delimiter = string[i++], passc; int delimiter = string[i++], passc;
for (passc = 0; (c = string[i]); i++) for (passc = 0; c = string[i]; i++)
{ {
if (passc) if (passc)
{ {
...@@ -1159,7 +1255,7 @@ rl_parse_and_bind (string) ...@@ -1159,7 +1255,7 @@ rl_parse_and_bind (string)
} }
/* If this is a new-style key-binding, then do the binding with /* If this is a new-style key-binding, then do the binding with
rl_set_key (). Otherwise, let the older code deal with it. */ rl_bind_keyseq (). Otherwise, let the older code deal with it. */
if (*string == '"') if (*string == '"')
{ {
char *seq; char *seq;
...@@ -1198,7 +1294,7 @@ rl_parse_and_bind (string) ...@@ -1198,7 +1294,7 @@ rl_parse_and_bind (string)
rl_macro_bind (seq, &funname[1], _rl_keymap); rl_macro_bind (seq, &funname[1], _rl_keymap);
} }
else else
rl_set_key (seq, rl_named_function (funname), _rl_keymap); rl_bind_keyseq (seq, rl_named_function (funname));
free (seq); free (seq);
return 0; return 0;
...@@ -1279,10 +1375,11 @@ static struct { ...@@ -1279,10 +1375,11 @@ static struct {
{ "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL }, { "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL },
{ "print-completions-horizontally", &_rl_print_completions_horizontally, 0 }, { "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
{ "show-all-if-ambiguous", &_rl_complete_show_all, 0 }, { "show-all-if-ambiguous", &_rl_complete_show_all, 0 },
{ "show-all-if-unmodified", &_rl_complete_show_unmodified, 0 },
#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
...@@ -1351,7 +1448,7 @@ static struct { ...@@ -1351,7 +1448,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
...@@ -1626,8 +1723,7 @@ rl_set_keymap_from_edit_mode () ...@@ -1626,8 +1723,7 @@ rl_set_keymap_from_edit_mode ()
#endif /* VI_MODE */ #endif /* VI_MODE */
} }
char *
const 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)
...@@ -1637,7 +1733,7 @@ rl_get_keymap_name_from_edit_mode () ...@@ -1637,7 +1733,7 @@ rl_get_keymap_name_from_edit_mode ()
return "vi"; return "vi";
#endif /* VI_MODE */ #endif /* VI_MODE */
else else
return "nope"; return "none";
} }
/* **************************************************************** */ /* **************************************************************** */
...@@ -1649,7 +1745,7 @@ rl_get_keymap_name_from_edit_mode () ...@@ -1649,7 +1745,7 @@ rl_get_keymap_name_from_edit_mode ()
/* Each of the following functions produces information about the /* Each of the following functions produces information about the
state of keybindings and functions known to Readline. The info state of keybindings and functions known to Readline. The info
is always printed to rl_outstream, and in such a way that it can is always printed to rl_outstream, and in such a way that it can
be read back in (i.e., passed to rl_parse_and_bind (). */ be read back in (i.e., passed to rl_parse_and_bind ()). */
/* Print the names of functions known to Readline. */ /* Print the names of functions known to Readline. */
void void
...@@ -1872,7 +1968,7 @@ rl_function_dumper (print_readably) ...@@ -1872,7 +1968,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;
...@@ -1932,7 +2028,7 @@ rl_function_dumper (print_readably) ...@@ -1932,7 +2028,7 @@ rl_function_dumper (print_readably)
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 (count, key) rl_dump_functions (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
if (rl_dispatching) if (rl_dispatching)
fprintf (rl_outstream, "\r\n"); fprintf (rl_outstream, "\r\n");
...@@ -2012,7 +2108,7 @@ rl_macro_dumper (print_readably) ...@@ -2012,7 +2108,7 @@ rl_macro_dumper (print_readably)
int int
rl_dump_macros (count, key) rl_dump_macros (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
if (rl_dispatching) if (rl_dispatching)
fprintf (rl_outstream, "\r\n"); fprintf (rl_outstream, "\r\n");
...@@ -2102,7 +2198,7 @@ rl_variable_dumper (print_readably) ...@@ -2102,7 +2198,7 @@ rl_variable_dumper (print_readably)
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 (count, key) rl_dump_variables (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
if (rl_dispatching) if (rl_dispatching)
fprintf (rl_outstream, "\r\n"); fprintf (rl_outstream, "\r\n");
...@@ -2111,28 +2207,6 @@ rl_dump_variables (count, key) ...@@ -2111,28 +2207,6 @@ rl_dump_variables (count, key)
return (0); return (0);
} }
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
now, this is always used to attempt to bind the arrow keys, hence the
check for rl_vi_movement_mode. */
void
_rl_bind_if_unbound (keyseq, default_func)
const char *keyseq;
rl_command_func_t *default_func;
{
rl_command_func_t *func;
if (keyseq)
{
func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL);
#if defined (VI_MODE)
if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
#else
if (!func || func == rl_do_lowercase_version)
#endif
rl_set_key (keyseq, default_func, _rl_keymap);
}
}
/* Return non-zero if any members of ARRAY are a substring in STRING. */ /* Return non-zero if any members of ARRAY are a substring in STRING. */
static int static int
substring_member_of_array (string, array) substring_member_of_array (string, array)
......
...@@ -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"
...@@ -129,7 +131,7 @@ rl_callback_read_char () ...@@ -129,7 +131,7 @@ 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) if (rl_pending_input || _rl_pushed_input_available ())
eof = readline_internal_char (); eof = readline_internal_char ();
else else
break; break;
......
...@@ -77,7 +77,11 @@ ...@@ -77,7 +77,11 @@
# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) # define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif #endif
#define NON_NEGATIVE(c) ((unsigned char)(c) == (c)) #if defined (CTYPE_NON_ASCII)
# define NON_NEGATIVE(c) 1
#else
# define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
#endif
/* Some systems define these; we want our definitions. */ /* Some systems define these; we want our definitions. */
#undef ISPRINT #undef ISPRINT
......
/* compat.c -- backwards compatibility functions. */
/* Copyright (C) 2000 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library 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.
The GNU Readline Library 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.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#include "rlstdc.h"
#include "rltypedefs.h"
extern void rl_free_undo_list PARAMS((void));
extern int rl_maybe_save_line PARAMS((void));
extern int rl_maybe_unsave_line PARAMS((void));
extern int rl_maybe_replace_line PARAMS((void));
extern int rl_crlf PARAMS((void));
extern int rl_ding PARAMS((void));
extern int rl_alphabetic PARAMS((int));
extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *));
extern char *rl_username_completion_function PARAMS((const char *, int));
extern char *rl_filename_completion_function PARAMS((const char *, int));
/* Provide backwards-compatible entry points for old function names. */
void
free_undo_list ()
{
rl_free_undo_list ();
}
int
maybe_replace_line ()
{
return rl_maybe_replace_line ();
}
int
maybe_save_line ()
{
return rl_maybe_save_line ();
}
int
maybe_unsave_line ()
{
return rl_maybe_unsave_line ();
}
int
ding ()
{
return rl_ding ();
}
int
crlf ()
{
return rl_crlf ();
}
int
alphabetic (c)
int c;
{
return rl_alphabetic (c);
}
char **
completion_matches (s, f)
const char *s;
rl_compentry_func_t *f;
{
return rl_completion_matches (s, f);
}
char *
username_completion_function (s, i)
const char *s;
int i;
{
return rl_username_completion_function (s, i);
}
char *
filename_completion_function (s, i)
const char *s;
int i;
{
return rl_filename_completion_function (s, i);
}
/* complete.c -- filename completion for readline. */ /* complete.c -- filename completion for readline. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. /* Copyright (C) 1987-2004 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,12 +21,14 @@ ...@@ -21,12 +21,14 @@
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>
#if defined (HAVE_SYS_FILE_H) #if defined (HAVE_SYS_FILE_H)
#include <sys/file.h> # include <sys/file.h>
#endif #endif
#if defined (HAVE_UNISTD_H) #if defined (HAVE_UNISTD_H)
...@@ -97,12 +99,16 @@ rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)N ...@@ -97,12 +99,16 @@ rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)N
static int stat_char PARAMS((char *)); static int stat_char PARAMS((char *));
#endif #endif
static int path_isdir PARAMS((const char *));
static char *rl_quote_filename PARAMS((char *, int, char *)); static char *rl_quote_filename PARAMS((char *, int, char *));
static void set_completion_defaults PARAMS((int)); static void set_completion_defaults PARAMS((int));
static int get_y_or_n PARAMS((int)); static int get_y_or_n PARAMS((int));
static int _rl_internal_pager PARAMS((int)); static int _rl_internal_pager PARAMS((int));
static char *printable_part PARAMS((char *)); static char *printable_part PARAMS((char *));
static int fnwidth PARAMS((const char *));
static int fnprint PARAMS((const char *));
static int print_filename PARAMS((char *, char *)); static int print_filename PARAMS((char *, char *));
static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int)); static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
...@@ -128,6 +134,10 @@ static char *make_quoted_replacement PARAMS((char *, int, char *)); ...@@ -128,6 +134,10 @@ static char *make_quoted_replacement PARAMS((char *, int, char *));
/* If non-zero, non-unique completions always show the list of matches. */ /* If non-zero, non-unique completions always show the list of matches. */
int _rl_complete_show_all = 0; int _rl_complete_show_all = 0;
/* If non-zero, non-unique completions show the list of matches, unless it
is not possible to do partial completion and modify the line. */
int _rl_complete_show_unmodified = 0;
/* If non-zero, completed directory names have a slash appended. */ /* If non-zero, completed directory names have a slash appended. */
int _rl_complete_mark_directories = 1; int _rl_complete_mark_directories = 1;
...@@ -212,7 +222,12 @@ const char *rl_basic_quote_characters = "\"'"; ...@@ -212,7 +222,12 @@ const char *rl_basic_quote_characters = "\"'";
/* The list of characters that signal a break between words for /* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */ rl_basic_word_break_characters. */
const char *rl_completer_word_break_characters = (const char *)NULL; /*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL;
/* Hook function to allow an application to set the completion word
break characters before readline breaks up the line. Allows
position-dependent word break characters. */
rl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL;
/* List of characters which can be used to quote a substring of the line. /* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring Completion occurs on the entire substring, and within the substring
...@@ -280,6 +295,19 @@ int rl_completion_suppress_append = 0; ...@@ -280,6 +295,19 @@ int rl_completion_suppress_append = 0;
default is a space. */ default is a space. */
int rl_completion_append_character = ' '; int rl_completion_append_character = ' ';
/* If non-zero, the completion functions don't append any closing quote.
This is set to 0 by rl_complete_internal and may be changed by an
application-specific completion function. */
int rl_completion_suppress_quote = 0;
/* Set to any quote character readline thinks it finds before any application
completion function is called. */
int rl_completion_quote_character;
/* Set to a non-zero value if readline found quoting anywhere in the word to
be completed; set before any application completion function is called. */
int rl_completion_found_quote;
/* If non-zero, a slash will be appended to completed filenames that are /* If non-zero, a slash will be appended to completed filenames that are
symbolic links to directory names, subject to the value of the symbolic links to directory names, subject to the value of the
mark-directories variable (which is user-settable). This exists so mark-directories variable (which is user-settable). This exists so
...@@ -318,6 +346,8 @@ rl_complete (ignore, invoking_key) ...@@ -318,6 +346,8 @@ rl_complete (ignore, invoking_key)
return (rl_complete_internal ('?')); return (rl_complete_internal ('?'));
else if (_rl_complete_show_all) else if (_rl_complete_show_all)
return (rl_complete_internal ('!')); return (rl_complete_internal ('!'));
else if (_rl_complete_show_unmodified)
return (rl_complete_internal ('@'));
else else
return (rl_complete_internal (TAB)); return (rl_complete_internal (TAB));
} }
...@@ -325,14 +355,14 @@ rl_complete (ignore, invoking_key) ...@@ -325,14 +355,14 @@ 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 (ignore, invoking_key) rl_possible_completions (ignore, invoking_key)
int ignore __attribute__((unused)), invoking_key __attribute__((unused)); int ignore, invoking_key;
{ {
return (rl_complete_internal ('?')); return (rl_complete_internal ('?'));
} }
int int
rl_insert_completions (ignore, invoking_key) rl_insert_completions (ignore, invoking_key)
int ignore __attribute__((unused)), invoking_key __attribute__((unused)); int ignore, invoking_key;
{ {
return (rl_complete_internal ('*')); return (rl_complete_internal ('*'));
} }
...@@ -350,6 +380,8 @@ rl_completion_mode (cfunc) ...@@ -350,6 +380,8 @@ rl_completion_mode (cfunc)
return '?'; return '?';
else if (_rl_complete_show_all) else if (_rl_complete_show_all)
return '!'; return '!';
else if (_rl_complete_show_unmodified)
return '@';
else else
return TAB; return TAB;
} }
...@@ -370,7 +402,7 @@ set_completion_defaults (what_to_do) ...@@ -370,7 +402,7 @@ set_completion_defaults (what_to_do)
rl_filename_completion_desired = 0; rl_filename_completion_desired = 0;
rl_filename_quoting_desired = 1; rl_filename_quoting_desired = 1;
rl_completion_type = what_to_do; rl_completion_type = what_to_do;
rl_completion_suppress_append = 0; rl_completion_suppress_append = rl_completion_suppress_quote = 0;
/* The completion entry function may optionally change this. */ /* The completion entry function may optionally change this. */
rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs; rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
...@@ -421,6 +453,15 @@ _rl_internal_pager (lines) ...@@ -421,6 +453,15 @@ _rl_internal_pager (lines)
return 0; return 0;
} }
static int
path_isdir (filename)
const char *filename;
{
struct stat finfo;
return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode));
}
#if defined (VISIBLE_STATS) #if defined (VISIBLE_STATS)
/* Return the character which best describes FILENAME. /* Return the character which best describes FILENAME.
`@' for symbolic links `@' for symbolic links
...@@ -518,53 +559,140 @@ printable_part (pathname) ...@@ -518,53 +559,140 @@ printable_part (pathname)
return ++temp; return ++temp;
} }
/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we /* Compute width of STRING when displayed on screen by print_filename */
are using it, check for and output a single character for `special' static int
filenames. Return the number of characters we output. */ fnwidth (string)
const char *string;
{
int width, pos;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
int left, w;
size_t clen;
wchar_t wc;
left = strlen (string) + 1;
memset (&ps, 0, sizeof (mbstate_t));
#endif
width = pos = 0;
while (string[pos])
{
if (CTRL_CHAR (*string) || *string == RUBOUT)
{
width += 2;
pos++;
}
else
{
#if defined (HANDLE_MULTIBYTE)
clen = mbrtowc (&wc, string + pos, left - pos, &ps);
if (MB_INVALIDCH (clen))
{
width++;
pos++;
memset (&ps, 0, sizeof (mbstate_t));
}
else if (MB_NULLWCH (clen))
break;
else
{
pos += clen;
w = wcwidth (wc);
width += (w >= 0) ? w : 1;
}
#else
width++;
pos++;
#endif
}
}
#define PUTX(c) \ return width;
do { \ }
if (CTRL_CHAR (c)) \
{ \
putc ('^', rl_outstream); \
putc (UNCTRL (c), rl_outstream); \
printed_len += 2; \
} \
else if (c == RUBOUT) \
{ \
putc ('^', rl_outstream); \
putc ('?', rl_outstream); \
printed_len += 2; \
} \
else \
{ \
putc (c, rl_outstream); \
printed_len++; \
} \
} while (0)
static int static int
print_filename (to_print, full_pathname) fnprint (to_print)
char *to_print, *full_pathname; const char *to_print;
{ {
int printed_len = 0; int printed_len;
#if !defined (VISIBLE_STATS) const char *s;
char *s; #if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
const char *end;
size_t tlen;
for (s = to_print; *s; s++) end = to_print + strlen (to_print) + 1;
memset (&ps, 0, sizeof (mbstate_t));
#endif
printed_len = 0;
s = to_print;
while (*s)
{
if (CTRL_CHAR (*s))
{ {
PUTX (*s); putc ('^', rl_outstream);
putc (UNCTRL (*s), rl_outstream);
printed_len += 2;
s++;
#if defined (HANDLE_MULTIBYTE)
memset (&ps, 0, sizeof (mbstate_t));
#endif
} }
else if (*s == RUBOUT)
{
putc ('^', rl_outstream);
putc ('?', rl_outstream);
printed_len += 2;
s++;
#if defined (HANDLE_MULTIBYTE)
memset (&ps, 0, sizeof (mbstate_t));
#endif
}
else
{
#if defined (HANDLE_MULTIBYTE)
tlen = mbrlen (s, end - s, &ps);
if (MB_INVALIDCH (tlen))
{
tlen = 1;
memset (&ps, 0, sizeof (mbstate_t));
}
else if (MB_NULLWCH (tlen))
break;
fwrite (s, 1, tlen, rl_outstream);
s += tlen;
#else #else
putc (*s, rl_outstream);
s++;
#endif
printed_len++;
}
}
return printed_len;
}
/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we
are using it, check for and output a single character for `special'
filenames. Return the number of characters we output. */
static int
print_filename (to_print, full_pathname)
char *to_print, *full_pathname;
{
int printed_len, extension_char, slen, tlen;
char *s, c, *new_full_pathname; char *s, c, *new_full_pathname;
int extension_char, slen, tlen;
for (s = to_print; *s; s++) extension_char = 0;
{ printed_len = fnprint (to_print);
PUTX (*s);
}
if (rl_filename_completion_desired && rl_visible_stats) #if defined (VISIBLE_STATS)
if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories))
#else
if (rl_filename_completion_desired && _rl_complete_mark_directories)
#endif
{ {
/* If to_print != full_pathname, to_print is the basename of the /* If to_print != full_pathname, to_print is the basename of the
path passed. In this case, we try to expand the directory path passed. In this case, we try to expand the directory
...@@ -591,7 +719,13 @@ print_filename (to_print, full_pathname) ...@@ -591,7 +719,13 @@ print_filename (to_print, full_pathname)
new_full_pathname[slen] = '/'; new_full_pathname[slen] = '/';
strcpy (new_full_pathname + slen + 1, to_print); strcpy (new_full_pathname + slen + 1, to_print);
#if defined (VISIBLE_STATS)
if (rl_visible_stats)
extension_char = stat_char (new_full_pathname); extension_char = stat_char (new_full_pathname);
else
#endif
if (path_isdir (new_full_pathname))
extension_char = '/';
free (new_full_pathname); free (new_full_pathname);
to_print[-1] = c; to_print[-1] = c;
...@@ -599,7 +733,13 @@ print_filename (to_print, full_pathname) ...@@ -599,7 +733,13 @@ print_filename (to_print, full_pathname)
else else
{ {
s = tilde_expand (full_pathname); s = tilde_expand (full_pathname);
#if defined (VISIBLE_STATS)
if (rl_visible_stats)
extension_char = stat_char (s); extension_char = stat_char (s);
else
#endif
if (path_isdir (s))
extension_char = '/';
} }
free (s); free (s);
...@@ -609,14 +749,14 @@ print_filename (to_print, full_pathname) ...@@ -609,14 +749,14 @@ print_filename (to_print, full_pathname)
printed_len++; printed_len++;
} }
} }
#endif /* VISIBLE_STATS */
return printed_len; return printed_len;
} }
static char * static char *
rl_quote_filename (s, rtype, qcp) rl_quote_filename (s, rtype, qcp)
char *s; char *s;
int rtype __attribute__((unused)); int rtype;
char *qcp; char *qcp;
{ {
char *r; char *r;
...@@ -649,19 +789,32 @@ _rl_find_completion_word (fp, dp) ...@@ -649,19 +789,32 @@ _rl_find_completion_word (fp, dp)
int *fp, *dp; int *fp, *dp;
{ {
int scan, end, found_quote, delimiter, pass_next, isbrk; int scan, end, found_quote, delimiter, pass_next, isbrk;
char quote_char; char quote_char, *brkchars;
end = rl_point; end = rl_point;
found_quote = delimiter = 0; found_quote = delimiter = 0;
quote_char = '\0'; quote_char = '\0';
brkchars = 0;
if (rl_completion_word_break_hook)
brkchars = (*rl_completion_word_break_hook) ();
if (brkchars == 0)
brkchars = rl_completer_word_break_characters;
if (rl_completer_quote_characters) if (rl_completer_quote_characters)
{ {
/* We have a list of characters which can be used in pairs to /* We have a list of characters which can be used in pairs to
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_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++) for (scan = pass_next = 0; scan < end; scan++)
#endif
{ {
if (pass_next) if (pass_next)
{ {
...@@ -719,7 +872,7 @@ _rl_find_completion_word (fp, dp) ...@@ -719,7 +872,7 @@ _rl_find_completion_word (fp, dp)
{ {
scan = rl_line_buffer[rl_point]; scan = rl_line_buffer[rl_point];
if (strchr (rl_completer_word_break_characters, scan) == 0) if (strchr (brkchars, scan) == 0)
continue; continue;
/* Call the application-specific function to tell us whether /* Call the application-specific function to tell us whether
...@@ -747,9 +900,9 @@ _rl_find_completion_word (fp, dp) ...@@ -747,9 +900,9 @@ _rl_find_completion_word (fp, dp)
if (rl_char_is_quoted_p) if (rl_char_is_quoted_p)
isbrk = (found_quote == 0 || isbrk = (found_quote == 0 ||
(*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) && (*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
strchr (rl_completer_word_break_characters, scan) != 0; strchr (brkchars, scan) != 0;
else else
isbrk = strchr (rl_completer_word_break_characters, scan) != 0; isbrk = strchr (brkchars, scan) != 0;
if (isbrk) if (isbrk)
{ {
...@@ -784,6 +937,9 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char) ...@@ -784,6 +937,9 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
{ {
char **matches, *temp; char **matches, *temp;
rl_completion_found_quote = found_quote;
rl_completion_quote_character = quote_char;
/* If the user wants to TRY to complete, but then wants to give /* If the user wants to TRY to complete, but then wants to give
up and use the default completion function, they set the up and use the default completion function, they set the
variable rl_attempted_completion_function. */ variable rl_attempted_completion_function. */
...@@ -887,6 +1043,7 @@ compute_lcd_of_matches (match_list, matches, text) ...@@ -887,6 +1043,7 @@ compute_lcd_of_matches (match_list, matches, text)
{ {
register int i, c1, c2, si; register int i, c1, c2, si;
int low; /* Count of max-matched characters. */ int low; /* Count of max-matched characters. */
char *dtext; /* dequoted TEXT, if needed */
#if defined (HANDLE_MULTIBYTE) #if defined (HANDLE_MULTIBYTE)
int v; int v;
mbstate_t ps1, ps2; mbstate_t ps1, ps2;
...@@ -978,6 +1135,26 @@ compute_lcd_of_matches (match_list, matches, text) ...@@ -978,6 +1135,26 @@ compute_lcd_of_matches (match_list, matches, text)
the user typed in the face of multiple matches differing in case. */ the user typed in the face of multiple matches differing in case. */
if (_rl_completion_case_fold) if (_rl_completion_case_fold)
{ {
/* We're making an assumption here:
IF we're completing filenames AND
the application has defined a filename dequoting function AND
we found a quote character AND
the application has requested filename quoting
THEN
we assume that TEXT was dequoted before checking against
the file system and needs to be dequoted here before we
check against the list of matches
FI */
dtext = (char *)NULL;
if (rl_filename_completion_desired &&
rl_filename_dequoting_function &&
rl_completion_found_quote &&
rl_filename_quoting_desired)
{
dtext = (*rl_filename_dequoting_function) (text, rl_completion_quote_character);
text = dtext;
}
/* sort the list to get consistent answers. */ /* sort the list to get consistent answers. */
qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare); qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
...@@ -997,6 +1174,8 @@ compute_lcd_of_matches (match_list, matches, text) ...@@ -997,6 +1174,8 @@ compute_lcd_of_matches (match_list, matches, text)
else else
/* otherwise, just use the text the user typed. */ /* otherwise, just use the text the user typed. */
strncpy (match_list[0], text, low); strncpy (match_list[0], text, low);
FREE (dtext);
} }
else else
strncpy (match_list[0], match_list[1], low); strncpy (match_list[0], match_list[1], low);
...@@ -1201,7 +1380,7 @@ display_matches (matches) ...@@ -1201,7 +1380,7 @@ display_matches (matches)
for (max = 0, i = 1; matches[i]; i++) for (max = 0, i = 1; matches[i]; i++)
{ {
temp = printable_part (matches[i]); temp = printable_part (matches[i]);
len = strlen (temp); len = fnwidth (temp);
if (len > max) if (len > max)
max = len; max = len;
...@@ -1336,7 +1515,8 @@ append_to_match (text, delimiter, quote_char, nontrivial_match) ...@@ -1336,7 +1515,8 @@ append_to_match (text, delimiter, quote_char, nontrivial_match)
struct stat finfo; struct stat finfo;
temp_string_index = 0; temp_string_index = 0;
if (quote_char && rl_point && rl_line_buffer[rl_point - 1] != quote_char) if (quote_char && rl_point && rl_completion_suppress_quote == 0 &&
rl_line_buffer[rl_point - 1] != quote_char)
temp_string[temp_string_index++] = quote_char; temp_string[temp_string_index++] = quote_char;
if (delimiter) if (delimiter)
...@@ -1447,7 +1627,9 @@ _rl_free_match_list (matches) ...@@ -1447,7 +1627,9 @@ _rl_free_match_list (matches)
TAB means do standard completion. TAB means do standard completion.
`*' means insert all of the possible completions. `*' means insert all of the possible completions.
`!' means to do standard completion, and list all possible completions if `!' means to do standard completion, and list all possible completions if
there is more than one. */ there is more than one.
`@' means to do standard completion, and list all possible completions if
there is more than one and partial completion is not possible. */
int int
rl_complete_internal (what_to_do) rl_complete_internal (what_to_do)
int what_to_do; int what_to_do;
...@@ -1466,7 +1648,6 @@ rl_complete_internal (what_to_do) ...@@ -1466,7 +1648,6 @@ rl_complete_internal (what_to_do)
our_func = rl_completion_entry_function our_func = rl_completion_entry_function
? rl_completion_entry_function ? rl_completion_entry_function
: rl_filename_completion_function; : rl_filename_completion_function;
/* We now look backwards for the start of a filename/variable word. */ /* We now look backwards for the start of a filename/variable word. */
end = rl_point; end = rl_point;
found_quote = delimiter = 0; found_quote = delimiter = 0;
...@@ -1514,6 +1695,7 @@ rl_complete_internal (what_to_do) ...@@ -1514,6 +1695,7 @@ rl_complete_internal (what_to_do)
{ {
case TAB: case TAB:
case '!': case '!':
case '@':
/* Insert the first match with proper quoting. */ /* Insert the first match with proper quoting. */
if (*matches[0]) if (*matches[0])
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char); insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
...@@ -1533,6 +1715,12 @@ rl_complete_internal (what_to_do) ...@@ -1533,6 +1715,12 @@ rl_complete_internal (what_to_do)
display_matches (matches); display_matches (matches);
break; break;
} }
else if (what_to_do == '@')
{
if (nontrivial_lcd == 0)
display_matches (matches);
break;
}
else if (rl_editing_mode != vi_mode) else if (rl_editing_mode != vi_mode)
rl_ding (); /* There are other matches remaining. */ rl_ding (); /* There are other matches remaining. */
} }
...@@ -1610,7 +1798,7 @@ rl_completion_matches (text, entry_function) ...@@ -1610,7 +1798,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
...@@ -1660,7 +1848,7 @@ rl_username_completion_function (text, state) ...@@ -1660,7 +1848,7 @@ rl_username_completion_function (text, state)
setpwent (); setpwent ();
} }
while ((entry = 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)))
...@@ -1897,7 +2085,7 @@ rl_filename_completion_function (text, state) ...@@ -1897,7 +2085,7 @@ rl_filename_completion_function (text, state)
ring the bell, and reset the counter to zero. */ ring the bell, and reset the counter to zero. */
int int
rl_menu_complete (count, ignore) rl_menu_complete (count, ignore)
int count, ignore __attribute__((unused)); 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;
......
...@@ -4,9 +4,9 @@ dnl ...@@ -4,9 +4,9 @@ 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 4.3, version 2.45, from autoconf version] AC_ACVERSION) AC_REVISION([for Readline 5.0, version 2.52, from autoconf version] AC_ACVERSION)
AC_INIT(readline, 4.3, bug-readline@gnu.org) AC_INIT(readline, 5.0-rc1, 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,7 +16,7 @@ AC_CONFIG_AUX_DIR(./support) ...@@ -16,7 +16,7 @@ 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=4.3 LIBVERSION=5.0
AC_CANONICAL_HOST AC_CANONICAL_HOST
...@@ -31,12 +31,18 @@ if test "$opt_curses" = "yes"; then ...@@ -31,12 +31,18 @@ if test "$opt_curses" = "yes"; then
fi fi
dnl option parsing for optional features dnl option parsing for optional features
opt_multibyte=yes
opt_static_libs=yes opt_static_libs=yes
opt_shared_libs=yes opt_shared_libs=yes
AC_ARG_ENABLE(multibyte, AC_HELP_STRING([--enable-multibyte], [enable multibyte characters if OS supports them]), opt_multibyte=$enableval)
AC_ARG_ENABLE(shared, AC_HELP_STRING([--enable-shared], [build shared libraries [[default=YES]]]), opt_shared_libs=$enableval) AC_ARG_ENABLE(shared, AC_HELP_STRING([--enable-shared], [build shared libraries [[default=YES]]]), opt_shared_libs=$enableval)
AC_ARG_ENABLE(static, AC_HELP_STRING([--enable-static], [build static libraries [[default=YES]]]), opt_static_libs=$enableval) AC_ARG_ENABLE(static, AC_HELP_STRING([--enable-static], [build static libraries [[default=YES]]]), opt_static_libs=$enableval)
if test $opt_multibyte = no; then
AC_DEFINE(NO_MULTIBYTE_SUPPORT)
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 ""
...@@ -72,6 +78,8 @@ AC_TYPE_SIGNAL ...@@ -72,6 +78,8 @@ AC_TYPE_SIGNAL
AC_TYPE_SIZE_T AC_TYPE_SIZE_T
AC_CHECK_TYPE(ssize_t, int) AC_CHECK_TYPE(ssize_t, int)
AC_HEADER_STDC
AC_HEADER_STAT AC_HEADER_STAT
AC_HEADER_DIRENT AC_HEADER_DIRENT
...@@ -90,6 +98,7 @@ BASH_SYS_REINSTALL_SIGHANDLERS ...@@ -90,6 +98,7 @@ BASH_SYS_REINSTALL_SIGHANDLERS
BASH_FUNC_POSIX_SETJMP BASH_FUNC_POSIX_SETJMP
BASH_FUNC_LSTAT BASH_FUNC_LSTAT
BASH_FUNC_STRCOLL BASH_FUNC_STRCOLL
BASH_FUNC_CTYPE_NONASCII
BASH_CHECK_GETPW_FUNCS BASH_CHECK_GETPW_FUNCS
......
/* display.c -- readline redisplay facility. */ /* display.c -- readline redisplay facility. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc. /* Copyright (C) 1987-2004 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>
...@@ -119,7 +121,7 @@ int _rl_suppress_redisplay = 0; ...@@ -119,7 +121,7 @@ int _rl_suppress_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. */
const 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. */
...@@ -176,12 +178,15 @@ static int prompt_invis_chars_first_line; ...@@ -176,12 +178,15 @@ static int prompt_invis_chars_first_line;
static int prompt_last_screen_line; static int prompt_last_screen_line;
static int prompt_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
index of the last invisible character in the returned string. NIFLP, index of the last invisible character in the returned string. NIFLP,
if non-zero, is a place to store the number of invisible characters in if non-zero, is a place to store the number of invisible characters in
the first prompt line. */ the first prompt line. The previous are used as byte counts -- indexes
into a character buffer. */
/* Current implementation: /* Current implementation:
\001 (^A) start non-visible characters \001 (^A) start non-visible characters
...@@ -191,19 +196,25 @@ static int prompt_last_screen_line; ...@@ -191,19 +196,25 @@ static int prompt_last_screen_line;
\002 are assumed to be `visible'. */ \002 are assumed to be `visible'. */
static char * static char *
expand_prompt (pmt, lp, lip, niflp) expand_prompt (pmt, lp, lip, niflp, vlp)
char *pmt; char *pmt;
int *lp, *lip, *niflp; int *lp, *lip, *niflp, *vlp;
{ {
char *r, *ret, *p; char *r, *ret, *p;
int l, rl, last, ignoring, ninvis, invfl; int l, rl, last, ignoring, ninvis, invfl, ind, pind, physchars;
/* Short-circuit if we can. */ /* Short-circuit if we can. */
if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0) if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
{ {
r = savestring (pmt); r = savestring (pmt);
if (lp) if (lp)
*lp = strlen (r); *lp = strlen (r);
if (lip)
*lip = 0;
if (niflp)
*niflp = 0;
if (vlp)
*vlp = lp ? *lp : strlen (r);
return r; return r;
} }
...@@ -212,7 +223,7 @@ expand_prompt (pmt, lp, lip, niflp) ...@@ -212,7 +223,7 @@ expand_prompt (pmt, lp, lip, niflp)
invfl = 0; /* invisible chars in first line of prompt */ invfl = 0; /* invisible chars in first line of prompt */
for (rl = ignoring = last = ninvis = 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 */
...@@ -229,13 +240,35 @@ expand_prompt (pmt, lp, lip, niflp) ...@@ -229,13 +240,35 @@ expand_prompt (pmt, lp, lip, niflp)
} }
else else
{ {
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
pind = p - pmt;
ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
l = ind - pind;
while (l--)
*r++ = *p++;
if (!ignoring)
rl += ind - pind;
else
ninvis += ind - pind;
p--; /* compensate for later increment */
}
else
#endif
{
*r++ = *p; *r++ = *p;
if (!ignoring) if (!ignoring)
rl++; rl++; /* visible length byte counter */
else else
ninvis++; ninvis++; /* invisible chars byte counter */
if (rl == _rl_screenwidth) }
if (rl >= _rl_screenwidth)
invfl = ninvis; invfl = ninvis;
if (ignoring == 0)
physchars++;
} }
} }
...@@ -249,6 +282,8 @@ expand_prompt (pmt, lp, lip, niflp) ...@@ -249,6 +282,8 @@ expand_prompt (pmt, lp, lip, niflp)
*lip = last; *lip = last;
if (niflp) if (niflp)
*niflp = invfl; *niflp = invfl;
if (vlp)
*vlp = physchars;
return ret; return ret;
} }
...@@ -260,7 +295,7 @@ _rl_strip_prompt (pmt) ...@@ -260,7 +295,7 @@ _rl_strip_prompt (pmt)
{ {
char *ret; char *ret;
ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL); ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
return ret; return ret;
} }
...@@ -304,7 +339,8 @@ rl_expand_prompt (prompt) ...@@ -304,7 +339,8 @@ rl_expand_prompt (prompt)
/* The prompt is only one logical line, though it might wrap. */ /* The prompt is only one logical line, though it might wrap. */
local_prompt = expand_prompt (prompt, &prompt_visible_length, local_prompt = expand_prompt (prompt, &prompt_visible_length,
&prompt_last_invisible, &prompt_last_invisible,
&prompt_invis_chars_first_line); &prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)0; local_prompt_prefix = (char *)0;
return (prompt_visible_length); return (prompt_visible_length);
} }
...@@ -314,13 +350,15 @@ rl_expand_prompt (prompt) ...@@ -314,13 +350,15 @@ rl_expand_prompt (prompt)
t = ++p; t = ++p;
local_prompt = expand_prompt (p, &prompt_visible_length, local_prompt = expand_prompt (p, &prompt_visible_length,
&prompt_last_invisible, &prompt_last_invisible,
&prompt_invis_chars_first_line); (int *)NULL,
(int *)NULL);
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);
*t = c; *t = c;
return (prompt_prefix_length); return (prompt_prefix_length);
} }
...@@ -379,8 +417,8 @@ rl_redisplay () ...@@ -379,8 +417,8 @@ 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 c_pos, inv_botlin, lb_botlin, lb_linenum;
int newlines, lpos, temp; int newlines, lpos, temp, modmark;
const 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;
...@@ -409,10 +447,12 @@ rl_redisplay () ...@@ -409,10 +447,12 @@ rl_redisplay ()
/* Mark the line as modified or not. We only do this for history /* Mark the line as modified or not. We only do this for history
lines. */ lines. */
modmark = 0;
if (_rl_mark_modified_lines && current_history () && rl_undo_list) if (_rl_mark_modified_lines && current_history () && rl_undo_list)
{ {
line[out++] = '*'; line[out++] = '*';
line[out] = '\0'; line[out] = '\0';
modmark = 1;
} }
/* If someone thought that the redisplay was handled, but the currently /* If someone thought that the redisplay was handled, but the currently
...@@ -466,7 +506,7 @@ rl_redisplay () ...@@ -466,7 +506,7 @@ rl_redisplay ()
} }
} }
pmtlen = strlen (prompt_this_line); prompt_physical_chars = pmtlen = strlen (prompt_this_line);
temp = pmtlen + out + 2; temp = pmtlen + out + 2;
if (temp >= line_size) if (temp >= line_size)
{ {
...@@ -525,7 +565,12 @@ rl_redisplay () ...@@ -525,7 +565,12 @@ rl_redisplay ()
/* inv_lbreaks[i] is where line i starts in the buffer. */ /* inv_lbreaks[i] is where line i starts in the buffer. */
inv_lbreaks[newlines = 0] = 0; inv_lbreaks[newlines = 0] = 0;
#if 0
lpos = out - wrap_offset; lpos = out - wrap_offset;
#else
lpos = prompt_physical_chars + modmark;
#endif
#if defined (HANDLE_MULTIBYTE) #if defined (HANDLE_MULTIBYTE)
memset (_rl_wrapped_line, 0, vis_lbsize); memset (_rl_wrapped_line, 0, vis_lbsize);
#endif #endif
...@@ -544,14 +589,12 @@ rl_redisplay () ...@@ -544,14 +589,12 @@ rl_redisplay ()
prompt_invis_chars_first_line variable could be made into an array prompt_invis_chars_first_line variable could be made into an array
saying how many invisible characters there are per line, but that's saying how many invisible characters there are per line, but that's
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> */
temp = ((newlines + 1) * _rl_screenwidth) + temp = ((newlines + 1) * _rl_screenwidth) +
#if 0 ((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
((newlines == 0) ? prompt_invis_chars_first_line : 0) + : ((newlines == 1) ? wrap_offset : 0))
#else : ((newlines == 0) ? wrap_offset :0));
((newlines == 0 && local_prompt_prefix == 0) ? prompt_invis_chars_first_line : 0) +
#endif
((newlines == 1) ? wrap_offset : 0);
inv_lbreaks[++newlines] = temp; inv_lbreaks[++newlines] = temp;
lpos -= _rl_screenwidth; lpos -= _rl_screenwidth;
...@@ -584,7 +627,7 @@ rl_redisplay () ...@@ -584,7 +627,7 @@ rl_redisplay ()
#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 (wc_bytes == (size_t)-1 || wc_bytes == (size_t)-2) if (MB_INVALIDCH (wc_bytes))
{ {
/* Byte sequence is invalid or shortened. Assume that the /* Byte sequence is invalid or shortened. Assume that the
first byte represents a character. */ first byte represents a character. */
...@@ -593,12 +636,12 @@ rl_redisplay () ...@@ -593,12 +636,12 @@ rl_redisplay ()
wc_width = 1; wc_width = 1;
memset (&ps, 0, sizeof (mbstate_t)); memset (&ps, 0, sizeof (mbstate_t));
} }
else if (wc_bytes == (size_t)0) else if (MB_NULLWCH (wc_bytes))
break; /* Found '\0' */ break; /* Found '\0' */
else else
{ {
temp = wcwidth (wc); temp = wcwidth (wc);
wc_width = (temp < 0) ? 1 : temp; wc_width = (temp >= 0) ? temp : 1;
} }
} }
#endif #endif
...@@ -788,7 +831,7 @@ rl_redisplay () ...@@ -788,7 +831,7 @@ 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. */
...@@ -829,7 +872,7 @@ rl_redisplay () ...@@ -829,7 +872,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;
...@@ -865,7 +908,7 @@ rl_redisplay () ...@@ -865,7 +908,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);
else else
_rl_last_c_pos = nleft; _rl_last_c_pos = nleft;
} }
...@@ -1067,12 +1110,12 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) ...@@ -1067,12 +1110,12 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
memset (&ps, 0, sizeof (mbstate_t)); memset (&ps, 0, sizeof (mbstate_t));
ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps); ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
if (ret == (size_t)-1 || ret == (size_t)-2) if (MB_INVALIDCH (ret))
{ {
tempwidth = 1; tempwidth = 1;
ret = 1; ret = 1;
} }
else if (ret == 0) else if (MB_NULLWCH (ret))
tempwidth = 0; tempwidth = 0;
else else
tempwidth = wcwidth (wc); tempwidth = wcwidth (wc);
...@@ -1089,7 +1132,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) ...@@ -1089,7 +1132,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps); ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
if (ret != 0 && bytes != 0) if (ret != 0 && bytes != 0)
{ {
if (ret == (size_t)-1 || ret == (size_t)-2) if (MB_INVALIDCH (ret))
memmove (old+bytes, old+1, strlen (old+1)); memmove (old+bytes, old+1, strlen (old+1));
else else
memmove (old+bytes, old+ret, strlen (old+ret)); memmove (old+bytes, old+ret, strlen (old+ret));
...@@ -1123,10 +1166,27 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) ...@@ -1123,10 +1166,27 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
/* Find first difference. */ /* Find first difference. */
#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)
{
/* See if the old line is a subset of the new line, so that the
only change is adding characters. */
temp = (omax < nmax) ? omax : nmax;
if (memcmp (old, new, temp) == 0)
{
ofd = old + temp;
nfd = new + temp;
}
else
{ {
memset (&ps_new, 0, sizeof(mbstate_t)); memset (&ps_new, 0, sizeof(mbstate_t));
memset (&ps_old, 0, sizeof(mbstate_t)); memset (&ps_old, 0, sizeof(mbstate_t));
if (omax == nmax && STREQN (new, old, omax))
{
ofd = old + omax;
nfd = new + nmax;
}
else
{
new_offset = old_offset = 0; new_offset = old_offset = 0;
for (ofd = old, nfd = new; for (ofd = old, nfd = new;
(ofd - old < omax) && *ofd && (ofd - old < omax) && *ofd &&
...@@ -1138,6 +1198,8 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) ...@@ -1138,6 +1198,8 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
nfd = new + new_offset; nfd = new + new_offset;
} }
} }
}
}
else else
#endif #endif
for (ofd = old, nfd = new; for (ofd = old, nfd = new;
...@@ -1167,8 +1229,11 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) ...@@ -1167,8 +1229,11 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
memset (&ps_old, 0, sizeof (mbstate_t)); memset (&ps_old, 0, sizeof (mbstate_t));
memset (&ps_new, 0, sizeof (mbstate_t)); memset (&ps_new, 0, sizeof (mbstate_t));
#if 0
/* On advice from jir@yamato.ibm.com */
_rl_adjust_point (old, ols - old, &ps_old); _rl_adjust_point (old, ols - old, &ps_old);
_rl_adjust_point (new, nls - new, &ps_new); _rl_adjust_point (new, nls - new, &ps_new);
#endif
if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0) if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
break; break;
...@@ -1322,7 +1387,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) ...@@ -1322,7 +1387,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) else if (*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. */
...@@ -1345,10 +1410,14 @@ update_line (old, new, current_line, omax, nmax, inv_botlin) ...@@ -1345,10 +1410,14 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
if ((temp - lendiff) > 0) if ((temp - lendiff) > 0)
{ {
_rl_output_some_chars (nfd + lendiff, temp - lendiff); _rl_output_some_chars (nfd + lendiff, temp - lendiff);
#if 0 #if 1
_rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff) - col_lendiff; /* XXX -- this bears closer inspection. Fixes a redisplay bug
#else reported against bash-3.0-alpha by Andreas Schwab involving
multibyte characters and prompt strings with invisible
characters, but was previously disabled. */
_rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff); _rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
#else
_rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff);
#endif #endif
} }
} }
...@@ -1424,12 +1493,13 @@ rl_on_new_line () ...@@ -1424,12 +1493,13 @@ rl_on_new_line ()
/* Tell the update routines that we have moved onto a new line with the /* Tell the update routines that we have moved onto a new line with the
prompt already displayed. Code originally from the version of readline prompt already displayed. Code originally from the version of readline
distributed with CLISP. */ distributed with CLISP. rl_expand_prompt must have already been called
(explicitly or implicitly). This still doesn't work exactly right. */
int int
rl_on_new_line_with_prompt () rl_on_new_line_with_prompt ()
{ {
int prompt_size, i, l, real_screenwidth, newlines; int prompt_size, i, l, real_screenwidth, newlines;
char *prompt_last_line; char *prompt_last_line, *lprompt;
/* Initialize visible_line and invisible_line to ensure that they can hold /* Initialize visible_line and invisible_line to ensure that they can hold
the already-displayed prompt. */ the already-displayed prompt. */
...@@ -1438,8 +1508,9 @@ rl_on_new_line_with_prompt () ...@@ -1438,8 +1508,9 @@ rl_on_new_line_with_prompt ()
/* Make sure the line structures hold the already-displayed prompt for /* Make sure the line structures hold the already-displayed prompt for
redisplay. */ redisplay. */
strcpy (visible_line, rl_prompt); lprompt = local_prompt ? local_prompt : rl_prompt;
strcpy (invisible_line, rl_prompt); strcpy (visible_line, lprompt);
strcpy (invisible_line, lprompt);
/* If the prompt contains newlines, take the last tail. */ /* If the prompt contains newlines, take the last tail. */
prompt_last_line = strrchr (rl_prompt, '\n'); prompt_last_line = strrchr (rl_prompt, '\n');
...@@ -1474,6 +1545,8 @@ rl_on_new_line_with_prompt () ...@@ -1474,6 +1545,8 @@ rl_on_new_line_with_prompt ()
vis_lbreaks[newlines] = l; vis_lbreaks[newlines] = l;
visible_wrap_offset = 0; visible_wrap_offset = 0;
rl_display_prompt = rl_prompt; /* XXX - make sure it's set */
return 0; return 0;
} }
...@@ -1508,8 +1581,15 @@ _rl_move_cursor_relative (new, data) ...@@ -1508,8 +1581,15 @@ _rl_move_cursor_relative (new, data)
#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. */ this case, NEW's display position is not obvious and must be
if ((MB_CUR_MAX == 1 || rl_byte_oriented ) && _rl_last_c_pos == new) return; calculated. */
if (MB_CUR_MAX == 1 || rl_byte_oriented)
{
if (_rl_last_c_pos == new)
return;
}
else if (_rl_last_c_pos == _rl_col_width (data, 0, new))
return;
#else #else
if (_rl_last_c_pos == new) return; if (_rl_last_c_pos == new) return;
#endif #endif
...@@ -1592,11 +1672,7 @@ _rl_move_cursor_relative (new, data) ...@@ -1592,11 +1672,7 @@ _rl_move_cursor_relative (new, data)
#endif #endif
{ {
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{ _rl_backspace (_rl_last_c_pos - _rl_col_width (data, 0, new));
tputs (_rl_term_cr, 1, _rl_output_character_function);
for (i = 0; i < new; i++)
putc (data[i], rl_outstream);
}
else else
_rl_backspace (_rl_last_c_pos - new); _rl_backspace (_rl_last_c_pos - new);
} }
...@@ -1734,7 +1810,6 @@ rl_message (va_alist) ...@@ -1734,7 +1810,6 @@ rl_message (va_alist)
int int
rl_message (format, arg1, arg2) rl_message (format, arg1, arg2)
char *format; char *format;
int 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? */
...@@ -1763,10 +1838,14 @@ rl_reset_line_state () ...@@ -1763,10 +1838,14 @@ rl_reset_line_state ()
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_prompt;
static char *saved_local_prefix; static char *saved_local_prefix;
static int saved_last_invisible; static int saved_last_invisible;
static int saved_visible_length; 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 ()
...@@ -1775,9 +1854,12 @@ rl_save_prompt () ...@@ -1775,9 +1854,12 @@ rl_save_prompt ()
saved_local_prefix = local_prompt_prefix; saved_local_prefix = local_prompt_prefix;
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_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; prompt_last_invisible = prompt_visible_length = 0;
prompt_invis_chars_first_line = prompt_physical_chars = 0;
} }
void void
...@@ -1790,6 +1872,8 @@ rl_restore_prompt () ...@@ -1790,6 +1872,8 @@ rl_restore_prompt ()
local_prompt_prefix = saved_local_prefix; local_prompt_prefix = saved_local_prefix;
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_physical_chars = saved_physical_chars;
} }
char * char *
...@@ -1822,6 +1906,7 @@ _rl_make_prompt_for_search (pchar) ...@@ -1822,6 +1906,7 @@ _rl_make_prompt_for_search (pchar)
prompt_last_invisible = saved_last_invisible; prompt_last_invisible = saved_last_invisible;
prompt_visible_length = saved_visible_length + 1; prompt_visible_length = saved_visible_length + 1;
} }
return pmt; return pmt;
} }
...@@ -1997,9 +2082,8 @@ static void ...@@ -1997,9 +2082,8 @@ static void
redraw_prompt (t) redraw_prompt (t)
char *t; char *t;
{ {
const char *oldp; char *oldp, *oldl, *oldlprefix;
char *oldl, *oldlprefix; int oldlen, oldlast, oldplen, oldninvis, oldphyschars;
int oldlen, oldlast, oldplen, oldninvis;
/* Geez, I should make this a struct. */ /* Geez, I should make this a struct. */
oldp = rl_display_prompt; oldp = rl_display_prompt;
...@@ -2009,11 +2093,13 @@ redraw_prompt (t) ...@@ -2009,11 +2093,13 @@ redraw_prompt (t)
oldplen = prompt_prefix_length; oldplen = prompt_prefix_length;
oldlast = prompt_last_invisible; oldlast = prompt_last_invisible;
oldninvis = prompt_invis_chars_first_line; 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,
&prompt_last_invisible, &prompt_last_invisible,
&prompt_invis_chars_first_line); &prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)NULL; local_prompt_prefix = (char *)NULL;
rl_forced_update_display (); rl_forced_update_display ();
...@@ -2024,6 +2110,7 @@ redraw_prompt (t) ...@@ -2024,6 +2110,7 @@ redraw_prompt (t)
prompt_prefix_length = oldplen; prompt_prefix_length = oldplen;
prompt_last_invisible = oldlast; prompt_last_invisible = oldlast;
prompt_invis_chars_first_line = oldninvis; 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. */
...@@ -2133,7 +2220,7 @@ _rl_col_width (str, start, end) ...@@ -2133,7 +2220,7 @@ _rl_col_width (str, start, end)
while (point < start) while (point < start)
{ {
tmp = mbrlen (str + point, max, &ps); tmp = mbrlen (str + point, max, &ps);
if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2) if (MB_INVALIDCH ((size_t)tmp))
{ {
/* In this case, the bytes are invalid or too short to compose a /* In this case, the bytes are invalid or too short to compose a
multibyte character, so we assume that the first byte represents multibyte character, so we assume that the first byte represents
...@@ -2145,7 +2232,7 @@ _rl_col_width (str, start, end) ...@@ -2145,7 +2232,7 @@ _rl_col_width (str, start, end)
effect of mbstate is undefined. */ effect of mbstate is undefined. */
memset (&ps, 0, sizeof (mbstate_t)); memset (&ps, 0, sizeof (mbstate_t));
} }
else if (tmp == 0) else if (MB_NULLWCH (tmp))
break; /* Found '\0' */ break; /* Found '\0' */
else else
{ {
...@@ -2162,7 +2249,7 @@ _rl_col_width (str, start, end) ...@@ -2162,7 +2249,7 @@ _rl_col_width (str, start, end)
while (point < end) while (point < end)
{ {
tmp = mbrtowc (&wc, str + point, max, &ps); tmp = mbrtowc (&wc, str + point, max, &ps);
if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2) if (MB_INVALIDCH ((size_t)tmp))
{ {
/* In this case, the bytes are invalid or too short to compose a /* In this case, the bytes are invalid or too short to compose a
multibyte character, so we assume that the first byte represents multibyte character, so we assume that the first byte represents
...@@ -2177,7 +2264,7 @@ _rl_col_width (str, start, end) ...@@ -2177,7 +2264,7 @@ _rl_col_width (str, start, end)
effect of mbstate is undefined. */ effect of mbstate is undefined. */
memset (&ps, 0, sizeof (mbstate_t)); memset (&ps, 0, sizeof (mbstate_t));
} }
else if (tmp == 0) else if (MB_NULLWCH (tmp))
break; /* Found '\0' */ break; /* Found '\0' */
else else
{ {
...@@ -2193,4 +2280,3 @@ _rl_col_width (str, start, end) ...@@ -2193,4 +2280,3 @@ _rl_col_width (str, start, end)
return width; return width;
} }
#endif /* HANDLE_MULTIBYTE */ #endif /* HANDLE_MULTIBYTE */
...@@ -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>
...@@ -129,6 +131,7 @@ static FUNMAP default_funmap[] = { ...@@ -129,6 +131,7 @@ static FUNMAP default_funmap[] = {
{ "tty-status", rl_tty_status }, { "tty-status", rl_tty_status },
{ "undo", rl_undo_command }, { "undo", rl_undo_command },
{ "universal-argument", rl_universal_argument }, { "universal-argument", rl_universal_argument },
{ "unix-filename-rubout", rl_unix_filename_rubout },
{ "unix-line-discard", rl_unix_line_discard }, { "unix-line-discard", rl_unix_line_discard },
{ "unix-word-rubout", rl_unix_word_rubout }, { "unix-word-rubout", rl_unix_word_rubout },
{ "upcase-word", rl_upcase_word }, { "upcase-word", rl_upcase_word },
......
/* histexpand.c -- history expansion. */ /* histexpand.c -- history expansion. */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. /* Copyright (C) 1989-2004 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.
...@@ -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>
...@@ -50,6 +52,8 @@ ...@@ -50,6 +52,8 @@
#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>" #define HISTORY_WORD_DELIMITERS " \t\n;&()|<>"
#define HISTORY_QUOTE_CHARACTERS "\"'`" #define HISTORY_QUOTE_CHARACTERS "\"'`"
#define slashify_in_quotes "\\`\"$"
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 */ extern int rl_byte_oriented; /* declared in mbutil.c */
...@@ -63,6 +67,8 @@ static int subst_rhs_len; ...@@ -63,6 +67,8 @@ static int subst_rhs_len;
static char *get_history_word_specifier PARAMS((char *, char *, int *)); static char *get_history_word_specifier PARAMS((char *, char *, int *));
static char *history_find_word PARAMS((char *, int)); static char *history_find_word PARAMS((char *, int));
static int history_tokenize_word PARAMS((const char *, int));
static char *history_substring PARAMS((const char *, int, int));
static char *quote_breaks PARAMS((char *)); static char *quote_breaks PARAMS((char *));
...@@ -83,14 +89,14 @@ char history_comment_char = '\0'; ...@@ -83,14 +89,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. */
const char *history_no_expand_chars = " \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. */
const char *history_word_delimiters = 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. */
...@@ -199,7 +205,7 @@ get_history_event (string, caller_index, delimiting_quote) ...@@ -199,7 +205,7 @@ 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)
{ {
...@@ -209,8 +215,8 @@ get_history_event (string, caller_index, delimiting_quote) ...@@ -209,8 +215,8 @@ get_history_event (string, caller_index, delimiting_quote)
memset (&ps, 0, sizeof (mbstate_t)); memset (&ps, 0, sizeof (mbstate_t));
/* These produce warnings because we're passing a const string to a /* These produce warnings because we're passing a const string to a
function that takes a non-const string. */ function that takes a non-const string. */
_rl_adjust_point (string, i, &ps); _rl_adjust_point ((char *)string, i, &ps);
if ((v = _rl_get_char_len (string + i, &ps)) > 1) if ((v = _rl_get_char_len ((char *)string + i, &ps)) > 1)
{ {
i += v - 1; i += v - 1;
continue; continue;
...@@ -515,7 +521,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) ...@@ -515,7 +521,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
char *current_line; /* for !# */ char *current_line; /* for !# */
{ {
int i, n, starting_index; int i, n, starting_index;
int substitute_globally, want_quotes, print_only; int substitute_globally, subst_bywords, want_quotes, print_only;
char *event, *temp, *result, *tstr, *t, c, *word_spec; char *event, *temp, *result, *tstr, *t, c, *word_spec;
int result_len; int result_len;
#if defined (HANDLE_MULTIBYTE) #if defined (HANDLE_MULTIBYTE)
...@@ -597,19 +603,25 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) ...@@ -597,19 +603,25 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
FREE (word_spec); FREE (word_spec);
/* Perhaps there are other modifiers involved. Do what they say. */ /* Perhaps there are other modifiers involved. Do what they say. */
want_quotes = substitute_globally = print_only = 0; want_quotes = substitute_globally = subst_bywords = print_only = 0;
starting_index = i; starting_index = i;
while (string[i] == ':') while (string[i] == ':')
{ {
c = string[i + 1]; c = string[i + 1];
if (c == 'g') if (c == 'g' || c == 'a')
{ {
substitute_globally = 1; substitute_globally = 1;
i++; i++;
c = string[i + 1]; c = string[i + 1];
} }
else if (c == 'G')
{
subst_bywords = 1;
i++;
c = string[i + 1];
}
switch (c) switch (c)
{ {
...@@ -681,7 +693,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) ...@@ -681,7 +693,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
case 's': case 's':
{ {
char *new_event; char *new_event;
int delimiter, failed, si, l_temp; int delimiter, failed, si, l_temp, ws, we;
if (c == 's') if (c == 's')
{ {
...@@ -758,8 +770,32 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) ...@@ -758,8 +770,32 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
} }
/* Find the first occurrence of THIS in TEMP. */ /* Find the first occurrence of THIS in TEMP. */
si = 0; /* Substitute SUBST_RHS for SUBST_LHS in TEMP. There are three
cases to consider:
1. substitute_globally == subst_bywords == 0
2. substitute_globally == 1 && subst_bywords == 0
3. substitute_globally == 0 && subst_bywords == 1
In the first case, we substitute for the first occurrence only.
In the second case, we substitute for every occurrence.
In the third case, we tokenize into words and substitute the
first occurrence of each word. */
si = we = 0;
for (failed = 1; (si + subst_lhs_len) <= l_temp; si++) for (failed = 1; (si + subst_lhs_len) <= l_temp; si++)
{
/* First skip whitespace and find word boundaries if
we're past the end of the word boundary we found
the last time. */
if (subst_bywords && si > we)
{
for (; temp[si] && whitespace (temp[si]); si++)
;
ws = si;
we = history_tokenize_word (temp, si);
}
if (STREQN (temp+si, subst_lhs, subst_lhs_len)) if (STREQN (temp+si, subst_lhs, subst_lhs_len))
{ {
int len = subst_rhs_len - subst_lhs_len + l_temp; int len = subst_rhs_len - subst_lhs_len + l_temp;
...@@ -777,14 +813,24 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line) ...@@ -777,14 +813,24 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (substitute_globally) if (substitute_globally)
{ {
si += subst_rhs_len; /* Reported to fix a bug that causes it to skip every
other match when matching a single character. Was
si += subst_rhs_len previously. */
si += subst_rhs_len - 1;
l_temp = strlen (temp); l_temp = strlen (temp);
substitute_globally++; substitute_globally++;
continue; continue;
} }
else if (subst_bywords)
{
si = we;
l_temp = strlen (temp);
continue;
}
else else
break; break;
} }
}
if (substitute_globally > 1) if (substitute_globally > 1)
{ {
...@@ -877,7 +923,7 @@ history_expand (hstring, output) ...@@ -877,7 +923,7 @@ history_expand (hstring, output)
char **output; char **output;
{ {
register int j; register int j;
int i, r, l, passc, cc, modified, eindex, only_printing; int i, r, l, passc, cc, modified, eindex, only_printing, dquote;
char *string; char *string;
/* The output string, and its length. */ /* The output string, and its length. */
...@@ -940,7 +986,7 @@ history_expand (hstring, output) ...@@ -940,7 +986,7 @@ history_expand (hstring, output)
/* `!' followed by one of the characters in history_no_expand_chars /* `!' followed by one of the characters in history_no_expand_chars
is NOT an expansion. */ is NOT an expansion. */
for (i = 0; string[i]; i++) for (i = dquote = 0; 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)
...@@ -982,9 +1028,19 @@ history_expand (hstring, output) ...@@ -982,9 +1028,19 @@ history_expand (hstring, output)
else else
break; break;
} }
/* XXX - at some point, might want to extend this to handle /* Shell-like quoting: allow backslashes to quote double quotes
double quotes as well. */ inside a double-quoted string. */
else if (history_quotes_inhibit_expansion && string[i] == '\'') else if (dquote && string[i] == '\\' && cc == '"')
i++;
/* More shell-like quoting: if we're paying attention to single
quotes and letting them quote the history expansion character,
then we need to pay attention to double quotes, because single
quotes are not special inside double-quoted strings. */
else if (history_quotes_inhibit_expansion && string[i] == '"')
{
dquote = 1 - dquote;
}
else if (dquote == 0 && history_quotes_inhibit_expansion && string[i] == '\'')
{ {
/* If this is bash, single quotes inhibit history expansion. */ /* If this is bash, single quotes inhibit history expansion. */
i++; i++;
...@@ -997,6 +1053,7 @@ history_expand (hstring, output) ...@@ -997,6 +1053,7 @@ history_expand (hstring, output)
if (cc == '\'' || cc == history_expansion_char) if (cc == '\'' || cc == history_expansion_char)
i++; i++;
} }
} }
if (string[i] != history_expansion_char) if (string[i] != history_expansion_char)
...@@ -1008,7 +1065,7 @@ history_expand (hstring, output) ...@@ -1008,7 +1065,7 @@ history_expand (hstring, output)
} }
/* Extract and perform the substitution. */ /* Extract and perform the substitution. */
for (passc = i = j = 0; i < l; i++) for (passc = dquote = i = j = 0; i < l; i++)
{ {
int tchar = string[i]; int tchar = string[i];
...@@ -1059,11 +1116,16 @@ history_expand (hstring, output) ...@@ -1059,11 +1116,16 @@ history_expand (hstring, output)
ADD_CHAR (tchar); ADD_CHAR (tchar);
break; break;
case '"':
dquote = 1 - dquote;
ADD_CHAR (tchar);
break;
case '\'': case '\'':
{ {
/* If history_quotes_inhibit_expansion is set, single quotes /* If history_quotes_inhibit_expansion is set, single quotes
inhibit history expansion. */ inhibit history expansion. */
if (history_quotes_inhibit_expansion) if (dquote == 0 && history_quotes_inhibit_expansion)
{ {
int quote, slen; int quote, slen;
...@@ -1158,7 +1220,9 @@ history_expand (hstring, output) ...@@ -1158,7 +1220,9 @@ history_expand (hstring, output)
if (only_printing) if (only_printing)
{ {
#if 0
add_history (result); add_history (result);
#endif
return (2); return (2);
} }
...@@ -1221,7 +1285,10 @@ get_history_word_specifier (spec, from, caller_index) ...@@ -1221,7 +1285,10 @@ get_history_word_specifier (spec, from, caller_index)
if (spec[i] == '-') if (spec[i] == '-')
first = 0; first = 0;
else if (spec[i] == '^') else if (spec[i] == '^')
{
first = 1; first = 1;
i++;
}
else if (_rl_digit_p (spec[i]) && expecting_word_spec) else if (_rl_digit_p (spec[i]) && expecting_word_spec)
{ {
for (first = 0; _rl_digit_p (spec[i]); i++) for (first = 0; _rl_digit_p (spec[i]); i++)
...@@ -1336,44 +1403,21 @@ history_arg_extract (first, last, string) ...@@ -1336,44 +1403,21 @@ history_arg_extract (first, last, string)
return (result); return (result);
} }
#define slashify_in_quotes "\\`\"$" static int
history_tokenize_word (string, ind)
/* Parse STRING into tokens and return an array of strings. If WIND is
not -1 and INDP is not null, we also want the word surrounding index
WIND. The position in the returned array of strings is returned in
*INDP. */
static char **
history_tokenize_internal (string, wind, indp)
const char *string; const char *string;
int wind, *indp; int ind;
{ {
char **result; register int i;
register int i, start, result_index, size; int delimiter;
int len, delimiter;
/* If we're searching for a string that's not part of a word (e.g., " "),
make sure we set *INDP to a reasonable value. */
if (indp && wind != -1)
*indp = -1;
/* Get a token, and stuff it into RESULT. The tokens are split i = ind;
exactly where the shell would split them. */
for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
{
delimiter = 0; delimiter = 0;
/* Skip leading whitespace. */
for (; string[i] && whitespace (string[i]); i++)
;
if (string[i] == 0 || string[i] == history_comment_char)
return (result);
start = i;
if (member (string[i], "()\n")) if (member (string[i], "()\n"))
{ {
i++; i++;
goto got_token; return i;
} }
if (member (string[i], "<>;&|$")) if (member (string[i], "<>;&|$"))
...@@ -1385,22 +1429,24 @@ history_tokenize_internal (string, wind, indp) ...@@ -1385,22 +1429,24 @@ history_tokenize_internal (string, wind, indp)
if (peek == '<' && string[i + 2] == '-') if (peek == '<' && string[i + 2] == '-')
i++; i++;
i += 2; i += 2;
goto got_token; return i;
} }
else else
{ {
if ((peek == '&' && (string[i] == '>' || string[i] == '<')) || if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
((peek == '>') && (string[i] == '&')) || (peek == '>' && string[i] == '&') ||
((peek == '(') && (string[i] == '$'))) (peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
(peek == '(' && string[i] == '$')) /* ) */
{ {
i += 2; i += 2;
goto got_token; return i;
} }
} }
if (string[i] != '$') if (string[i] != '$')
{ {
i++; i++;
goto got_token; return i;
} }
} }
...@@ -1437,20 +1483,76 @@ history_tokenize_internal (string, wind, indp) ...@@ -1437,20 +1483,76 @@ history_tokenize_internal (string, wind, indp)
delimiter = string[i]; delimiter = string[i];
} }
got_token: return i;
}
static char *
history_substring (string, start, end)
const char *string;
int start, end;
{
register int len;
register char *result;
len = end - start;
result = (char *)xmalloc (len + 1);
strncpy (result, string + start, len);
result[len] = '\0';
return result;
}
/* Parse STRING into tokens and return an array of strings. If WIND is
not -1 and INDP is not null, we also want the word surrounding index
WIND. The position in the returned array of strings is returned in
*INDP. */
static char **
history_tokenize_internal (string, wind, indp)
const char *string;
int wind, *indp;
{
char **result;
register int i, start, result_index, size;
/* If we're searching for a string that's not part of a word (e.g., " "),
make sure we set *INDP to a reasonable value. */
if (indp && wind != -1)
*indp = -1;
/* Get a token, and stuff it into RESULT. The tokens are split
exactly where the shell would split them. */
for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
{
/* Skip leading whitespace. */
for (; string[i] && whitespace (string[i]); i++)
;
if (string[i] == 0 || string[i] == history_comment_char)
return (result);
start = i;
i = history_tokenize_word (string, start);
/* If we have a non-whitespace delimiter character (which would not be
skipped by the loop above), use it and any adjacent delimiters to
make a separate field. Any adjacent white space will be skipped the
next time through the loop. */
if (i == start && history_word_delimiters)
{
i++;
while (string[i] && member (string[i], history_word_delimiters))
i++;
}
/* If we are looking for the word in which the character at a /* If we are looking for the word in which the character at a
particular index falls, remember it. */ particular index falls, remember it. */
if (indp && wind != -1 && wind >= start && wind < i) if (indp && wind != -1 && wind >= start && wind < i)
*indp = result_index; *indp = result_index;
len = i - start;
if (result_index + 2 >= size) if (result_index + 2 >= size)
result = (char **)xrealloc (result, ((size += 10) * sizeof (char *))); result = (char **)xrealloc (result, ((size += 10) * sizeof (char *)));
result[result_index] = (char *)xmalloc (1 + len);
strncpy (result[result_index], string + start, len); result[result_index++] = history_substring (string, start, i);
result[result_index][len] = '\0'; result[result_index] = (char *)NULL;
result[++result_index] = (char *)NULL;
} }
return (result); return (result);
......
/* histfile.c - functions to manipulate the history file. */ /* histfile.c - functions to manipulate the history file. */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. /* Copyright (C) 1989-2003 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.
...@@ -23,14 +23,21 @@ ...@@ -23,14 +23,21 @@
/* The goal is to make the implementation transparent, so that you /* The goal is to make the implementation transparent, so that you
don't have to know what data types are used, just what functions don't have to know what data types are used, just what functions
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 (__TANDEM)
# include <floss.h>
#endif
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#ifndef _MINIX #if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h> # include <sys/file.h>
#endif #endif
#include "posixstat.h" #include "posixstat.h"
...@@ -50,7 +57,7 @@ ...@@ -50,7 +57,7 @@
# undef HAVE_MMAP # undef HAVE_MMAP
#endif #endif
#ifdef HAVE_MMAP #ifdef HISTORY_USE_MMAP
# include <sys/mman.h> # include <sys/mman.h>
# ifdef MAP_FILE # ifdef MAP_FILE
...@@ -65,7 +72,7 @@ ...@@ -65,7 +72,7 @@
# define MAP_FAILED ((void *)-1) # define MAP_FAILED ((void *)-1)
# endif # endif
#endif /* HAVE_MMAP */ #endif /* HISTORY_USE_MMAP */
/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment /* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
on win 95/98/nt), we want to open files with O_BINARY mode so that there on win 95/98/nt), we want to open files with O_BINARY mode so that there
...@@ -91,6 +98,13 @@ extern int errno; ...@@ -91,6 +98,13 @@ extern int errno;
#include "rlshell.h" #include "rlshell.h"
#include "xmalloc.h" #include "xmalloc.h"
/* If non-zero, we write timestamps to the history file in history_do_write() */
int history_write_timestamps = 0;
/* Does S look like the beginning of a history timestamp entry? Placeholder
for more extensive tests. */
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char)
/* Return the string that should be used in the place of this /* Return the string that should be used in the place of this
filename. This only matters when you don't specify the filename. This only matters when you don't specify the
filename to read_history (), or write_history (). */ filename to read_history (), or write_history (). */
...@@ -149,13 +163,20 @@ read_history_range (filename, from, to) ...@@ -149,13 +163,20 @@ read_history_range (filename, from, to)
const char *filename; const char *filename;
int from, to; int from, to;
{ {
register char *line_start, *line_end; register char *line_start, *line_end, *p;
char *input, *buffer, *bufend; char *input, *buffer, *bufend, *last_ts;
int file, current_line, chars_read; int file, current_line, chars_read;
struct stat finfo; struct stat finfo;
size_t file_size; size_t file_size;
#if defined (EFBIG)
int overflow_errno = EFBIG;
#elif defined (EOVERFLOW)
int overflow_errno = EOVERFLOW;
#else
int overflow_errno = EIO;
#endif
buffer = (char *)NULL; buffer = last_ts = (char *)NULL;
input = history_filename (filename); input = history_filename (filename);
file = open (input, O_RDONLY|O_BINARY, 0666); file = open (input, O_RDONLY|O_BINARY, 0666);
...@@ -167,37 +188,42 @@ read_history_range (filename, from, to) ...@@ -167,37 +188,42 @@ read_history_range (filename, from, to)
/* check for overflow on very large files */ /* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size) if (file_size != finfo.st_size || file_size + 1 < file_size)
{ {
#if defined (EFBIG) errno = overflow_errno;
errno = EFBIG;
#elif defined (EOVERFLOW)
errno = EOVERFLOW;
#endif
goto error_and_exit; goto error_and_exit;
} }
#ifdef HAVE_MMAP #ifdef HISTORY_USE_MMAP
/* We map read/write and private so we can change newlines to NULs without /* We map read/write and private so we can change newlines to NULs without
affecting the underlying object. */ affecting the underlying object. */
buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0); buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0);
if ((void *)buffer == MAP_FAILED) if ((void *)buffer == MAP_FAILED)
{
errno = overflow_errno;
goto error_and_exit; goto error_and_exit;
}
chars_read = file_size; chars_read = file_size;
#else #else
buffer = (char *)malloc (file_size + 1); buffer = (char *)malloc (file_size + 1);
if (buffer == 0) if (buffer == 0)
{
errno = overflow_errno;
goto error_and_exit; goto error_and_exit;
}
chars_read = read (file, buffer, file_size); chars_read = read (file, buffer, file_size);
#endif #endif
if (chars_read < 0) if (chars_read < 0)
{ {
error_and_exit: error_and_exit:
if (errno != 0)
chars_read = errno; chars_read = errno;
else
chars_read = EIO;
if (file >= 0) if (file >= 0)
close (file); close (file);
FREE (input); FREE (input);
#ifndef HAVE_MMAP #ifndef HISTORY_USE_MMAP
FREE (buffer); FREE (buffer);
#endif #endif
...@@ -218,8 +244,12 @@ read_history_range (filename, from, to) ...@@ -218,8 +244,12 @@ read_history_range (filename, from, to)
for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++) for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
if (*line_end == '\n') if (*line_end == '\n')
{ {
p = line_end + 1;
/* If we see something we think is a timestamp, continue with this
line. We should check more extensively here... */
if (HIST_TIMESTAMP_START(p) == 0)
current_line++; current_line++;
line_start = line_end + 1; line_start = p;
} }
/* If there are lines left to gobble, then gobble them now. */ /* If there are lines left to gobble, then gobble them now. */
...@@ -229,7 +259,22 @@ read_history_range (filename, from, to) ...@@ -229,7 +259,22 @@ read_history_range (filename, from, to)
*line_end = '\0'; *line_end = '\0';
if (*line_start) if (*line_start)
{
if (HIST_TIMESTAMP_START(line_start) == 0)
{
add_history (line_start); add_history (line_start);
if (last_ts)
{
add_history_time (last_ts);
last_ts = NULL;
}
}
else
{
last_ts = line_start;
current_line--;
}
}
current_line++; current_line++;
...@@ -240,7 +285,7 @@ read_history_range (filename, from, to) ...@@ -240,7 +285,7 @@ read_history_range (filename, from, to)
} }
FREE (input); FREE (input);
#ifndef HAVE_MMAP #ifndef HISTORY_USE_MMAP
FREE (buffer); FREE (buffer);
#else #else
munmap (buffer, file_size); munmap (buffer, file_size);
...@@ -257,7 +302,7 @@ history_truncate_file (fname, lines) ...@@ -257,7 +302,7 @@ history_truncate_file (fname, lines)
const char *fname; const char *fname;
int lines; int lines;
{ {
char *buffer, *filename, *bp; char *buffer, *filename, *bp, *bp1; /* bp1 == bp+1 */
int file, chars_read, rv; int file, chars_read, rv;
struct stat finfo; struct stat finfo;
size_t file_size; size_t file_size;
...@@ -320,11 +365,14 @@ history_truncate_file (fname, lines) ...@@ -320,11 +365,14 @@ history_truncate_file (fname, lines)
} }
/* Count backwards from the end of buffer until we have passed /* Count backwards from the end of buffer until we have passed
LINES lines. */ LINES lines. bp1 is set funny initially. But since bp[1] can't
for (bp = buffer + chars_read - 1; lines && bp > buffer; bp--) be a comment character (since it's off the end) and *bp can't be
both a newline and the history comment character, it should be OK. */
for (bp1 = bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
{ {
if (*bp == '\n') if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
lines--; lines--;
bp1 = bp;
} }
/* If this is the first line, then the file contains exactly the /* If this is the first line, then the file contains exactly the
...@@ -333,11 +381,14 @@ history_truncate_file (fname, lines) ...@@ -333,11 +381,14 @@ history_truncate_file (fname, lines)
the current value of i and 0. Otherwise, write from the start of the current value of i and 0. Otherwise, write from the start of
this line until the end of the buffer. */ this line until the end of the buffer. */
for ( ; bp > buffer; bp--) for ( ; bp > buffer; bp--)
if (*bp == '\n') {
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
{ {
bp++; bp++;
break; break;
} }
bp1 = bp;
}
/* Write only if there are more lines in the file than we want to /* Write only if there are more lines in the file than we want to
truncate to. */ truncate to. */
...@@ -372,9 +423,9 @@ history_do_write (filename, nelements, overwrite) ...@@ -372,9 +423,9 @@ history_do_write (filename, nelements, overwrite)
register int i; register int i;
char *output; char *output;
int file, mode, rv; int file, mode, rv;
#ifdef HISTORY_USE_MMAP
size_t cursize; size_t cursize;
#ifdef HAVE_MMAP
mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY; mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
#else #else
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY; mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
...@@ -388,7 +439,7 @@ history_do_write (filename, nelements, overwrite) ...@@ -388,7 +439,7 @@ history_do_write (filename, nelements, overwrite)
return (errno); return (errno);
} }
#ifdef HAVE_MMAP #ifdef HISTORY_USE_MMAP
cursize = overwrite ? 0 : lseek (file, 0, SEEK_END); cursize = overwrite ? 0 : lseek (file, 0, SEEK_END);
#endif #endif
...@@ -406,10 +457,18 @@ history_do_write (filename, nelements, overwrite) ...@@ -406,10 +457,18 @@ history_do_write (filename, nelements, overwrite)
the_history = history_list (); the_history = history_list ();
/* Calculate the total number of bytes to write. */ /* Calculate the total number of bytes to write. */
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++) for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
buffer_size += 1 + strlen (the_history[i]->line); #if 0
buffer_size += 2 + HISTENT_BYTES (the_history[i]);
#else
{
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
buffer_size += strlen (the_history[i]->timestamp) + 1;
buffer_size += strlen (the_history[i]->line) + 1;
}
#endif
/* Allocate the buffer, and fill it. */ /* Allocate the buffer, and fill it. */
#ifdef HAVE_MMAP #ifdef HISTORY_USE_MMAP
if (ftruncate (file, buffer_size+cursize) == -1) if (ftruncate (file, buffer_size+cursize) == -1)
goto mmap_error; goto mmap_error;
buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize); buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize);
...@@ -434,12 +493,18 @@ history_do_write (filename, nelements, overwrite) ...@@ -434,12 +493,18 @@ history_do_write (filename, nelements, overwrite)
for (j = 0, i = history_length - nelements; i < history_length; i++) for (j = 0, i = history_length - nelements; i < history_length; i++)
{ {
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
{
strcpy (buffer + j, the_history[i]->timestamp);
j += strlen (the_history[i]->timestamp);
buffer[j++] = '\n';
}
strcpy (buffer + j, the_history[i]->line); strcpy (buffer + j, the_history[i]->line);
j += strlen (the_history[i]->line); j += strlen (the_history[i]->line);
buffer[j++] = '\n'; buffer[j++] = '\n';
} }
#ifdef HAVE_MMAP #ifdef HISTORY_USE_MMAP
if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0) if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0)
rv = errno; rv = errno;
#else #else
......
/* History.c -- standalone history library */ /* history.c -- standalone history library */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. /* Copyright (C) 1989-2003 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>
...@@ -50,6 +52,8 @@ ...@@ -50,6 +52,8 @@
/* The number of slots to increase the_history by. */ /* The number of slots to increase the_history by. */
#define DEFAULT_HISTORY_GROW_SIZE 50 #define DEFAULT_HISTORY_GROW_SIZE 50
static char *hist_inittime PARAMS((void));
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
/* History Functions */ /* History Functions */
...@@ -121,14 +125,15 @@ using_history () ...@@ -121,14 +125,15 @@ using_history ()
} }
/* Return the number of bytes that the primary history entries are using. /* Return the number of bytes that the primary history entries are using.
This just adds up the lengths of the_history->lines. */ This just adds up the lengths of the_history->lines and the associated
timestamps. */
int int
history_total_bytes () history_total_bytes ()
{ {
register int i, result; register int i, result;
for (i = result = 0; the_history && the_history[i]; i++) for (i = result = 0; the_history && the_history[i]; i++)
result += strlen (the_history[i]->line); result += HISTENT_BYTES (the_history[i]);
return (result); return (result);
} }
...@@ -204,6 +209,40 @@ history_get (offset) ...@@ -204,6 +209,40 @@ history_get (offset)
: the_history[local_index]; : the_history[local_index];
} }
time_t
history_get_time (hist)
HIST_ENTRY *hist;
{
char *ts;
time_t t;
if (hist == 0 || hist->timestamp == 0)
return 0;
ts = hist->timestamp;
if (ts[0] != history_comment_char)
return 0;
t = (time_t) atol (ts + 1); /* XXX - should use strtol() here */
return t;
}
static char *
hist_inittime ()
{
time_t t;
char ts[64], *ret;
t = (time_t) time ((time_t *)0);
#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
#else
sprintf (ts, "X%lu", (unsigned long) t);
#endif
ret = savestring (ts);
ret[0] = history_comment_char;
return ret;
}
/* Place STRING at the end of the history list. The data field /* Place STRING at the end of the history list. The data field
is set to NULL. */ is set to NULL. */
void void
...@@ -223,10 +262,7 @@ add_history (string) ...@@ -223,10 +262,7 @@ add_history (string)
/* If there is something in the slot, then remove it. */ /* If there is something in the slot, then remove it. */
if (the_history[0]) if (the_history[0])
{ (void) free_history_entry (the_history[0]);
free (the_history[0]->line);
free (the_history[0]);
}
/* Copy the rest of the entries, moving down one slot. */ /* Copy the rest of the entries, moving down one slot. */
for (i = 0; i < history_length; i++) for (i = 0; i < history_length; i++)
...@@ -258,10 +294,41 @@ add_history (string) ...@@ -258,10 +294,41 @@ add_history (string)
temp->line = savestring (string); temp->line = savestring (string);
temp->data = (char *)NULL; 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;
} }
/* Change the time stamp of the most recent history entry to STRING. */
void
add_history_time (string)
const char *string;
{
HIST_ENTRY *hs;
hs = the_history[history_length - 1];
FREE (hs->timestamp);
hs->timestamp = savestring (string);
}
/* Free HIST and return the data so the calling application can free it
if necessary and desired. */
histdata_t
free_history_entry (hist)
HIST_ENTRY *hist;
{
histdata_t x;
if (hist == 0)
return ((histdata_t) 0);
FREE (hist->line);
FREE (hist->timestamp);
x = hist->data;
free (hist);
return (x);
}
/* 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. */
...@@ -281,6 +348,7 @@ replace_history_entry (which, line, data) ...@@ -281,6 +348,7 @@ replace_history_entry (which, line, data)
temp->line = savestring (line); temp->line = savestring (line);
temp->data = data; temp->data = data;
temp->timestamp = savestring (old_value->timestamp);
the_history[which] = temp; the_history[which] = temp;
return (old_value); return (old_value);
...@@ -325,10 +393,7 @@ stifle_history (max) ...@@ -325,10 +393,7 @@ stifle_history (max)
{ {
/* This loses because we cannot free the data. */ /* This loses because we cannot free the data. */
for (i = 0, j = history_length - max; i < j; i++) for (i = 0, j = history_length - max; i < j; i++)
{ free_history_entry (the_history[i]);
free (the_history[i]->line);
free (the_history[i]);
}
history_base = i; history_base = i;
for (j = 0, i = history_length - max; j < max; i++, j++) for (j = 0, i = history_length - max; j < max; i++, j++)
...@@ -370,8 +435,7 @@ clear_history () ...@@ -370,8 +435,7 @@ clear_history ()
/* This loses because we cannot free the data. */ /* This loses because we cannot free the data. */
for (i = 0; i < history_length; i++) for (i = 0; i < history_length; i++)
{ {
free (the_history[i]->line); free_history_entry (the_history[i]);
free (the_history[i]);
the_history[i] = (HIST_ENTRY *)NULL; the_history[i] = (HIST_ENTRY *)NULL;
} }
......
/* History.h -- the names of functions that you can call in history. */ /* history.h -- the names of functions that you can call in history. */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc. /* Copyright (C) 1989-2003 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.
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
extern "C" { extern "C" {
#endif #endif
#include <time.h> /* XXX - for history timestamp code */
#if defined READLINE_LIBRARY #if defined READLINE_LIBRARY
# include "rlstdc.h" # include "rlstdc.h"
# include "rltypedefs.h" # include "rltypedefs.h"
...@@ -43,9 +45,13 @@ typedef char *histdata_t; ...@@ -43,9 +45,13 @@ typedef char *histdata_t;
/* The structure used to store a history entry. */ /* The structure used to store a history entry. */
typedef struct _hist_entry { typedef struct _hist_entry {
char *line; char *line;
char *timestamp; /* char * rather than time_t for read/write */
histdata_t data; histdata_t data;
} HIST_ENTRY; } HIST_ENTRY;
/* Size of the history-library-managed space in history entry HS. */
#define HISTENT_BYTES(hs) (strlen ((hs)->line) + strlen ((hs)->timestamp))
/* A structure used to pass the current state of the history stuff around. */ /* A structure used to pass the current state of the history stuff around. */
typedef struct _hist_state { typedef struct _hist_state {
HIST_ENTRY **entries; /* Pointer to the entries themselves. */ HIST_ENTRY **entries; /* Pointer to the entries themselves. */
...@@ -76,11 +82,19 @@ extern void history_set_history_state PARAMS((HISTORY_STATE *)); ...@@ -76,11 +82,19 @@ extern void history_set_history_state PARAMS((HISTORY_STATE *));
The associated data field (if any) is set to NULL. */ The associated data field (if any) is set to NULL. */
extern void add_history PARAMS((const char *)); extern void add_history PARAMS((const char *));
/* Change the timestamp associated with the most recent history entry to
STRING. */
extern void add_history_time PARAMS((const char *));
/* A reasonably useless function, only here for completeness. WHICH /* A reasonably useless function, only here for completeness. WHICH
is the magic number that tells us which element to delete. The is the magic number that tells us which element to delete. The
elements are numbered from 0. */ elements are numbered from 0. */
extern HIST_ENTRY *remove_history PARAMS((int)); extern HIST_ENTRY *remove_history PARAMS((int));
/* Free the history entry H and return any application-specific data
associated with it. */
extern histdata_t free_history_entry PARAMS((HIST_ENTRY *));
/* 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. */
...@@ -119,6 +133,10 @@ extern HIST_ENTRY *current_history PARAMS((void)); ...@@ -119,6 +133,10 @@ extern HIST_ENTRY *current_history PARAMS((void));
array. OFFSET is relative to history_base. */ array. OFFSET is relative to history_base. */
extern HIST_ENTRY *history_get PARAMS((int)); extern HIST_ENTRY *history_get PARAMS((int));
/* Return the timestamp associated with the HIST_ENTRY * passed as an
argument */
extern time_t history_get_time PARAMS((HIST_ENTRY *));
/* Return the number of bytes that the primary history entries are using. /* Return the number of bytes that the primary history entries are using.
This just adds up the lengths of the_history->lines. */ This just adds up the lengths of the_history->lines. */
extern int history_total_bytes PARAMS((void)); extern int history_total_bytes PARAMS((void));
...@@ -225,12 +243,14 @@ extern int history_length; ...@@ -225,12 +243,14 @@ extern int history_length;
extern int history_max_entries; extern int history_max_entries;
extern char history_expansion_char; extern char history_expansion_char;
extern char history_subst_char; extern char history_subst_char;
extern const char *history_word_delimiters; extern char *history_word_delimiters;
extern char history_comment_char; extern char history_comment_char;
extern const char *history_no_expand_chars; extern char *history_no_expand_chars;
extern char *history_search_delimiter_chars; extern char *history_search_delimiter_chars;
extern int history_quotes_inhibit_expansion; extern int history_quotes_inhibit_expansion;
extern int history_write_timestamps;
/* Backwards compatibility */ /* Backwards compatibility */
extern int max_input_history; extern int max_input_history;
......
...@@ -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)
...@@ -75,11 +77,11 @@ history_search_internal (string, direction, anchored) ...@@ -75,11 +77,11 @@ history_search_internal (string, direction, anchored)
if (string == 0 || *string == '\0') if (string == 0 || *string == '\0')
return (-1); return (-1);
if (!history_length || ((i == history_length) && !reverse)) if (!history_length || ((i >= history_length) && !reverse))
return (-1); return (-1);
if (reverse && (i == history_length)) if (reverse && (i >= history_length))
i--; i = history_length - 1;
#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0) #define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
......
...@@ -21,7 +21,13 @@ ...@@ -21,7 +21,13 @@
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 (__TANDEM)
# include <floss.h>
#endif
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h> #include <fcntl.h>
...@@ -152,6 +158,12 @@ _rl_unget_char (key) ...@@ -152,6 +158,12 @@ _rl_unget_char (key)
return (0); return (0);
} }
int
_rl_pushed_input_available ()
{
return (push_index != pop_index);
}
/* If a character is available to be read, then read it and stuff it into /* If a character is available to be read, then read it and stuff it into
IBUFFER. Otherwise, just return. Returns number of characters read IBUFFER. Otherwise, just return. Returns number of characters read
(0 if none available) and -1 on error (EIO). */ (0 if none available) and -1 on error (EIO). */
...@@ -160,7 +172,7 @@ rl_gather_tyi () ...@@ -160,7 +172,7 @@ rl_gather_tyi ()
{ {
int tty; int tty;
register int tem, result; register int tem, result;
int chars_avail; int chars_avail, k;
char input; char input;
#if defined(HAVE_SELECT) #if defined(HAVE_SELECT)
fd_set readfds, exceptfds; fd_set readfds, exceptfds;
...@@ -200,6 +212,11 @@ rl_gather_tyi () ...@@ -200,6 +212,11 @@ rl_gather_tyi ()
fcntl (tty, F_SETFL, tem); fcntl (tty, F_SETFL, tem);
if (chars_avail == -1 && errno == EAGAIN) if (chars_avail == -1 && errno == EAGAIN)
return 0; return 0;
if (chars_avail == 0) /* EOF */
{
rl_stuff_char (EOF);
return (0);
}
} }
#endif /* O_NDELAY */ #endif /* O_NDELAY */
...@@ -223,7 +240,12 @@ rl_gather_tyi () ...@@ -223,7 +240,12 @@ rl_gather_tyi ()
if (result != -1) if (result != -1)
{ {
while (chars_avail--) while (chars_avail--)
rl_stuff_char ((*rl_getc_function) (rl_instream)); {
k = (*rl_getc_function) (rl_instream);
rl_stuff_char (k);
if (k == NEWLINE || k == RETURN)
break;
}
} }
else else
{ {
...@@ -385,7 +407,7 @@ rl_read_key () ...@@ -385,7 +407,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. */
......
...@@ -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>
...@@ -68,7 +70,7 @@ static char *prev_line_found; ...@@ -68,7 +70,7 @@ static char *prev_line_found;
static char *last_isearch_string; static char *last_isearch_string;
static int last_isearch_string_len; static int last_isearch_string_len;
static const char *default_isearch_terminators = "\033\012"; static char *default_isearch_terminators = "\033\012";
/* 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. */
...@@ -96,7 +98,7 @@ rl_forward_search_history (sign, key) ...@@ -96,7 +98,7 @@ rl_forward_search_history (sign, key)
static void static void
rl_display_search (search_string, reverse_p, where) rl_display_search (search_string, reverse_p, where)
char *search_string; char *search_string;
int reverse_p, where __attribute__((unused)); int reverse_p, where;
{ {
char *message; char *message;
int msglen, searchlen; int msglen, searchlen;
...@@ -144,7 +146,7 @@ rl_display_search (search_string, reverse_p, where) ...@@ -144,7 +146,7 @@ rl_display_search (search_string, reverse_p, where)
backwards. */ backwards. */
static int static int
rl_search_history (direction, invoking_key) rl_search_history (direction, invoking_key)
int direction, invoking_key __attribute__((unused)); int direction, invoking_key;
{ {
/* The string that the user types in to search for. */ /* The string that the user types in to search for. */
char *search_string; char *search_string;
...@@ -184,7 +186,7 @@ rl_search_history (direction, invoking_key) ...@@ -184,7 +186,7 @@ rl_search_history (direction, invoking_key)
/* The list of characters which terminate the search, but are not /* The list of characters which terminate the search, but are not
subsequently executed. If the variable isearch-terminators has subsequently executed. If the variable isearch-terminators has
been set, we use that value, otherwise we use ESC and C-J. */ been set, we use that value, otherwise we use ESC and C-J. */
const char *isearch_terminators; char *isearch_terminators;
RL_SETSTATE(RL_STATE_ISEARCH); RL_SETSTATE(RL_STATE_ISEARCH);
orig_point = rl_point; orig_point = rl_point;
......
...@@ -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>
...@@ -62,11 +64,13 @@ rl_make_bare_keymap () ...@@ -62,11 +64,13 @@ rl_make_bare_keymap ()
keymap[i].function = (rl_command_func_t *)NULL; keymap[i].function = (rl_command_func_t *)NULL;
} }
#if 0
for (i = 'A'; i < ('Z' + 1); i++) for (i = 'A'; i < ('Z' + 1); i++)
{ {
keymap[i].type = ISFUNC; keymap[i].type = ISFUNC;
keymap[i].function = rl_do_lowercase_version; keymap[i].function = rl_do_lowercase_version;
} }
#endif
return (keymap); return (keymap);
} }
...@@ -77,8 +81,9 @@ rl_copy_keymap (map) ...@@ -77,8 +81,9 @@ rl_copy_keymap (map)
Keymap map; Keymap map;
{ {
register int i; register int i;
Keymap temp = rl_make_bare_keymap (); Keymap temp;
temp = rl_make_bare_keymap ();
for (i = 0; i < KEYMAP_SIZE; i++) for (i = 0; i < KEYMAP_SIZE; i++)
{ {
temp[i].type = map[i].type; temp[i].type = map[i].type;
...@@ -107,12 +112,8 @@ rl_make_keymap () ...@@ -107,12 +112,8 @@ rl_make_keymap ()
newmap[CTRL('H')].function = rl_rubout; newmap[CTRL('H')].function = rl_rubout;
#if KEYMAP_SIZE > 128 #if KEYMAP_SIZE > 128
/* Printing characters in some 8-bit character sets. */ /* Printing characters in ISO Latin-1 and some 8-bit character sets. */
for (i = 128; i < 160; i++) for (i = 128; i < 256; i++)
newmap[i].function = rl_insert;
/* ISO Latin-1 printing characters should self-insert. */
for (i = 160; i < 256; i++)
newmap[i].function = rl_insert; newmap[i].function = rl_insert;
#endif /* KEYMAP_SIZE > 128 */ #endif /* KEYMAP_SIZE > 128 */
......
...@@ -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>
...@@ -77,7 +79,7 @@ static int rl_yank_nth_arg_internal PARAMS((int, int, int)); ...@@ -77,7 +79,7 @@ static int rl_yank_nth_arg_internal PARAMS((int, int, int));
of kill material. */ of kill material. */
int int
rl_set_retained_kills (num) rl_set_retained_kills (num)
int num __attribute__((unused)); int num;
{ {
return 0; return 0;
} }
...@@ -294,7 +296,7 @@ rl_backward_kill_line (direction, ignore) ...@@ -294,7 +296,7 @@ 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 (count, ignore) rl_kill_full_line (count, ignore)
int count __attribute__((unused)), ignore __attribute__((unused)); int count, ignore;
{ {
rl_begin_undo_group (); rl_begin_undo_group ();
rl_point = 0; rl_point = 0;
...@@ -312,7 +314,7 @@ rl_kill_full_line (count, ignore) ...@@ -312,7 +314,7 @@ rl_kill_full_line (count, ignore)
using behaviour that they expect. */ using behaviour that they expect. */
int int
rl_unix_word_rubout (count, key) rl_unix_word_rubout (count, key)
int count, key __attribute__((unused)); int count, key;
{ {
int orig_point; int orig_point;
...@@ -337,6 +339,47 @@ rl_unix_word_rubout (count, key) ...@@ -337,6 +339,47 @@ rl_unix_word_rubout (count, key)
if (rl_editing_mode == emacs_mode) if (rl_editing_mode == emacs_mode)
rl_mark = rl_point; rl_mark = rl_point;
} }
return 0;
}
/* This deletes one filename component in a Unix pathname. That is, it
deletes backward to directory separator (`/') or whitespace. */
int
rl_unix_filename_rubout (count, key)
int count, key;
{
int orig_point, c;
if (rl_point == 0)
rl_ding ();
else
{
orig_point = rl_point;
if (count <= 0)
count = 1;
while (count--)
{
c = rl_line_buffer[rl_point - 1];
while (rl_point && (whitespace (c) || c == '/'))
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
while (rl_point && (whitespace (c) == 0) && c != '/')
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
}
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0; return 0;
} }
...@@ -348,7 +391,7 @@ rl_unix_word_rubout (count, key) ...@@ -348,7 +391,7 @@ rl_unix_word_rubout (count, key)
doing. */ doing. */
int int
rl_unix_line_discard (count, key) rl_unix_line_discard (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
if (rl_point == 0) if (rl_point == 0)
rl_ding (); rl_ding ();
...@@ -385,7 +428,7 @@ region_kill_internal (delete) ...@@ -385,7 +428,7 @@ 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 (count, ignore) rl_copy_region_to_kill (count, ignore)
int count __attribute__((unused)), ignore __attribute__((unused)); int count, ignore;
{ {
return (region_kill_internal (0)); return (region_kill_internal (0));
} }
...@@ -393,7 +436,7 @@ rl_copy_region_to_kill (count, ignore) ...@@ -393,7 +436,7 @@ rl_copy_region_to_kill (count, ignore)
/* Kill the text between the point and mark. */ /* Kill the text between the point and mark. */
int int
rl_kill_region (count, ignore) rl_kill_region (count, ignore)
int count __attribute__((unused)), ignore __attribute__((unused)); int count, ignore;
{ {
int r, npoint; int r, npoint;
...@@ -458,7 +501,7 @@ rl_copy_backward_word (count, key) ...@@ -458,7 +501,7 @@ 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 (count, ignore) rl_yank (count, ignore)
int count __attribute__((unused)), ignore __attribute__((unused)); int count, ignore;
{ {
if (rl_kill_ring == 0) if (rl_kill_ring == 0)
{ {
...@@ -477,7 +520,7 @@ rl_yank (count, ignore) ...@@ -477,7 +520,7 @@ rl_yank (count, ignore)
yank back some other text. */ yank back some other text. */
int int
rl_yank_pop (count, key) rl_yank_pop (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
int l, n; int l, n;
......
...@@ -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>
...@@ -190,7 +192,7 @@ _rl_kill_kbd_macro () ...@@ -190,7 +192,7 @@ _rl_kill_kbd_macro ()
re-executing the existing macro. */ re-executing the existing macro. */
int int
rl_start_kbd_macro (ignore1, ignore2) rl_start_kbd_macro (ignore1, ignore2)
int ignore1 __attribute__((unused)), ignore2 __attribute__((unused)); int ignore1, ignore2;
{ {
if (RL_ISSTATE (RL_STATE_MACRODEF)) if (RL_ISSTATE (RL_STATE_MACRODEF))
{ {
...@@ -215,7 +217,7 @@ rl_start_kbd_macro (ignore1, ignore2) ...@@ -215,7 +217,7 @@ rl_start_kbd_macro (ignore1, ignore2)
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 (count, ignore) rl_end_kbd_macro (count, ignore)
int count, ignore __attribute__((unused)); int count, ignore;
{ {
if (RL_ISSTATE (RL_STATE_MACRODEF) == 0) if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
{ {
...@@ -235,7 +237,7 @@ rl_end_kbd_macro (count, ignore) ...@@ -235,7 +237,7 @@ rl_end_kbd_macro (count, ignore)
COUNT says how many times to execute it. */ COUNT says how many times to execute it. */
int int
rl_call_last_kbd_macro (count, ignore) rl_call_last_kbd_macro (count, ignore)
int count, ignore __attribute__((unused)); 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 Free Software Foundation, Inc. /* Copyright (C) 2001-2004 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>
...@@ -90,12 +92,12 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) ...@@ -90,12 +92,12 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
/* 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)
count --; count--;
while (count > 0) while (count > 0)
{ {
tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps); tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps);
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2) if (MB_INVALIDCH ((size_t)tmp))
{ {
/* invalid bytes. asume a byte represents a character */ /* invalid bytes. asume a byte represents a character */
point++; point++;
...@@ -103,9 +105,8 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero) ...@@ -103,9 +105,8 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
/* reset states. */ /* reset states. */
memset(&ps, 0, sizeof(mbstate_t)); memset(&ps, 0, sizeof(mbstate_t));
} }
else if (tmp == (size_t)0) else if (MB_NULLWCH (tmp))
/* found '\0' char */ break; /* found wide '\0' */
break;
else else
{ {
/* valid bytes */ /* valid bytes */
...@@ -158,7 +159,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) ...@@ -158,7 +159,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero)
while (point < seed) while (point < seed)
{ {
tmp = mbrtowc (&wc, string + point, length - point, &ps); tmp = mbrtowc (&wc, string + point, length - point, &ps);
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2) if (MB_INVALIDCH ((size_t)tmp))
{ {
/* in this case, bytes are invalid or shorted to compose /* in this case, bytes are invalid or shorted to compose
multibyte char, so assume that the first byte represents multibyte char, so assume that the first byte represents
...@@ -167,8 +168,12 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) ...@@ -167,8 +168,12 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero)
/* clear the state of the byte sequence, because /* clear the state of the byte sequence, because
in this case effect of mbstate is undefined */ in this case effect of mbstate is undefined */
memset(&ps, 0, sizeof (mbstate_t)); memset(&ps, 0, sizeof (mbstate_t));
/* Since we're assuming that this byte represents a single
non-zero-width character, don't forget about it. */
prev = point;
} }
else if (tmp == 0) else if (MB_NULLWCH (tmp))
break; /* Found '\0' char. Can this happen? */ break; /* Found '\0' char. Can this happen? */
else else
{ {
...@@ -194,7 +199,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero) ...@@ -194,7 +199,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero)
if it couldn't parse a complete multibyte character. */ if it couldn't parse a complete multibyte character. */
int int
_rl_get_char_len (src, ps) _rl_get_char_len (src, ps)
const char *src; char *src;
mbstate_t *ps; mbstate_t *ps;
{ {
size_t tmp; size_t tmp;
...@@ -203,6 +208,7 @@ _rl_get_char_len (src, ps) ...@@ -203,6 +208,7 @@ _rl_get_char_len (src, ps)
if (tmp == (size_t)(-2)) if (tmp == (size_t)(-2))
{ {
/* shorted to compose multibyte char */ /* shorted to compose multibyte char */
if (ps)
memset (ps, 0, sizeof(mbstate_t)); memset (ps, 0, sizeof(mbstate_t));
return -2; return -2;
} }
...@@ -210,6 +216,7 @@ _rl_get_char_len (src, ps) ...@@ -210,6 +216,7 @@ _rl_get_char_len (src, ps)
{ {
/* invalid to compose multibyte char */ /* invalid to compose multibyte char */
/* initialize the conversion state */ /* initialize the conversion state */
if (ps)
memset (ps, 0, sizeof(mbstate_t)); memset (ps, 0, sizeof(mbstate_t));
return -1; return -1;
} }
...@@ -223,9 +230,12 @@ _rl_get_char_len (src, ps) ...@@ -223,9 +230,12 @@ _rl_get_char_len (src, ps)
return 1. Otherwise return 0. */ return 1. Otherwise return 0. */
int int
_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2) _rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
char *buf1, *buf2; char *buf1;
mbstate_t *ps1, *ps2; int pos1;
int pos1, pos2; mbstate_t *ps1;
char *buf2;
int pos2;
mbstate_t *ps2;
{ {
int i, w1, w2; int i, w1, w2;
...@@ -249,7 +259,7 @@ _rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2) ...@@ -249,7 +259,7 @@ _rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
it returns -1 */ it returns -1 */
int int
_rl_adjust_point(string, point, ps) _rl_adjust_point(string, point, ps)
const char *string; char *string;
int point; int point;
mbstate_t *ps; mbstate_t *ps;
{ {
...@@ -266,7 +276,7 @@ _rl_adjust_point(string, point, ps) ...@@ -266,7 +276,7 @@ _rl_adjust_point(string, point, ps)
while (pos < point) while (pos < point)
{ {
tmp = mbrlen (string + pos, length - pos, ps); tmp = mbrlen (string + pos, length - pos, ps);
if((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2) if (MB_INVALIDCH ((size_t)tmp))
{ {
/* in this case, bytes are invalid or shorted to compose /* in this case, bytes are invalid or shorted to compose
multibyte char, so assume that the first byte represents multibyte char, so assume that the first byte represents
...@@ -274,8 +284,11 @@ _rl_adjust_point(string, point, ps) ...@@ -274,8 +284,11 @@ _rl_adjust_point(string, point, ps)
pos++; pos++;
/* clear the state of the byte sequence, because /* clear the state of the byte sequence, because
in this case effect of mbstate is undefined */ in this case effect of mbstate is undefined */
if (ps)
memset (ps, 0, sizeof (mbstate_t)); memset (ps, 0, sizeof (mbstate_t));
} }
else if (MB_NULLWCH (tmp))
pos++;
else else
pos += tmp; pos += tmp;
} }
...@@ -308,8 +321,8 @@ _rl_is_mbchar_matched (string, seed, end, mbchar, length) ...@@ -308,8 +321,8 @@ _rl_is_mbchar_matched (string, seed, end, mbchar, length)
#undef _rl_find_next_mbchar #undef _rl_find_next_mbchar
int int
_rl_find_next_mbchar (string, seed, count, flags) _rl_find_next_mbchar (string, seed, count, flags)
char *string __attribute__((unused)); char *string;
int seed, count, flags __attribute__((unused)); int seed, count, flags;
{ {
#if defined (HANDLE_MULTIBYTE) #if defined (HANDLE_MULTIBYTE)
return _rl_find_next_mbchar_internal (string, seed, count, flags); return _rl_find_next_mbchar_internal (string, seed, count, flags);
...@@ -324,8 +337,8 @@ _rl_find_next_mbchar (string, seed, count, flags) ...@@ -324,8 +337,8 @@ _rl_find_next_mbchar (string, seed, count, flags)
#undef _rl_find_prev_mbchar #undef _rl_find_prev_mbchar
int int
_rl_find_prev_mbchar (string, seed, flags) _rl_find_prev_mbchar (string, seed, flags)
char *string __attribute__((unused)); char *string;
int seed, flags __attribute__((unused)); int seed, flags;
{ {
#if defined (HANDLE_MULTIBYTE) #if defined (HANDLE_MULTIBYTE)
return _rl_find_prev_mbchar_internal (string, seed, flags); return _rl_find_prev_mbchar_internal (string, seed, flags);
......
/* misc.c -- miscellaneous bindable readline functions. */ /* misc.c -- miscellaneous bindable readline functions. */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc. /* Copyright (C) 1987-2004 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>
...@@ -155,7 +157,7 @@ rl_digit_loop () ...@@ -155,7 +157,7 @@ rl_digit_loop ()
/* Add the current digit to the argument in progress. */ /* Add the current digit to the argument in progress. */
int int
rl_digit_argument (ignore, key) rl_digit_argument (ignore, key)
int ignore __attribute__((unused)), key; int ignore, key;
{ {
rl_execute_next (key); rl_execute_next (key);
return (rl_digit_loop ()); return (rl_digit_loop ());
...@@ -185,7 +187,7 @@ _rl_init_argument () ...@@ -185,7 +187,7 @@ _rl_init_argument ()
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 (count, key) rl_universal_argument (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
rl_numeric_arg *= 4; rl_numeric_arg *= 4;
return (rl_digit_loop ()); return (rl_digit_loop ());
...@@ -251,6 +253,8 @@ rl_maybe_unsave_line () ...@@ -251,6 +253,8 @@ rl_maybe_unsave_line ()
{ {
if (_rl_saved_line_for_history) if (_rl_saved_line_for_history)
{ {
/* Can't call with `1' because rl_undo_list might point to an undo
list from a history entry, as in rl_replace_from_history() below. */
rl_replace_line (_rl_saved_line_for_history->line, 0); rl_replace_line (_rl_saved_line_for_history->line, 0);
rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data; rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
_rl_free_history_entry (_rl_saved_line_for_history); _rl_free_history_entry (_rl_saved_line_for_history);
...@@ -272,6 +276,13 @@ rl_maybe_save_line () ...@@ -272,6 +276,13 @@ rl_maybe_save_line ()
_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->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;
} }
...@@ -296,7 +307,7 @@ _rl_history_set_point () ...@@ -296,7 +307,7 @@ _rl_history_set_point ()
rl_point = rl_end; rl_point = rl_end;
#if defined (VI_MODE) #if defined (VI_MODE)
if (rl_editing_mode == vi_mode) if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
rl_point = 0; rl_point = 0;
#endif /* VI_MODE */ #endif /* VI_MODE */
...@@ -307,8 +318,10 @@ _rl_history_set_point () ...@@ -307,8 +318,10 @@ _rl_history_set_point ()
void void
rl_replace_from_history (entry, flags) rl_replace_from_history (entry, flags)
HIST_ENTRY *entry; HIST_ENTRY *entry;
int flags __attribute__((unused)); /* currently unused */ int flags; /* currently unused */
{ {
/* Can't call with `1' because rl_undo_list might point to an undo list
from a history entry, just like we're setting up here. */
rl_replace_line (entry->line, 0); rl_replace_line (entry->line, 0);
rl_undo_list = (UNDO_LIST *)entry->data; rl_undo_list = (UNDO_LIST *)entry->data;
rl_point = rl_end; rl_point = rl_end;
...@@ -332,7 +345,7 @@ rl_replace_from_history (entry, flags) ...@@ -332,7 +345,7 @@ rl_replace_from_history (entry, flags)
/* Meta-< goes to the start of the history. */ /* Meta-< goes to the start of the history. */
int int
rl_beginning_of_history (count, key) rl_beginning_of_history (count, key)
int count __attribute__((unused)), key; int count, key;
{ {
return (rl_get_previous_history (1 + where_history (), key)); return (rl_get_previous_history (1 + where_history (), key));
} }
...@@ -340,7 +353,7 @@ rl_beginning_of_history (count, key) ...@@ -340,7 +353,7 @@ rl_beginning_of_history (count, 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 (count, key) rl_end_of_history (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
rl_maybe_replace_line (); rl_maybe_replace_line ();
using_history (); using_history ();
...@@ -433,6 +446,7 @@ rl_get_previous_history (count, key) ...@@ -433,6 +446,7 @@ rl_get_previous_history (count, key)
rl_replace_from_history (temp, 0); rl_replace_from_history (temp, 0);
_rl_history_set_point (); _rl_history_set_point ();
} }
return 0; return 0;
} }
...@@ -444,7 +458,7 @@ rl_get_previous_history (count, key) ...@@ -444,7 +458,7 @@ 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 (count, key) rl_vi_editing_mode (count, key)
int count __attribute__((unused)), 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 */
...@@ -457,7 +471,7 @@ rl_vi_editing_mode (count, key) ...@@ -457,7 +471,7 @@ rl_vi_editing_mode (count, key)
int int
rl_emacs_editing_mode (count, key) rl_emacs_editing_mode (count, key)
int count __attribute__((unused)), 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 */
...@@ -468,7 +482,7 @@ rl_emacs_editing_mode (count, key) ...@@ -468,7 +482,7 @@ rl_emacs_editing_mode (count, key)
/* 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 (im, force) _rl_set_insert_mode (im, force)
int im, force __attribute__((unused)); int im, force;
{ {
#ifdef CURSOR_MODE #ifdef CURSOR_MODE
_rl_set_cursor (im, force); _rl_set_cursor (im, force);
...@@ -481,7 +495,7 @@ _rl_set_insert_mode (im, force) ...@@ -481,7 +495,7 @@ _rl_set_insert_mode (im, force)
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 (count, key) rl_overwrite_mode (count, key)
int count, key __attribute__((unused)); 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>
...@@ -73,6 +75,23 @@ static char *normalize_codeset PARAMS((char *)); ...@@ -73,6 +75,23 @@ static char *normalize_codeset PARAMS((char *));
static char *find_codeset PARAMS((char *, size_t *)); static char *find_codeset PARAMS((char *, size_t *));
#endif /* !HAVE_SETLOCALE */ #endif /* !HAVE_SETLOCALE */
static char *_rl_get_locale_var PARAMS((const char *));
static char *
_rl_get_locale_var (v)
const char *v;
{
char *lspec;
lspec = sh_get_env_value ("LC_ALL");
if (lspec == 0 || *lspec == 0)
lspec = sh_get_env_value (v);
if (lspec == 0 || *lspec == 0)
lspec = sh_get_env_value ("LANG");
return lspec;
}
/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value /* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
to decide the defaults for 8-bit character input and output. Returns to decide the defaults for 8-bit character input and output. Returns
1 if we set eight-bit mode. */ 1 if we set eight-bit mode. */
...@@ -82,10 +101,21 @@ _rl_init_eightbit () ...@@ -82,10 +101,21 @@ _rl_init_eightbit ()
/* If we have setlocale(3), just check the current LC_CTYPE category /* If we have setlocale(3), just check the current LC_CTYPE category
value, and go into eight-bit mode if it's not C or POSIX. */ value, and go into eight-bit mode if it's not C or POSIX. */
#if defined (HAVE_SETLOCALE) #if defined (HAVE_SETLOCALE)
char *t; char *lspec, *t;
/* Set the LC_CTYPE locale category from environment variables. */ /* Set the LC_CTYPE locale category from environment variables. */
t = setlocale (LC_CTYPE, ""); lspec = _rl_get_locale_var ("LC_CTYPE");
/* Since _rl_get_locale_var queries the right environment variables,
we query the current locale settings with setlocale(), and, if
that doesn't return anything, we set lspec to the empty string to
force the subsequent call to setlocale() to define the `native'
environment. */
if (lspec == 0 || *lspec == 0)
lspec = setlocale (LC_CTYPE, (char *)NULL);
if (lspec == 0)
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))
{ {
_rl_meta_flag = 1; _rl_meta_flag = 1;
...@@ -103,9 +133,8 @@ _rl_init_eightbit () ...@@ -103,9 +133,8 @@ _rl_init_eightbit ()
/* We don't have setlocale. Finesse it. Check the environment for the /* We don't have setlocale. Finesse it. Check the environment for the
appropriate variables and set eight-bit mode if they have the right appropriate variables and set eight-bit mode if they have the right
values. */ values. */
lspec = sh_get_env_value ("LC_ALL"); lspec = _rl_get_locale_var ("LC_CTYPE");
if (lspec == 0) lspec = sh_get_env_value ("LC_CTYPE");
if (lspec == 0) lspec = sh_get_env_value ("LANG");
if (lspec == 0 || (t = normalize_codeset (lspec)) == 0) if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
return (0); return (0);
for (i = 0; t && legal_lang_values[i]; i++) for (i = 0; t && legal_lang_values[i]; i++)
......
...@@ -21,9 +21,15 @@ ...@@ -21,9 +21,15 @@
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 (__TANDEM)
# include <floss.h>
#endif
#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>
......
...@@ -25,7 +25,11 @@ ...@@ -25,7 +25,11 @@
#if defined (HAVE_DIRENT_H) #if defined (HAVE_DIRENT_H)
# include <dirent.h> # include <dirent.h>
# if defined (HAVE_STRUCT_DIRENT_D_NAMLEN)
# define D_NAMLEN(d) ((d)->d_namlen)
# else
# define D_NAMLEN(d) (strlen ((d)->d_name)) # define D_NAMLEN(d) (strlen ((d)->d_name))
# endif /* !HAVE_STRUCT_DIRENT_D_NAMLEN */
#else #else
# if defined (HAVE_SYS_NDIR_H) # if defined (HAVE_SYS_NDIR_H)
# include <sys/ndir.h> # include <sys/ndir.h>
...@@ -42,11 +46,11 @@ ...@@ -42,11 +46,11 @@
# define D_NAMLEN(d) ((d)->d_namlen) # define D_NAMLEN(d) ((d)->d_namlen)
#endif /* !HAVE_DIRENT_H */ #endif /* !HAVE_DIRENT_H */
#if defined (STRUCT_DIRENT_HAS_D_INO) && !defined (STRUCT_DIRENT_HAS_D_FILENO) #if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO)
# define d_fileno d_ino # define d_fileno d_ino
#endif #endif
#if defined (_POSIX_SOURCE) && (!defined (STRUCT_DIRENT_HAS_D_INO) || defined (BROKEN_DIRENT_D_INO)) #if defined (_POSIX_SOURCE) && (!defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO))
/* Posix does not require that the d_ino field be present, and some /* Posix does not require that the d_ino field be present, and some
systems do not provide it. */ systems do not provide it. */
# define REAL_DIR_ENTRY(dp) 1 # define REAL_DIR_ENTRY(dp) 1
......
...@@ -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"
...@@ -66,11 +68,11 @@ ...@@ -66,11 +68,11 @@
#include "xmalloc.h" #include "xmalloc.h"
#ifndef RL_LIBRARY_VERSION #ifndef RL_LIBRARY_VERSION
# define RL_LIBRARY_VERSION "4.3" # define RL_LIBRARY_VERSION "5.0"
#endif #endif
#ifndef RL_READLINE_VERSION #ifndef RL_READLINE_VERSION
# define RL_READLINE_VERSION 0x0403 # define RL_READLINE_VERSION 0x0500
#endif #endif
extern void _rl_free_history_entry PARAMS((HIST_ENTRY *)); extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
...@@ -83,6 +85,7 @@ static void bind_arrow_keys_internal PARAMS((Keymap)); ...@@ -83,6 +85,7 @@ 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));
static void reset_default_bindings PARAMS((void));
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
...@@ -345,7 +348,7 @@ readline_internal_setup () ...@@ -345,7 +348,7 @@ readline_internal_setup ()
#if defined (VI_MODE) #if defined (VI_MODE)
if (rl_editing_mode == vi_mode) if (rl_editing_mode == vi_mode)
rl_vi_insertion_mode (1, 0); rl_vi_insertion_mode (1, 'i');
#endif /* VI_MODE */ #endif /* VI_MODE */
if (rl_pre_input_hook) if (rl_pre_input_hook)
...@@ -648,7 +651,21 @@ _rl_dispatch_subseq (key, map, got_subseq) ...@@ -648,7 +651,21 @@ _rl_dispatch_subseq (key, map, got_subseq)
the function. The recursive call to _rl_dispatch_subseq has the function. The recursive call to _rl_dispatch_subseq has
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
r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key)); r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key));
#else
/* XXX - experimental code -- might never be executed. Save
for later. */
Keymap m = FUNCTION_TO_KEYMAP (map, key);
int type = m[ANYOTHERKEY].type;
func = m[ANYOTHERKEY].function;
if (type == ISFUNC && func == rl_do_lowercase_version)
r = _rl_dispatch (_rl_to_lower (key), map);
else
r = _rl_dispatch (ANYOTHERKEY, m);
#endif
}
else if (r && map[ANYOTHERKEY].function) else if (r && map[ANYOTHERKEY].function)
{ {
/* We didn't match (r is probably -1), so return something to /* We didn't match (r is probably -1), so return something to
...@@ -682,6 +699,7 @@ _rl_dispatch_subseq (key, map, got_subseq) ...@@ -682,6 +699,7 @@ _rl_dispatch_subseq (key, map, got_subseq)
} }
#if defined (VI_MODE) #if defined (VI_MODE)
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap && if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
key != ANYOTHERKEY &&
_rl_vi_textmod_command (key)) _rl_vi_textmod_command (key))
_rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign); _rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
#endif #endif
...@@ -836,7 +854,7 @@ readline_initialize_everything () ...@@ -836,7 +854,7 @@ readline_initialize_everything ()
/* If the completion parser's default word break characters haven't /* If the completion parser's default word break characters haven't
been set yet, then do so now. */ been set yet, then do so now. */
if (rl_completer_word_break_characters == (char *)NULL) if (rl_completer_word_break_characters == (char *)NULL)
rl_completer_word_break_characters = rl_basic_word_break_characters; rl_completer_word_break_characters = (char *)rl_basic_word_break_characters;
} }
/* If this system allows us to look at the values of the regular /* If this system allows us to look at the values of the regular
...@@ -848,6 +866,15 @@ readline_default_bindings () ...@@ -848,6 +866,15 @@ readline_default_bindings ()
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
interested in back to rl_insert and read the new ones. */
static void
reset_default_bindings ()
{
rl_tty_unset_default_bindings (_rl_keymap);
rl_tty_set_default_bindings (_rl_keymap);
}
/* Bind some common arrow key sequences in MAP. */ /* Bind some common arrow key sequences in MAP. */
static void static void
bind_arrow_keys_internal (map) bind_arrow_keys_internal (map)
...@@ -859,25 +886,25 @@ bind_arrow_keys_internal (map) ...@@ -859,25 +886,25 @@ bind_arrow_keys_internal (map)
_rl_keymap = map; _rl_keymap = map;
#if defined (__MSDOS__) #if defined (__MSDOS__)
_rl_bind_if_unbound ("\033[0A", rl_get_previous_history); rl_bind_keyseq_if_unbound ("\033[0A", rl_get_previous_history);
_rl_bind_if_unbound ("\033[0B", rl_backward_char); rl_bind_keyseq_if_unbound ("\033[0B", rl_backward_char);
_rl_bind_if_unbound ("\033[0C", rl_forward_char); rl_bind_keyseq_if_unbound ("\033[0C", rl_forward_char);
_rl_bind_if_unbound ("\033[0D", rl_get_next_history); rl_bind_keyseq_if_unbound ("\033[0D", rl_get_next_history);
#endif #endif
_rl_bind_if_unbound ("\033[A", rl_get_previous_history); rl_bind_keyseq_if_unbound ("\033[A", rl_get_previous_history);
_rl_bind_if_unbound ("\033[B", rl_get_next_history); rl_bind_keyseq_if_unbound ("\033[B", rl_get_next_history);
_rl_bind_if_unbound ("\033[C", rl_forward_char); rl_bind_keyseq_if_unbound ("\033[C", rl_forward_char);
_rl_bind_if_unbound ("\033[D", rl_backward_char); rl_bind_keyseq_if_unbound ("\033[D", rl_backward_char);
_rl_bind_if_unbound ("\033[H", rl_beg_of_line); rl_bind_keyseq_if_unbound ("\033[H", rl_beg_of_line);
_rl_bind_if_unbound ("\033[F", rl_end_of_line); rl_bind_keyseq_if_unbound ("\033[F", rl_end_of_line);
_rl_bind_if_unbound ("\033OA", rl_get_previous_history); rl_bind_keyseq_if_unbound ("\033OA", rl_get_previous_history);
_rl_bind_if_unbound ("\033OB", rl_get_next_history); rl_bind_keyseq_if_unbound ("\033OB", rl_get_next_history);
_rl_bind_if_unbound ("\033OC", rl_forward_char); rl_bind_keyseq_if_unbound ("\033OC", rl_forward_char);
_rl_bind_if_unbound ("\033OD", rl_backward_char); rl_bind_keyseq_if_unbound ("\033OD", rl_backward_char);
_rl_bind_if_unbound ("\033OH", rl_beg_of_line); rl_bind_keyseq_if_unbound ("\033OH", rl_beg_of_line);
_rl_bind_if_unbound ("\033OF", rl_end_of_line); rl_bind_keyseq_if_unbound ("\033OF", rl_end_of_line);
_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, 1989, 1992 Free Software Foundation, Inc. /* Copyright (C) 1987-2004 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 0x0403 /* Readline 4.3 */ #define RL_READLINE_VERSION 0x0500 /* Readline 5.0 */
#define RL_VERSION_MAJOR 4 #define RL_VERSION_MAJOR 5
#define RL_VERSION_MINOR 3 #define RL_VERSION_MINOR 0
/* Readline data structures. */ /* Readline data structures. */
...@@ -160,6 +160,7 @@ extern int rl_kill_line PARAMS((int, int)); ...@@ -160,6 +160,7 @@ extern int rl_kill_line PARAMS((int, int));
extern int rl_backward_kill_line PARAMS((int, int)); extern int rl_backward_kill_line PARAMS((int, int));
extern int rl_kill_full_line PARAMS((int, int)); extern int rl_kill_full_line PARAMS((int, int));
extern int rl_unix_word_rubout PARAMS((int, int)); extern int rl_unix_word_rubout PARAMS((int, int));
extern int rl_unix_filename_rubout PARAMS((int, int));
extern int rl_unix_line_discard PARAMS((int, int)); extern int rl_unix_line_discard PARAMS((int, int));
extern int rl_copy_region_to_kill PARAMS((int, int)); extern int rl_copy_region_to_kill PARAMS((int, int));
extern int rl_kill_region PARAMS((int, int)); extern int rl_kill_region PARAMS((int, int));
...@@ -258,6 +259,8 @@ extern int rl_vi_check PARAMS((void)); ...@@ -258,6 +259,8 @@ extern int rl_vi_check PARAMS((void));
extern int rl_vi_domove PARAMS((int, int *)); extern int rl_vi_domove PARAMS((int, int *));
extern int rl_vi_bracktype PARAMS((int)); extern int rl_vi_bracktype PARAMS((int));
extern void rl_vi_start_inserting PARAMS((int, int, int));
/* VI-mode pseudo-bindable commands, used as utility functions. */ /* VI-mode pseudo-bindable commands, used as utility functions. */
extern int rl_vi_fWord PARAMS((int, int)); extern int rl_vi_fWord PARAMS((int, int));
extern int rl_vi_bWord PARAMS((int, int)); extern int rl_vi_bWord PARAMS((int, int));
...@@ -290,12 +293,20 @@ extern int rl_bind_key PARAMS((int, rl_command_func_t *)); ...@@ -290,12 +293,20 @@ extern int rl_bind_key PARAMS((int, rl_command_func_t *));
extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap)); extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
extern int rl_unbind_key PARAMS((int)); extern int rl_unbind_key PARAMS((int));
extern int rl_unbind_key_in_map PARAMS((int, Keymap)); extern int rl_unbind_key_in_map PARAMS((int, Keymap));
extern int rl_bind_key_if_unbound PARAMS((int, rl_command_func_t *));
extern int rl_bind_key_if_unbound_in_map PARAMS((int, rl_command_func_t *, Keymap));
extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap)); extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap));
extern int rl_unbind_command_in_map PARAMS((const char *, Keymap)); extern int rl_unbind_command_in_map PARAMS((const char *, Keymap));
extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap)); extern int rl_bind_keyseq PARAMS((const char *, rl_command_func_t *));
extern int rl_bind_keyseq_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *));
extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap)); extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap));
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. */
extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
/* Backwards compatibility, use rl_generic_bind instead. */ /* Backwards compatibility, use rl_generic_bind instead. */
extern int rl_macro_bind PARAMS((const char *, const char *, Keymap)); extern int rl_macro_bind PARAMS((const char *, const char *, Keymap));
...@@ -329,7 +340,7 @@ extern void rl_set_keymap PARAMS((Keymap)); ...@@ -329,7 +340,7 @@ extern void rl_set_keymap PARAMS((Keymap));
extern Keymap rl_get_keymap PARAMS((void)); extern Keymap rl_get_keymap PARAMS((void));
/* Undocumented; used internally only. */ /* Undocumented; used internally only. */
extern void rl_set_keymap_from_edit_mode PARAMS((void)); extern void rl_set_keymap_from_edit_mode PARAMS((void));
extern const char *rl_get_keymap_name_from_edit_mode PARAMS((void)); extern char *rl_get_keymap_name_from_edit_mode PARAMS((void));
/* Functions for manipulating the funmap, which maps command names to functions. */ /* Functions for manipulating the funmap, which maps command names to functions. */
extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *)); extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *));
...@@ -358,7 +369,7 @@ extern int rl_clear_message PARAMS((void)); ...@@ -358,7 +369,7 @@ extern int rl_clear_message PARAMS((void));
extern int rl_reset_line_state PARAMS((void)); extern int rl_reset_line_state PARAMS((void));
extern int rl_crlf PARAMS((void)); extern int rl_crlf PARAMS((void));
#if (defined (__STDC__) || defined (__cplusplus)) && defined (USE_VARARGS) && defined (PREFER_STDARG) #if defined (USE_VARARGS) && defined (PREFER_STDARG)
extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2))); extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else #else
extern int rl_message (); extern int rl_message ();
...@@ -384,13 +395,14 @@ extern char *rl_copy_text PARAMS((int, int)); ...@@ -384,13 +395,14 @@ extern char *rl_copy_text PARAMS((int, int));
extern void rl_prep_terminal PARAMS((int)); extern void rl_prep_terminal PARAMS((int));
extern void rl_deprep_terminal PARAMS((void)); extern void rl_deprep_terminal PARAMS((void));
extern void rl_tty_set_default_bindings PARAMS((Keymap)); extern void rl_tty_set_default_bindings PARAMS((Keymap));
extern void rl_tty_unset_default_bindings PARAMS((Keymap));
extern int rl_reset_terminal PARAMS((const char *)); 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 const char *rl_get_termcap PARAMS((const char *)); extern char *rl_get_termcap PARAMS((const char *));
/* Functions for character input. */ /* Functions for character input. */
extern int rl_stuff_char PARAMS((int)); extern int rl_stuff_char PARAMS((int));
...@@ -603,7 +615,12 @@ extern const char *rl_basic_word_break_characters; ...@@ -603,7 +615,12 @@ extern const char *rl_basic_word_break_characters;
/* The list of characters that signal a break between words for /* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */ rl_basic_word_break_characters. */
extern const char *rl_completer_word_break_characters; extern /*const*/ char *rl_completer_word_break_characters;
/* Hook function to allow an application to set the completion word
break characters before readline breaks up the line. Allows
position-dependent word break characters. */
extern rl_cpvfunc_t *rl_completion_word_break_hook;
/* List of characters which can be used to quote a substring of the line. /* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring Completion occurs on the entire substring, and within the substring
...@@ -687,6 +704,11 @@ extern int rl_attempted_completion_over; ...@@ -687,6 +704,11 @@ extern int rl_attempted_completion_over;
functions. */ functions. */
extern int rl_completion_type; extern int rl_completion_type;
/* Up to this many items will be displayed in response to a
possible-completions call. After that, we ask the user if she
is sure she wants to see them all. The default value is 100. */
extern int rl_completion_query_items;
/* Character appended to completed words when at the end of the line. The /* Character appended to completed words when at the end of the line. The
default is a space. Nothing is added if this is '\0'. */ default is a space. Nothing is added if this is '\0'. */
extern int rl_completion_append_character; extern int rl_completion_append_character;
...@@ -695,10 +717,18 @@ extern int rl_completion_append_character; ...@@ -695,10 +717,18 @@ extern int rl_completion_append_character;
rl_completion_append_character will not be appended. */ rl_completion_append_character will not be appended. */
extern int rl_completion_suppress_append; extern int rl_completion_suppress_append;
/* Up to this many items will be displayed in response to a /* Set to any quote character readline thinks it finds before any application
possible-completions call. After that, we ask the user if she completion function is called. */
is sure she wants to see them all. The default value is 100. */ extern int rl_completion_quote_character;
extern int rl_completion_query_items;
/* Set to a non-zero value if readline found quoting anywhere in the word to
be completed; set before any application completion function is called. */
extern int rl_completion_found_quote;
/* If non-zero, the completion functions don't append any closing quote.
This is set to 0 by rl_complete_internal and may be changed by an
application-specific completion function. */
extern int rl_completion_suppress_quote;
/* If non-zero, a slash will be appended to completed filenames that are /* If non-zero, a slash will be appended to completed filenames that are
symbolic links to directory names, subject to the value of the symbolic links to directory names, subject to the value of the
...@@ -749,6 +779,7 @@ extern int rl_inhibit_completion; ...@@ -749,6 +779,7 @@ extern int rl_inhibit_completion;
#define RL_STATE_SIGHANDLER 0x08000 /* in readline sighandler */ #define RL_STATE_SIGHANDLER 0x08000 /* in readline sighandler */
#define RL_STATE_UNDOING 0x10000 /* doing an undo */ #define RL_STATE_UNDOING 0x10000 /* doing an undo */
#define RL_STATE_INPUTPENDING 0x20000 /* rl_execute_next called */ #define RL_STATE_INPUTPENDING 0x20000 /* rl_execute_next called */
#define RL_STATE_TTYCSAVED 0x40000 /* tty special chars saved */
#define RL_STATE_DONE 0x80000 /* done; accepted line */ #define RL_STATE_DONE 0x80000 /* done; accepted line */
...@@ -785,6 +816,12 @@ struct readline_state { ...@@ -785,6 +816,12 @@ struct readline_state {
int catchsigs; int catchsigs;
int catchsigwinch; int catchsigwinch;
/* search state */
/* completion state */
/* options state */
/* reserved for future expansion, so the struct size doesn't change */ /* reserved for future expansion, so the struct size doesn't change */
char reserved[64]; char reserved[64];
}; };
......
...@@ -32,10 +32,6 @@ ...@@ -32,10 +32,6 @@
#include "rlstdc.h" #include "rlstdc.h"
#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ <8)
#define __attribute__(A)
#endif
#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING) #if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
# define TERMIOS_TTY_DRIVER # define TERMIOS_TTY_DRIVER
#else #else
...@@ -81,7 +77,7 @@ extern int _rl_stricmp PARAMS((char *, char *)); ...@@ -81,7 +77,7 @@ extern int _rl_stricmp PARAMS((char *, char *));
extern int _rl_strnicmp PARAMS((char *, char *, int)); extern int _rl_strnicmp PARAMS((char *, char *, int));
#endif #endif
#if defined (HAVE_STRPBRK) #if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE)
# define _rl_strpbrk(a,b) strpbrk((a),(b)) # define _rl_strpbrk(a,b) strpbrk((a),(b))
#else #else
extern char *_rl_strpbrk PARAMS((const char *, const char *)); extern char *_rl_strpbrk PARAMS((const char *, const char *));
......
...@@ -35,11 +35,18 @@ ...@@ -35,11 +35,18 @@
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H) #if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H)
# include <wchar.h> # include <wchar.h>
# include <wctype.h> # include <wctype.h>
# if defined (HAVE_MBSRTOWCS) /* system is supposed to support XPG5 */ # if defined (HAVE_MBSRTOWCS) && defined (HAVE_MBRTOWC) && defined (HAVE_MBRLEN) && defined (HAVE_WCWIDTH)
/* system is supposed to support XPG5 */
# define HANDLE_MULTIBYTE 1 # define HANDLE_MULTIBYTE 1
# endif # endif
#endif #endif
/* If we don't want multibyte chars even on a system that supports them, let
the configuring user turn multibyte support off. */
#if defined (NO_MULTIBYTE_SUPPORT)
# undef HANDLE_MULTIBYTE
#endif
/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T) #if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0) # define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
...@@ -82,14 +89,17 @@ extern int _rl_find_next_mbchar PARAMS((char *, int, int, int)); ...@@ -82,14 +89,17 @@ extern int _rl_find_next_mbchar PARAMS((char *, int, int, int));
#ifdef HANDLE_MULTIBYTE #ifdef HANDLE_MULTIBYTE
extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *)); extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *));
extern int _rl_get_char_len PARAMS((const char *, mbstate_t *)); extern int _rl_get_char_len PARAMS((char *, mbstate_t *));
extern int _rl_adjust_point PARAMS((const char *, int, mbstate_t *)); extern int _rl_adjust_point PARAMS((char *, int, mbstate_t *));
extern int _rl_read_mbchar PARAMS((char *, int)); extern int _rl_read_mbchar PARAMS((char *, int));
extern int _rl_read_mbstring PARAMS((int, char *, int)); 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));
#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
#define MB_NULLWCH(x) ((x) == 0)
#else /* !HANDLE_MULTIBYTE */ #else /* !HANDLE_MULTIBYTE */
#undef MB_LEN_MAX #undef MB_LEN_MAX
...@@ -101,6 +111,9 @@ extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int)); ...@@ -101,6 +111,9 @@ 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 MB_INVALIDCH(x) (0)
#define MB_NULLWCH(x) (0)
#endif /* !HANDLE_MULTIBYTE */ #endif /* !HANDLE_MULTIBYTE */
extern int rl_byte_oriented; extern int rl_byte_oriented;
......
/* 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 Free Software Foundation, Inc. /* Copyright (C) 1999-2004 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.
...@@ -73,7 +73,7 @@ extern int rl_set_retained_kills PARAMS((int)); ...@@ -73,7 +73,7 @@ extern int rl_set_retained_kills PARAMS((int));
extern void _rl_set_screen_size PARAMS((int, int)); extern void _rl_set_screen_size PARAMS((int, int));
/* undo.c */ /* undo.c */
extern int _rl_fix_last_undo_of_type PARAMS((unsigned int, int, int)); extern int _rl_fix_last_undo_of_type PARAMS((int, int, int));
/* util.c */ /* util.c */
extern char *_rl_savestring PARAMS((const char *)); extern char *_rl_savestring PARAMS((const char *));
...@@ -103,7 +103,6 @@ extern int readline_internal_char PARAMS((void)); ...@@ -103,7 +103,6 @@ extern int readline_internal_char PARAMS((void));
#endif /* READLINE_CALLBACKS */ #endif /* READLINE_CALLBACKS */
/* bind.c */ /* bind.c */
extern void _rl_bind_if_unbound PARAMS((const char *, rl_command_func_t *));
/* complete.c */ /* complete.c */
extern char _rl_find_completion_word PARAMS((int *, int *)); extern char _rl_find_completion_word PARAMS((int *, int *));
...@@ -131,6 +130,7 @@ extern int _rl_input_available PARAMS((void)); ...@@ -131,6 +130,7 @@ extern int _rl_input_available PARAMS((void));
extern int _rl_input_queued PARAMS((int)); extern int _rl_input_queued PARAMS((int));
extern void _rl_insert_typein PARAMS((int)); 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));
/* macro.c */ /* macro.c */
extern void _rl_with_macro_input PARAMS((char *)); extern void _rl_with_macro_input PARAMS((char *));
...@@ -219,6 +219,7 @@ extern const char *_rl_possible_meta_prefixes[]; ...@@ -219,6 +219,7 @@ extern const char *_rl_possible_meta_prefixes[];
/* 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_mark_directories; extern int _rl_complete_mark_directories;
extern int _rl_complete_mark_symlink_dirs; extern int _rl_complete_mark_symlink_dirs;
extern int _rl_print_completions_horizontally; extern int _rl_print_completions_horizontally;
...@@ -230,7 +231,7 @@ extern int _rl_page_completions; ...@@ -230,7 +231,7 @@ 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 const char *rl_display_prompt; extern char *rl_display_prompt;
/* isearch.c */ /* isearch.c */
extern char *_rl_isearch_terminators; extern char *_rl_isearch_terminators;
...@@ -261,16 +262,16 @@ extern procenv_t readline_top_level; ...@@ -261,16 +262,16 @@ extern procenv_t readline_top_level;
/* terminal.c */ /* terminal.c */
extern int _rl_enable_keypad; extern int _rl_enable_keypad;
extern int _rl_enable_meta; extern int _rl_enable_meta;
extern const char *_rl_term_clreol; extern char *_rl_term_clreol;
extern const char *_rl_term_clrpag; extern char *_rl_term_clrpag;
extern const char *_rl_term_im; extern char *_rl_term_im;
extern const char *_rl_term_ic; extern char *_rl_term_ic;
extern const char *_rl_term_ei; extern char *_rl_term_ei;
extern const char *_rl_term_DC; extern char *_rl_term_DC;
extern const char *_rl_term_up; extern char *_rl_term_up;
extern const char *_rl_term_dc; extern char *_rl_term_dc;
extern const char *_rl_term_cr; extern char *_rl_term_cr;
extern const char *_rl_term_IC; extern char *_rl_term_IC;
extern int _rl_screenheight; extern int _rl_screenheight;
extern int _rl_screenwidth; extern int _rl_screenwidth;
extern int _rl_screenchars; extern int _rl_screenchars;
...@@ -281,4 +282,7 @@ extern int _rl_term_autowrap; ...@@ -281,4 +282,7 @@ extern int _rl_term_autowrap;
extern int _rl_doing_an_undo; extern int _rl_doing_an_undo;
extern int _rl_undo_group_level; extern int _rl_undo_group_level;
/* vi_mode.c */
extern int _rl_vi_last_command;
#endif /* _RL_PRIVATE_H_ */ #endif /* _RL_PRIVATE_H_ */
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
#endif #endif
#ifndef __attribute__ #ifndef __attribute__
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
# define __attribute__(x) # define __attribute__(x)
# endif # endif
#endif #endif
......
...@@ -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>
...@@ -184,6 +186,8 @@ static int set_tty_settings PARAMS((int, TIOTYPE *)); ...@@ -184,6 +186,8 @@ static int set_tty_settings PARAMS((int, TIOTYPE *));
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
static void static void
save_tty_chars (tiop) save_tty_chars (tiop)
TIOTYPE *tiop; TIOTYPE *tiop;
...@@ -398,6 +402,9 @@ static int set_tty_settings PARAMS((int, TIOTYPE *)); ...@@ -398,6 +402,9 @@ static int set_tty_settings PARAMS((int, TIOTYPE *));
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *)); static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE));
#if defined (FLUSHO) #if defined (FLUSHO)
# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO) # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
#else #else
...@@ -650,7 +657,10 @@ rl_prep_terminal (meta_flag) ...@@ -650,7 +657,10 @@ rl_prep_terminal (meta_flag)
otio = tio; otio = tio;
rl_tty_unset_default_bindings (_rl_keymap);
save_tty_chars (&otio); save_tty_chars (&otio);
RL_SETSTATE(RL_STATE_TTYCSAVED);
_rl_bind_tty_special_chars (_rl_keymap, tio);
prepare_terminal_settings (meta_flag, otio, &tio); prepare_terminal_settings (meta_flag, otio, &tio);
...@@ -709,7 +719,7 @@ rl_deprep_terminal () ...@@ -709,7 +719,7 @@ rl_deprep_terminal ()
int int
rl_restart_output (count, key) rl_restart_output (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
int fildes = fileno (rl_outstream); int fildes = fileno (rl_outstream);
#if defined (TIOCSTART) #if defined (TIOCSTART)
...@@ -742,7 +752,7 @@ rl_restart_output (count, key) ...@@ -742,7 +752,7 @@ rl_restart_output (count, key)
int int
rl_stop_output (count, key) rl_stop_output (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
int fildes = fileno (rl_instream); int fildes = fileno (rl_instream);
...@@ -774,29 +784,29 @@ rl_stop_output (count, key) ...@@ -774,29 +784,29 @@ rl_stop_output (count, key)
/* */ /* */
/* **************************************************************** */ /* **************************************************************** */
/* Set the system's default editing characters to their readline equivalents #define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func)
in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
void
rltty_set_default_bindings (kmap)
Keymap kmap;
{
TIOTYPE ttybuff;
int tty = fileno (rl_instream);
#if defined (NEW_TTY_DRIVER) #if defined (NEW_TTY_DRIVER)
static void
set_special_char (kmap, tiop, sc, func)
Keymap kmap;
TIOTYPE *tiop;
int sc;
rl_command_func_t *func;
{
if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC)
kmap[(unsigned char)sc].function = func;
}
#define SET_SPECIAL(sc, func) \ #define RESET_SPECIAL(c) \
do \ if (c != -1 && kmap[(unsigned char)c].type == ISFUNC)
{ \ kmap[(unsigned char)c].function = rl_insert;
int ic; \
ic = sc; \
if (ic != -1 && kmap[(unsigned char)ic].type == ISFUNC) \
kmap[(unsigned char)ic].function = func; \
} \
while (0)
if (get_tty_settings (tty, &ttybuff) == 0) static void
{ _rl_bind_tty_special_chars (kmap, ttybuff)
Keymap kmap;
TIOTYPE ttybuff;
{
if (ttybuff.flags & SGTTY_SET) if (ttybuff.flags & SGTTY_SET)
{ {
SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout); SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
...@@ -810,22 +820,33 @@ rltty_set_default_bindings (kmap) ...@@ -810,22 +820,33 @@ rltty_set_default_bindings (kmap)
SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert); SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
} }
# endif /* TIOCGLTC */ # endif /* TIOCGLTC */
} }
#else /* !NEW_TTY_DRIVER */ #else /* !NEW_TTY_DRIVER */
static void
set_special_char (kmap, tiop, sc, func)
Keymap kmap;
TIOTYPE *tiop;
int sc;
rl_command_func_t *func;
{
unsigned char uc;
uc = tiop->c_cc[sc];
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
kmap[uc].function = func;
}
#define SET_SPECIAL(sc, func) \ /* used later */
do \ #define RESET_SPECIAL(uc) \
{ \
unsigned char uc; \
uc = ttybuff.c_cc[sc]; \
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \ if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
kmap[uc].function = func; \ kmap[uc].function = rl_insert;
} \
while (0)
if (get_tty_settings (tty, &ttybuff) == 0) static void
{ _rl_bind_tty_special_chars (kmap, ttybuff)
Keymap kmap;
TIOTYPE ttybuff;
{
SET_SPECIAL (VERASE, rl_rubout); SET_SPECIAL (VERASE, rl_rubout);
SET_SPECIAL (VKILL, rl_unix_line_discard); SET_SPECIAL (VKILL, rl_unix_line_discard);
...@@ -836,8 +857,24 @@ rltty_set_default_bindings (kmap) ...@@ -836,8 +857,24 @@ rltty_set_default_bindings (kmap)
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER) # if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VWERASE, rl_unix_word_rubout); SET_SPECIAL (VWERASE, rl_unix_word_rubout);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */ # endif /* VWERASE && TERMIOS_TTY_DRIVER */
} }
#endif /* !NEW_TTY_DRIVER */ #endif /* !NEW_TTY_DRIVER */
/* Set the system's default editing characters to their readline equivalents
in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
void
rltty_set_default_bindings (kmap)
Keymap kmap;
{
TIOTYPE ttybuff;
int tty;
static int called = 0;
tty = fileno (rl_instream);
if (get_tty_settings (tty, &ttybuff) == 0)
_rl_bind_tty_special_chars (kmap, ttybuff);
} }
/* 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
...@@ -849,6 +886,30 @@ rl_tty_set_default_bindings (kmap) ...@@ -849,6 +886,30 @@ rl_tty_set_default_bindings (kmap)
rltty_set_default_bindings (kmap); rltty_set_default_bindings (kmap);
} }
/* Rebind all of the tty special chars that readline worries about back
to self-insert. Call this before saving the current terminal special
chars with save_tty_chars(). This only works on POSIX termios or termio
systems. */
void
rl_tty_unset_default_bindings (kmap)
Keymap kmap;
{
/* Don't bother before we've saved the tty special chars at least once. */
if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
return;
RESET_SPECIAL (_rl_tty_chars.t_erase);
RESET_SPECIAL (_rl_tty_chars.t_kill);
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
RESET_SPECIAL (_rl_tty_chars.t_lnext);
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
RESET_SPECIAL (_rl_tty_chars.t_werase);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#if defined (HANDLE_SIGNALS) #if defined (HANDLE_SIGNALS)
#if defined (NEW_TTY_DRIVER) #if defined (NEW_TTY_DRIVER)
......
...@@ -61,22 +61,22 @@ ...@@ -61,22 +61,22 @@
#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */ #endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
typedef struct _rl_tty_chars { typedef struct _rl_tty_chars {
char t_eof; unsigned char t_eof;
char t_eol; unsigned char t_eol;
char t_eol2; unsigned char t_eol2;
char t_erase; unsigned char t_erase;
char t_werase; unsigned char t_werase;
char t_kill; unsigned char t_kill;
char t_reprint; unsigned char t_reprint;
char t_intr; unsigned char t_intr;
char t_quit; unsigned char t_quit;
char t_susp; unsigned char t_susp;
char t_dsusp; unsigned char t_dsusp;
char t_start; unsigned char t_start;
char t_stop; unsigned char t_stop;
char t_lnext; unsigned char t_lnext;
char t_flush; unsigned char t_flush;
char t_status; unsigned char t_status;
} _RL_TTY_CHARS; } _RL_TTY_CHARS;
#endif /* _RLTTY_H_ */ #endif /* _RLTTY_H_ */
/* rltypedefs.h -- Type declarations for readline functions. */ /* rltypedefs.h -- Type declarations for readline functions. */
/* Copyright (C) 2000 Free Software Foundation, Inc. /* Copyright (C) 2000-2004 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.
...@@ -79,6 +79,12 @@ typedef void rl_voidfunc_t PARAMS((void)); ...@@ -79,6 +79,12 @@ typedef void rl_voidfunc_t PARAMS((void));
typedef void rl_vintfunc_t PARAMS((int)); typedef void rl_vintfunc_t PARAMS((int));
typedef void rl_vcpfunc_t PARAMS((char *)); typedef void rl_vcpfunc_t PARAMS((char *));
typedef void rl_vcppfunc_t PARAMS((char **)); typedef void rl_vcppfunc_t PARAMS((char **));
typedef char *rl_cpvfunc_t PARAMS((void));
typedef char *rl_cpifunc_t PARAMS((int));
typedef char *rl_cpcpfunc_t PARAMS((char *));
typedef char *rl_cpcppfunc_t PARAMS((char **));
#endif /* _RL_FUNCTION_TYPEDEF */ #endif /* _RL_FUNCTION_TYPEDEF */
#ifdef __cplusplus #ifdef __cplusplus
......
/* savestring.c */
/* Copyright (C) 1998,2003 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library 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.
The GNU Readline Library 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.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include <config.h>
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#include "xmalloc.h"
/* Backwards compatibility, now that savestring has been removed from
all `public' readline header files. */
char *
savestring (s)
const char *s;
{
return ((char *)strcpy ((char *)xmalloc (1 + strlen (s)), (s)));
}
...@@ -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>
...@@ -80,8 +82,13 @@ static void ...@@ -80,8 +82,13 @@ static void
make_history_line_current (entry) make_history_line_current (entry)
HIST_ENTRY *entry; HIST_ENTRY *entry;
{ {
rl_replace_line (entry->line, 0); #if 0
rl_replace_line (entry->line, 1);
rl_undo_list = (UNDO_LIST *)entry->data; rl_undo_list = (UNDO_LIST *)entry->data;
#else
_rl_replace_text (entry->line, 0, rl_end);
_rl_fix_point (1);
#endif
if (_rl_saved_line_for_history) if (_rl_saved_line_for_history)
_rl_free_history_entry (_rl_saved_line_for_history); _rl_free_history_entry (_rl_saved_line_for_history);
...@@ -187,6 +194,11 @@ noninc_search (dir, pchar) ...@@ -187,6 +194,11 @@ noninc_search (dir, pchar)
saved_point = rl_point; saved_point = rl_point;
saved_mark = rl_mark; saved_mark = rl_mark;
/* Clear the undo list, since reading the search string should create its
own undo list, and the whole list will end up being freed when we
finish reading the search string. */
rl_undo_list = 0;
/* Use the line buffer to read the search string. */ /* Use the line buffer to read the search string. */
rl_line_buffer[0] = 0; rl_line_buffer[0] = 0;
rl_end = rl_point = 0; rl_end = rl_point = 0;
...@@ -294,7 +306,7 @@ noninc_search (dir, pchar) ...@@ -294,7 +306,7 @@ noninc_search (dir, pchar)
code calls this, KEY will be `?'. */ code calls this, KEY will be `?'. */
int int
rl_noninc_forward_search (count, key) rl_noninc_forward_search (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
noninc_search (1, (key == '?') ? '?' : 0); noninc_search (1, (key == '?') ? '?' : 0);
return 0; return 0;
...@@ -304,7 +316,7 @@ rl_noninc_forward_search (count, key) ...@@ -304,7 +316,7 @@ rl_noninc_forward_search (count, key)
calls this, KEY will be `/'. */ calls this, KEY will be `/'. */
int int
rl_noninc_reverse_search (count, key) rl_noninc_reverse_search (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
noninc_search (-1, (key == '/') ? '/' : 0); noninc_search (-1, (key == '/') ? '/' : 0);
return 0; return 0;
...@@ -314,7 +326,7 @@ rl_noninc_reverse_search (count, key) ...@@ -314,7 +326,7 @@ rl_noninc_reverse_search (count, key)
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 (count, key) rl_noninc_forward_search_again (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
if (!noninc_search_string) if (!noninc_search_string)
{ {
...@@ -329,7 +341,7 @@ rl_noninc_forward_search_again (count, key) ...@@ -329,7 +341,7 @@ rl_noninc_forward_search_again (count, key)
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 (count, key) rl_noninc_reverse_search_again (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
if (!noninc_search_string) if (!noninc_search_string)
{ {
......
...@@ -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>
...@@ -124,6 +126,7 @@ sh_set_lines_and_columns (lines, cols) ...@@ -124,6 +126,7 @@ sh_set_lines_and_columns (lines, cols)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1); b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
sprintf (b, "LINES=%d", lines); sprintf (b, "LINES=%d", lines);
putenv (b); putenv (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1); b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
sprintf (b, "COLUMNS=%d", cols); sprintf (b, "COLUMNS=%d", cols);
putenv (b); putenv (b);
...@@ -132,9 +135,12 @@ sh_set_lines_and_columns (lines, cols) ...@@ -132,9 +135,12 @@ sh_set_lines_and_columns (lines, cols)
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);
free (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1); b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", cols); sprintf (b, "%d", cols);
setenv ("COLUMNS", b, 1); setenv ("COLUMNS", b, 1);
free (b);
# endif /* HAVE_SETENV */ # endif /* HAVE_SETENV */
#endif /* !HAVE_PUTENV */ #endif /* !HAVE_PUTENV */
} }
......
...@@ -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>
...@@ -71,6 +73,10 @@ typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt ...@@ -71,6 +73,10 @@ typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt
# define sigemptyset(m) # define sigemptyset(m)
#endif /* !HAVE_POSIX_SIGNALS */ #endif /* !HAVE_POSIX_SIGNALS */
#ifndef SA_RESTART
# define SA_RESTART 0
#endif
static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *)); static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
...@@ -83,6 +89,8 @@ int rl_catch_signals = 1; ...@@ -83,6 +89,8 @@ int rl_catch_signals = 1;
/* If non-zero, readline will install a signal handler for SIGWINCH. */ /* If non-zero, readline will install a signal handler for SIGWINCH. */
#ifdef SIGWINCH #ifdef SIGWINCH
int rl_catch_sigwinch = 1; int rl_catch_sigwinch = 1;
#else
int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
#endif #endif
static int signals_set_flag; static int signals_set_flag;
...@@ -231,7 +239,7 @@ rl_set_sighandler (sig, handler, ohandler) ...@@ -231,7 +239,7 @@ rl_set_sighandler (sig, handler, ohandler)
struct sigaction act; struct sigaction act;
act.sa_handler = handler; act.sa_handler = handler;
act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */ act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
sigemptyset (&act.sa_mask); sigemptyset (&act.sa_mask);
sigemptyset (&ohandler->sa_mask); sigemptyset (&ohandler->sa_mask);
sigaction (sig, &act, &old_handler); sigaction (sig, &act, &old_handler);
......
...@@ -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"
...@@ -82,41 +84,40 @@ static int tcap_initialized; ...@@ -82,41 +84,40 @@ static int tcap_initialized;
# if defined (__EMX__) || defined (NEED_EXTERN_PC) # if defined (__EMX__) || defined (NEED_EXTERN_PC)
extern extern
# endif /* __EMX__ || NEED_EXTERN_PC */ # endif /* __EMX__ || NEED_EXTERN_PC */
char PC; char PC, *BC, *UP;
char *BC, *UP;
#endif /* __linux__ */ #endif /* __linux__ */
/* Some strings to control terminal actions. These are output by tputs (). */ /* Some strings to control terminal actions. These are output by tputs (). */
const char *_rl_term_clreol; char *_rl_term_clreol;
const char *_rl_term_clrpag; char *_rl_term_clrpag;
const char *_rl_term_cr; char *_rl_term_cr;
const char *_rl_term_backspace; char *_rl_term_backspace;
const char *_rl_term_goto; char *_rl_term_goto;
const char *_rl_term_pc; char *_rl_term_pc;
/* Non-zero if we determine that the terminal can do character insertion. */ /* Non-zero if we determine that the terminal can do character insertion. */
int _rl_terminal_can_insert = 0; int _rl_terminal_can_insert = 0;
/* How to insert characters. */ /* How to insert characters. */
const char *_rl_term_im; char *_rl_term_im;
const char *_rl_term_ei; char *_rl_term_ei;
const char *_rl_term_ic; char *_rl_term_ic;
const char *_rl_term_ip; char *_rl_term_ip;
const char *_rl_term_IC; char *_rl_term_IC;
/* How to delete characters. */ /* How to delete characters. */
const char *_rl_term_dc; char *_rl_term_dc;
const char *_rl_term_DC; char *_rl_term_DC;
#if defined (HACK_TERMCAP_MOTION) #if defined (HACK_TERMCAP_MOTION)
char *_rl_term_forward_char; char *_rl_term_forward_char;
#endif /* HACK_TERMCAP_MOTION */ #endif /* HACK_TERMCAP_MOTION */
/* How to go up a line. */ /* How to go up a line. */
const char *_rl_term_up; char *_rl_term_up;
/* A visible bell; char if the terminal can be made to flash the screen. */ /* A visible bell; char if the terminal can be made to flash the screen. */
static const 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;
...@@ -126,30 +127,30 @@ static int term_has_meta; ...@@ -126,30 +127,30 @@ static int term_has_meta;
/* The sequences to write to turn on and off the meta key, if this /* The sequences to write to turn on and off the meta key, if this
terminal has one. */ terminal has one. */
static const char *_rl_term_mm; static char *_rl_term_mm;
static const char *_rl_term_mo; static char *_rl_term_mo;
/* The key sequences output by the arrow keys, if this terminal has any. */ /* The key sequences output by the arrow keys, if this terminal has any. */
static const char *_rl_term_ku; static char *_rl_term_ku;
static const char *_rl_term_kd; static char *_rl_term_kd;
static const char *_rl_term_kr; static char *_rl_term_kr;
static const char *_rl_term_kl; static char *_rl_term_kl;
/* How to initialize and reset the arrow keys, if this terminal has any. */ /* How to initialize and reset the arrow keys, if this terminal has any. */
static const char *_rl_term_ks; static char *_rl_term_ks;
static const char *_rl_term_ke; static char *_rl_term_ke;
/* The key sequences sent by the Home and End keys, if any. */ /* The key sequences sent by the Home and End keys, if any. */
static const char *_rl_term_kh; static char *_rl_term_kh;
static const char *_rl_term_kH; static char *_rl_term_kH;
static const char *_rl_term_at7; /* @7 */ static char *_rl_term_at7; /* @7 */
/* Insert key */ /* Insert key */
static const char *_rl_term_kI; static char *_rl_term_kI;
/* Cursor control */ /* Cursor control */
static const char *_rl_term_vs; /* very visible */ static char *_rl_term_vs; /* very visible */
static const char *_rl_term_ve; /* normal */ static char *_rl_term_ve; /* normal */
static void bind_termcap_arrow_keys PARAMS((Keymap)); static void bind_termcap_arrow_keys PARAMS((Keymap));
...@@ -295,7 +296,7 @@ rl_resize_terminal () ...@@ -295,7 +296,7 @@ rl_resize_terminal ()
struct _tc_string { struct _tc_string {
const char *tc_var; const char *tc_var;
const char **tc_value; char **tc_value;
}; };
/* This should be kept sorted, just in case we decide to change the /* This should be kept sorted, just in case we decide to change the
...@@ -343,14 +344,10 @@ get_term_capabilities (bp) ...@@ -343,14 +344,10 @@ get_term_capabilities (bp)
char **bp; char **bp;
{ {
#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */ #if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
register unsigned int i; register int i;
for (i = 0; i < NUM_TC_STRINGS; i++) for (i = 0; i < NUM_TC_STRINGS; i++)
# if defined(__LCC__) || defined(__MWERKS__)
*(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);
# else
*(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
# endif
#endif #endif
tcap_initialized = 1; tcap_initialized = 1;
} }
...@@ -432,8 +429,8 @@ _rl_init_terminal_io (terminal_name) ...@@ -432,8 +429,8 @@ _rl_init_terminal_io (terminal_name)
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 = (char*)(_rl_term_backspace = "\b"); BC = _rl_term_backspace = "\b";
UP = (char*)_rl_term_up; UP = _rl_term_up;
return 0; return 0;
} }
...@@ -443,8 +440,8 @@ _rl_init_terminal_io (terminal_name) ...@@ -443,8 +440,8 @@ _rl_init_terminal_io (terminal_name)
/* Set up the variables that the termcap library expects the application /* Set up the variables that the termcap library expects the application
to provide. */ to provide. */
PC = _rl_term_pc ? *_rl_term_pc : 0; PC = _rl_term_pc ? *_rl_term_pc : 0;
BC = (char*)_rl_term_backspace; BC = _rl_term_backspace;
UP = (char*)_rl_term_up; UP = _rl_term_up;
if (!_rl_term_cr) if (!_rl_term_cr)
_rl_term_cr = "\r"; _rl_term_cr = "\r";
...@@ -488,22 +485,22 @@ bind_termcap_arrow_keys (map) ...@@ -488,22 +485,22 @@ bind_termcap_arrow_keys (map)
xkeymap = _rl_keymap; xkeymap = _rl_keymap;
_rl_keymap = map; _rl_keymap = map;
_rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history); rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history);
_rl_bind_if_unbound (_rl_term_kd, rl_get_next_history); rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history);
_rl_bind_if_unbound (_rl_term_kr, rl_forward); rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char);
_rl_bind_if_unbound (_rl_term_kl, rl_backward); rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char);
_rl_bind_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_if_unbound (_rl_term_at7, rl_end_of_line); /* End */ rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
_rl_keymap = xkeymap; _rl_keymap = xkeymap;
} }
const char * char *
rl_get_termcap (cap) rl_get_termcap (cap)
const char *cap; const char *cap;
{ {
register unsigned int i; register int i;
if (tcap_initialized == 0) if (tcap_initialized == 0)
return ((char *)NULL); return ((char *)NULL);
......
/* text.c -- text handling commands for readline. */ /* text.c -- text handling commands for readline. */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc. /* Copyright (C) 1987-2004 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>
...@@ -168,6 +170,9 @@ _rl_fix_point (fix_mark_too) ...@@ -168,6 +170,9 @@ _rl_fix_point (fix_mark_too)
} }
#undef _RL_FIX_POINT #undef _RL_FIX_POINT
/* Replace the contents of the line buffer between START and END with
TEXT. The operation is undoable. To replace the entire line in an
undoable mode, use _rl_replace_text(text, 0, rl_end); */
int int
_rl_replace_text (text, start, end) _rl_replace_text (text, start, end)
const char *text; const char *text;
...@@ -400,7 +405,7 @@ rl_backward (count, key) ...@@ -400,7 +405,7 @@ rl_backward (count, key)
/* Move to the beginning of the line. */ /* Move to the beginning of the line. */
int int
rl_beg_of_line (count, key) rl_beg_of_line (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
rl_point = 0; rl_point = 0;
return 0; return 0;
...@@ -409,7 +414,7 @@ rl_beg_of_line (count, key) ...@@ -409,7 +414,7 @@ rl_beg_of_line (count, key)
/* Move to the end of the line. */ /* Move to the end of the line. */
int int
rl_end_of_line (count, key) rl_end_of_line (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
rl_point = rl_end; rl_point = rl_end;
return 0; return 0;
...@@ -506,7 +511,7 @@ rl_backward_word (count, key) ...@@ -506,7 +511,7 @@ 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 (ignore1, ignore2) rl_refresh_line (ignore1, ignore2)
int ignore1 __attribute__((unused)), ignore2 __attribute__((unused)); int ignore1, ignore2;
{ {
int curr_line; int curr_line;
...@@ -545,7 +550,7 @@ rl_clear_screen (count, key) ...@@ -545,7 +550,7 @@ rl_clear_screen (count, key)
int int
rl_arrow_keys (count, c) rl_arrow_keys (count, c)
int count, c __attribute__((unused)); int count, c;
{ {
int ch; int ch;
...@@ -799,13 +804,10 @@ _rl_overwrite_char (count, c) ...@@ -799,13 +804,10 @@ _rl_overwrite_char (count, c)
k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX); k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
#endif #endif
for (i = 0; i < count; i++)
{
rl_begin_undo_group (); rl_begin_undo_group ();
if (rl_point < rl_end) for (i = 0; i < count; i++)
rl_delete (1, c); {
#if defined (HANDLE_MULTIBYTE) #if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (mbkey); rl_insert_text (mbkey);
...@@ -813,9 +815,12 @@ _rl_overwrite_char (count, c) ...@@ -813,9 +815,12 @@ _rl_overwrite_char (count, c)
#endif #endif
_rl_insert_char (1, c); _rl_insert_char (1, c);
rl_end_undo_group (); if (rl_point < rl_end)
rl_delete (1, c);
} }
rl_end_undo_group ();
return 0; return 0;
} }
...@@ -830,7 +835,7 @@ rl_insert (count, c) ...@@ -830,7 +835,7 @@ rl_insert (count, c)
/* Insert the next typed character verbatim. */ /* Insert the next typed character verbatim. */
int int
rl_quoted_insert (count, key) rl_quoted_insert (count, key)
int count, key __attribute__((unused)); int count, key;
{ {
int c; int c;
...@@ -852,7 +857,7 @@ rl_quoted_insert (count, key) ...@@ -852,7 +857,7 @@ rl_quoted_insert (count, key)
/* Insert a tab character. */ /* Insert a tab character. */
int int
rl_tab_insert (count, key) rl_tab_insert (count, key)
int count, key __attribute__((unused)); int count, key;
{ {
return (_rl_insert_char (count, '\t')); return (_rl_insert_char (count, '\t'));
} }
...@@ -862,7 +867,7 @@ rl_tab_insert (count, key) ...@@ -862,7 +867,7 @@ rl_tab_insert (count, key)
meaning in the future. */ meaning in the future. */
int int
rl_newline (count, key) rl_newline (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
rl_done = 1; rl_done = 1;
...@@ -875,6 +880,7 @@ rl_newline (count, key) ...@@ -875,6 +880,7 @@ rl_newline (count, key)
if (rl_editing_mode == vi_mode) if (rl_editing_mode == vi_mode)
{ {
_rl_vi_done_inserting (); _rl_vi_done_inserting ();
if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
_rl_vi_reset_last (); _rl_vi_reset_last ();
} }
#endif /* VI_MODE */ #endif /* VI_MODE */
...@@ -895,7 +901,7 @@ rl_newline (count, key) ...@@ -895,7 +901,7 @@ rl_newline (count, key)
is special cased. */ is special cased. */
int int
rl_do_lowercase_version (ignore1, ignore2) rl_do_lowercase_version (ignore1, ignore2)
int ignore1 __attribute__((unused)), ignore2 __attribute__((unused)); int ignore1, ignore2;
{ {
return 0; return 0;
} }
...@@ -933,9 +939,12 @@ _rl_overwrite_rubout (count, key) ...@@ -933,9 +939,12 @@ _rl_overwrite_rubout (count, key)
rl_delete_text (opoint, rl_point); rl_delete_text (opoint, rl_point);
/* Emacs puts point at the beginning of the sequence of spaces. */ /* Emacs puts point at the beginning of the sequence of spaces. */
if (rl_point < rl_end)
{
opoint = rl_point; opoint = rl_point;
_rl_insert_char (l, ' '); _rl_insert_char (l, ' ');
rl_point = opoint; rl_point = opoint;
}
rl_end_undo_group (); rl_end_undo_group ();
...@@ -1087,7 +1096,7 @@ rl_rubout_or_delete (count, key) ...@@ -1087,7 +1096,7 @@ 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 (count, ignore) rl_delete_horizontal_space (count, ignore)
int count __attribute__((unused)), ignore __attribute__((unused)); int count, ignore;
{ {
int start = rl_point; int start = rl_point;
...@@ -1128,9 +1137,9 @@ rl_delete_or_show_completions (count, key) ...@@ -1128,9 +1137,9 @@ rl_delete_or_show_completions (count, key)
A K*rn shell style function. */ A K*rn shell style function. */
int int
rl_insert_comment (count, key) rl_insert_comment (count, key)
int count __attribute__((unused)), key; int count, key;
{ {
const 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);
...@@ -1167,7 +1176,7 @@ rl_insert_comment (count, key) ...@@ -1167,7 +1176,7 @@ rl_insert_comment (count, key)
/* Uppercase the word at point. */ /* Uppercase the word at point. */
int int
rl_upcase_word (count, key) rl_upcase_word (count, key)
int count, key __attribute__((unused)); int count, key;
{ {
return (rl_change_case (count, UpCase)); return (rl_change_case (count, UpCase));
} }
...@@ -1175,7 +1184,7 @@ rl_upcase_word (count, key) ...@@ -1175,7 +1184,7 @@ rl_upcase_word (count, key)
/* Lowercase the word at point. */ /* Lowercase the word at point. */
int int
rl_downcase_word (count, key) rl_downcase_word (count, key)
int count, key __attribute__((unused)); int count, key;
{ {
return (rl_change_case (count, DownCase)); return (rl_change_case (count, DownCase));
} }
...@@ -1183,7 +1192,7 @@ rl_downcase_word (count, key) ...@@ -1183,7 +1192,7 @@ rl_downcase_word (count, key)
/* Upcase the first letter, downcase the rest. */ /* Upcase the first letter, downcase the rest. */
int int
rl_capitalize_word (count, key) rl_capitalize_word (count, key)
int count, key __attribute__((unused)); int count, key;
{ {
return (rl_change_case (count, CapCase)); return (rl_change_case (count, CapCase));
} }
...@@ -1308,7 +1317,7 @@ rl_transpose_words (count, key) ...@@ -1308,7 +1317,7 @@ rl_transpose_words (count, key)
then transpose the characters before point. */ then transpose the characters before point. */
int int
rl_transpose_chars (count, key) rl_transpose_chars (count, key)
int count, key __attribute__((unused)); int count, key;
{ {
#if defined (HANDLE_MULTIBYTE) #if defined (HANDLE_MULTIBYTE)
char *dummy; char *dummy;
...@@ -1480,14 +1489,14 @@ _rl_char_search (count, fdir, bdir) ...@@ -1480,14 +1489,14 @@ _rl_char_search (count, fdir, bdir)
int int
rl_char_search (count, key) rl_char_search (count, key)
int count, key __attribute__((unused)); int count, key;
{ {
return (_rl_char_search (count, FFIND, BFIND)); return (_rl_char_search (count, FFIND, BFIND));
} }
int int
rl_backward_char_search (count, key) rl_backward_char_search (count, key)
int count, key __attribute__((unused)); int count, key;
{ {
return (_rl_char_search (count, BFIND, FFIND)); return (_rl_char_search (count, BFIND, FFIND));
} }
...@@ -1513,7 +1522,7 @@ _rl_set_mark_at_pos (position) ...@@ -1513,7 +1522,7 @@ _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 (count, key) rl_set_mark (count, key)
int count, key __attribute__((unused)); 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));
} }
...@@ -1521,7 +1530,7 @@ rl_set_mark (count, key) ...@@ -1521,7 +1530,7 @@ rl_set_mark (count, key)
/* Exchange the position of mark and point. */ /* Exchange the position of mark and point. */
int int
rl_exchange_point_and_mark (count, key) rl_exchange_point_and_mark (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
if (rl_mark > rl_end) if (rl_mark > rl_end)
rl_mark = -1; rl_mark = -1;
......
...@@ -19,7 +19,11 @@ ...@@ -19,7 +19,11 @@
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. */
#include "config_readline.h" #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_UNISTD_H) #if defined (HAVE_UNISTD_H)
# ifdef _MINIX # ifdef _MINIX
...@@ -188,7 +192,7 @@ tilde_expand (string) ...@@ -188,7 +192,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));
......
...@@ -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>
...@@ -169,8 +171,7 @@ rl_do_undo () ...@@ -169,8 +171,7 @@ rl_do_undo ()
int int
_rl_fix_last_undo_of_type (type, start, end) _rl_fix_last_undo_of_type (type, start, end)
unsigned int type; int type, start, end;
int start, end;
{ {
UNDO_LIST *rl; UNDO_LIST *rl;
...@@ -228,7 +229,7 @@ rl_modifying (start, end) ...@@ -228,7 +229,7 @@ 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 (count, key) rl_revert_line (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
if (!rl_undo_list) if (!rl_undo_list)
rl_ding (); rl_ding ();
...@@ -243,7 +244,7 @@ rl_revert_line (count, key) ...@@ -243,7 +244,7 @@ rl_revert_line (count, key)
/* Do some undoing of things that were done. */ /* Do some undoing of things that were done. */
int int
rl_undo_command (count, key) rl_undo_command (count, key)
int count, key __attribute__((unused)); int count, key;
{ {
if (count < 0) if (count < 0)
return 0; /* Nothing to do. */ return 0; /* Nothing to do. */
......
...@@ -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>
...@@ -96,14 +98,14 @@ _rl_abort_internal () ...@@ -96,14 +98,14 @@ _rl_abort_internal ()
int int
rl_abort (count, key) rl_abort (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
return (_rl_abort_internal ()); return (_rl_abort_internal ());
} }
int int
rl_tty_status (count, key) rl_tty_status (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
#if defined (TIOCSTAT) #if defined (TIOCSTAT)
ioctl (1, TIOCSTAT, (char *)0); ioctl (1, TIOCSTAT, (char *)0);
...@@ -153,7 +155,7 @@ rl_extend_line_buffer (len) ...@@ -153,7 +155,7 @@ rl_extend_line_buffer (len)
/* A function for simple tilde expansion. */ /* A function for simple tilde expansion. */
int int
rl_tilde_expand (ignore, key) rl_tilde_expand (ignore, key)
int ignore __attribute__((unused)), key __attribute__((unused)); int ignore, key;
{ {
register int start, end; register int start, end;
char *homedir, *temp; char *homedir, *temp;
...@@ -248,7 +250,7 @@ _rl_strpbrk (string1, string2) ...@@ -248,7 +250,7 @@ _rl_strpbrk (string1, string2)
{ {
v = _rl_get_char_len (string1, &ps); v = _rl_get_char_len (string1, &ps);
if (v > 1) if (v > 1)
string += v - 1; /* -1 to account for auto-increment in loop */ string1 += v - 1; /* -1 to account for auto-increment in loop */
} }
#endif #endif
} }
......
/* 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, 1989, 1992 Free Software Foundation, Inc. /* Copyright (C) 1987-2004 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>
...@@ -61,6 +63,8 @@ ...@@ -61,6 +63,8 @@
#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0) #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
#endif #endif
int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
/* Non-zero means enter insertion mode. */ /* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert; static int _rl_vi_doing_insert;
...@@ -81,7 +85,6 @@ static int vi_continued_command; ...@@ -81,7 +85,6 @@ static int vi_continued_command;
static char *vi_insert_buffer; static char *vi_insert_buffer;
static int vi_insert_buffer_size; static int vi_insert_buffer_size;
static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
static int _rl_vi_last_repeat = 1; static int _rl_vi_last_repeat = 1;
static int _rl_vi_last_arg_sign = 1; static int _rl_vi_last_arg_sign = 1;
static int _rl_vi_last_motion; static int _rl_vi_last_motion;
...@@ -109,7 +112,7 @@ static int rl_digit_loop1 PARAMS((void)); ...@@ -109,7 +112,7 @@ static int rl_digit_loop1 PARAMS((void));
void void
_rl_vi_initialize_line () _rl_vi_initialize_line ()
{ {
register unsigned int i; register int i;
for (i = 0; i < 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;
...@@ -133,6 +136,16 @@ _rl_vi_set_last (key, repeat, sign) ...@@ -133,6 +136,16 @@ _rl_vi_set_last (key, repeat, sign)
_rl_vi_last_arg_sign = sign; _rl_vi_last_arg_sign = sign;
} }
/* A convenience function that calls _rl_vi_set_last to save the last command
information and enters insertion mode. */
void
rl_vi_start_inserting (key, repeat, sign)
int key, repeat, sign;
{
_rl_vi_set_last (key, repeat, sign);
rl_vi_insertion_mode (1, key);
}
/* Is the command C a VI mode text modification command? */ /* Is the command C a VI mode text modification command? */
int int
_rl_vi_textmod_command (c) _rl_vi_textmod_command (c)
...@@ -156,7 +169,7 @@ _rl_vi_stuff_insert (count) ...@@ -156,7 +169,7 @@ _rl_vi_stuff_insert (count)
puts you back into insert mode. */ puts you back into insert mode. */
int int
rl_vi_redo (count, c) rl_vi_redo (count, c)
int count, c __attribute__((unused)); int count, c;
{ {
int r; int r;
...@@ -195,7 +208,7 @@ rl_vi_undo (count, key) ...@@ -195,7 +208,7 @@ 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 (count, key) rl_vi_yank_arg (count, key)
int count, key __attribute__((unused)); 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. */
...@@ -276,7 +289,7 @@ rl_vi_search (count, key) ...@@ -276,7 +289,7 @@ rl_vi_search (count, key)
/* Completion, from vi's point of view. */ /* Completion, from vi's point of view. */
int int
rl_vi_complete (ignore, key) rl_vi_complete (ignore, key)
int ignore __attribute__((unused)), 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])))
{ {
...@@ -295,21 +308,18 @@ rl_vi_complete (ignore, key) ...@@ -295,21 +308,18 @@ rl_vi_complete (ignore, key)
rl_complete (0, key); rl_complete (0, key);
if (key == '*' || key == '\\') if (key == '*' || key == '\\')
{ rl_vi_start_inserting (key, 1, rl_arg_sign);
_rl_vi_set_last (key, 1, rl_arg_sign);
rl_vi_insertion_mode (1, key);
}
return (0); return (0);
} }
/* Tilde expansion for vi mode. */ /* Tilde expansion for vi mode. */
int int
rl_vi_tilde_expand (ignore, key) rl_vi_tilde_expand (ignore, key)
int ignore __attribute__((unused)), key; int ignore, key;
{ {
rl_tilde_expand (0, key); rl_tilde_expand (0, key);
_rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */ rl_vi_start_inserting (key, 1, rl_arg_sign);
rl_vi_insertion_mode (1, key);
return (0); return (0);
} }
...@@ -377,7 +387,7 @@ rl_vi_end_word (count, key) ...@@ -377,7 +387,7 @@ 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 (count, ignore) rl_vi_fWord (count, ignore)
int count, ignore __attribute__((unused)); int count, ignore;
{ {
while (count-- && rl_point < (rl_end - 1)) while (count-- && rl_point < (rl_end - 1))
{ {
...@@ -394,7 +404,7 @@ rl_vi_fWord (count, ignore) ...@@ -394,7 +404,7 @@ rl_vi_fWord (count, ignore)
int int
rl_vi_bWord (count, ignore) rl_vi_bWord (count, ignore)
int count, ignore __attribute__((unused)); int count, ignore;
{ {
while (count-- && rl_point > 0) while (count-- && rl_point > 0)
{ {
...@@ -418,7 +428,7 @@ rl_vi_bWord (count, ignore) ...@@ -418,7 +428,7 @@ rl_vi_bWord (count, ignore)
int int
rl_vi_eWord (count, ignore) rl_vi_eWord (count, ignore)
int count, ignore __attribute__((unused)); int count, ignore;
{ {
while (count-- && rl_point < (rl_end - 1)) while (count-- && rl_point < (rl_end - 1))
{ {
...@@ -427,7 +437,8 @@ rl_vi_eWord (count, ignore) ...@@ -427,7 +437,8 @@ rl_vi_eWord (count, ignore)
/* Move to the next non-whitespace character (to the start of the /* Move to the next non-whitespace character (to the start of the
next word). */ next word). */
while (++rl_point < rl_end && whitespace (rl_line_buffer[rl_point])); while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
rl_point++;
if (rl_point && rl_point < rl_end) if (rl_point && rl_point < rl_end)
{ {
...@@ -448,7 +459,7 @@ rl_vi_eWord (count, ignore) ...@@ -448,7 +459,7 @@ rl_vi_eWord (count, ignore)
int int
rl_vi_fword (count, ignore) rl_vi_fword (count, ignore)
int count, ignore __attribute__((unused)); int count, ignore;
{ {
while (count-- && rl_point < (rl_end - 1)) while (count-- && rl_point < (rl_end - 1))
{ {
...@@ -474,7 +485,7 @@ rl_vi_fword (count, ignore) ...@@ -474,7 +485,7 @@ rl_vi_fword (count, ignore)
int int
rl_vi_bword (count, ignore) rl_vi_bword (count, ignore)
int count, ignore __attribute__((unused)); int count, ignore;
{ {
while (count-- && rl_point > 0) while (count-- && rl_point > 0)
{ {
...@@ -513,7 +524,7 @@ rl_vi_bword (count, ignore) ...@@ -513,7 +524,7 @@ rl_vi_bword (count, ignore)
int int
rl_vi_eword (count, ignore) rl_vi_eword (count, ignore)
int count, ignore __attribute__((unused)); int count, ignore;
{ {
while (count-- && rl_point < rl_end - 1) while (count-- && rl_point < rl_end - 1)
{ {
...@@ -538,7 +549,7 @@ rl_vi_eword (count, ignore) ...@@ -538,7 +549,7 @@ rl_vi_eword (count, ignore)
int int
rl_vi_insert_beg (count, key) rl_vi_insert_beg (count, key)
int count __attribute__((unused)), 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);
...@@ -547,7 +558,7 @@ rl_vi_insert_beg (count, key) ...@@ -547,7 +558,7 @@ rl_vi_insert_beg (count, key)
int int
rl_vi_append_mode (count, key) rl_vi_append_mode (count, key)
int count __attribute__((unused)), key; int count, key;
{ {
if (rl_point < rl_end) if (rl_point < rl_end)
{ {
...@@ -567,7 +578,7 @@ rl_vi_append_mode (count, key) ...@@ -567,7 +578,7 @@ rl_vi_append_mode (count, key)
int int
rl_vi_append_eol (count, key) rl_vi_append_eol (count, key)
int count __attribute__((unused)), 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);
...@@ -577,7 +588,7 @@ rl_vi_append_eol (count, key) ...@@ -577,7 +588,7 @@ rl_vi_append_eol (count, 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 (count, c) rl_vi_eof_maybe (count, c)
int count __attribute__((unused)), c __attribute__((unused)); int count, c;
{ {
return (rl_newline (1, '\n')); return (rl_newline (1, '\n'));
} }
...@@ -588,7 +599,7 @@ rl_vi_eof_maybe (count, c) ...@@ -588,7 +599,7 @@ rl_vi_eof_maybe (count, c)
switching keymaps. */ switching keymaps. */
int int
rl_vi_insertion_mode (count, key) rl_vi_insertion_mode (count, key)
int count __attribute__((unused)), 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;
...@@ -638,7 +649,7 @@ _rl_vi_done_inserting () ...@@ -638,7 +649,7 @@ _rl_vi_done_inserting ()
} }
else else
{ {
if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list) if ((_rl_vi_last_key_before_insert == 'i' || _rl_vi_last_key_before_insert == 'a') && rl_undo_list)
_rl_vi_save_insert (rl_undo_list); _rl_vi_save_insert (rl_undo_list);
/* XXX - Other keys probably need to be checked. */ /* XXX - Other keys probably need to be checked. */
else if (_rl_vi_last_key_before_insert == 'C') else if (_rl_vi_last_key_before_insert == 'C')
...@@ -651,7 +662,7 @@ _rl_vi_done_inserting () ...@@ -651,7 +662,7 @@ _rl_vi_done_inserting ()
int int
rl_vi_movement_mode (count, key) rl_vi_movement_mode (count, key)
int count __attribute__((unused)), key; int count, key;
{ {
if (rl_point > 0) if (rl_point > 0)
rl_backward_char (1, key); rl_backward_char (1, key);
...@@ -678,7 +689,8 @@ _rl_vi_change_mbchar_case (count) ...@@ -678,7 +689,8 @@ _rl_vi_change_mbchar_case (count)
int count; int count;
{ {
wchar_t wc; wchar_t wc;
char mb[MB_LEN_MAX]; char mb[MB_LEN_MAX+1];
int mblen;
mbstate_t ps; mbstate_t ps;
memset (&ps, 0, sizeof (mbstate_t)); memset (&ps, 0, sizeof (mbstate_t));
...@@ -701,7 +713,9 @@ _rl_vi_change_mbchar_case (count) ...@@ -701,7 +713,9 @@ _rl_vi_change_mbchar_case (count)
/* Vi is kind of strange here. */ /* Vi is kind of strange here. */
if (wc) if (wc)
{ {
wctomb (mb, wc); mblen = wcrtomb (mb, wc, &ps);
if (mblen >= 0)
mb[mblen] = '\0';
rl_begin_undo_group (); rl_begin_undo_group ();
rl_delete (1, 0); rl_delete (1, 0);
rl_insert_text (mb); rl_insert_text (mb);
...@@ -718,14 +732,15 @@ _rl_vi_change_mbchar_case (count) ...@@ -718,14 +732,15 @@ _rl_vi_change_mbchar_case (count)
int int
rl_vi_change_case (count, ignore) rl_vi_change_case (count, ignore)
int count, ignore __attribute__((unused)); int count, ignore;
{ {
char c = 0; int c, p;
/* Don't try this on an empty line. */ /* Don't try this on an empty line. */
if (rl_point >= rl_end) if (rl_point >= rl_end)
return (0); return (0);
c = 0;
#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)
return (_rl_vi_change_mbchar_case (count)); return (_rl_vi_change_mbchar_case (count));
...@@ -747,8 +762,11 @@ rl_vi_change_case (count, ignore) ...@@ -747,8 +762,11 @@ rl_vi_change_case (count, ignore)
/* Vi is kind of strange here. */ /* Vi is kind of strange here. */
if (c) if (c)
{ {
p = rl_point;
rl_begin_undo_group (); rl_begin_undo_group ();
rl_delete (1, c); rl_vi_delete (1, c);
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++;
_rl_insert_char (1, c); _rl_insert_char (1, c);
rl_end_undo_group (); rl_end_undo_group ();
rl_vi_check (); rl_vi_check ();
...@@ -761,12 +779,14 @@ rl_vi_change_case (count, ignore) ...@@ -761,12 +779,14 @@ rl_vi_change_case (count, ignore)
int int
rl_vi_put (count, key) rl_vi_put (count, key)
int count __attribute__((unused)), key; int count, key;
{ {
if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end)) if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO); rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
while (count--)
rl_yank (1, key); rl_yank (1, key);
rl_backward_char (1, key); rl_backward_char (1, key);
return (0); return (0);
} }
...@@ -814,6 +834,7 @@ rl_vi_domove (key, nextkey) ...@@ -814,6 +834,7 @@ 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_digit_loop1 (); rl_digit_loop1 ();
rl_numeric_arg *= save; rl_numeric_arg *= save;
RL_SETSTATE(RL_STATE_MOREINPUT); RL_SETSTATE(RL_STATE_MOREINPUT);
...@@ -941,7 +962,7 @@ rl_digit_loop1 () ...@@ -941,7 +962,7 @@ rl_digit_loop1 ()
int int
rl_vi_delete_to (count, key) rl_vi_delete_to (count, key)
int count __attribute__((unused)), key; int count, key;
{ {
int c; int c;
...@@ -1012,8 +1033,7 @@ rl_vi_change_to (count, key) ...@@ -1012,8 +1033,7 @@ rl_vi_change_to (count, key)
/* `C' does not save the text inserted for undoing or redoing. */ /* `C' does not save the text inserted for undoing or redoing. */
if (_rl_uppercase_p (key) == 0) if (_rl_uppercase_p (key) == 0)
_rl_vi_doing_insert = 1; _rl_vi_doing_insert = 1;
_rl_vi_set_last (key, count, rl_arg_sign); rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
rl_vi_insertion_mode (1, key);
} }
return (0); return (0);
...@@ -1021,7 +1041,7 @@ rl_vi_change_to (count, key) ...@@ -1021,7 +1041,7 @@ rl_vi_change_to (count, key)
int int
rl_vi_yank_to (count, key) rl_vi_yank_to (count, key)
int count __attribute__((unused)), key; int count, key;
{ {
int c, save = rl_point; int c, save = rl_point;
...@@ -1077,7 +1097,7 @@ rl_vi_delete (count, key) ...@@ -1077,7 +1097,7 @@ rl_vi_delete (count, key)
int int
rl_vi_back_to_indent (count, key) rl_vi_back_to_indent (count, key)
int count __attribute__((unused)), 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]))
...@@ -1087,7 +1107,7 @@ rl_vi_back_to_indent (count, key) ...@@ -1087,7 +1107,7 @@ rl_vi_back_to_indent (count, key)
int int
rl_vi_first_print (count, key) rl_vi_first_print (count, key)
int count __attribute__((unused)), key; int count, key;
{ {
return (rl_vi_back_to_indent (1, key)); return (rl_vi_back_to_indent (1, key));
} }
...@@ -1156,7 +1176,7 @@ rl_vi_char_search (count, key) ...@@ -1156,7 +1176,7 @@ rl_vi_char_search (count, key)
/* Match brackets */ /* Match brackets */
int int
rl_vi_match (ignore, key) rl_vi_match (ignore, key)
int ignore __attribute__((unused)), key; int ignore, key;
{ {
int count = 1, brack, pos, tmp, pre; int count = 1, brack, pos, tmp, pre;
...@@ -1262,14 +1282,14 @@ rl_vi_bracktype (c) ...@@ -1262,14 +1282,14 @@ rl_vi_bracktype (c)
/* XXX - think about reading an entire mbchar with _rl_read_mbchar and /* XXX - think about reading an entire mbchar with _rl_read_mbchar and
inserting it in one bunch instead of the loop below (like in inserting it in one bunch instead of the loop below (like in
rl_vi_char_search or _rl_vi_change_mbchar_case. Set c to mbchar[0] rl_vi_char_search or _rl_vi_change_mbchar_case). Set c to mbchar[0]
for test against 033 or ^C. Make sure that _rl_read_mbchar does for test against 033 or ^C. Make sure that _rl_read_mbchar does
this right. */ this right. */
int int
rl_vi_change_char (count, key) rl_vi_change_char (count, key)
int count, key __attribute__((unused)); int count, key;
{ {
int c; int c, p;
if (vi_redoing) if (vi_redoing)
c = _rl_vi_last_replacement; c = _rl_vi_last_replacement;
...@@ -1283,11 +1303,11 @@ rl_vi_change_char (count, key) ...@@ -1283,11 +1303,11 @@ rl_vi_change_char (count, key)
if (c == '\033' || c == CTRL ('C')) if (c == '\033' || c == CTRL ('C'))
return -1; return -1;
rl_begin_undo_group ();
while (count-- && rl_point < rl_end) while (count-- && rl_point < rl_end)
{ {
rl_begin_undo_group (); p = rl_point;
rl_vi_delete (1, c);
rl_delete (1, c);
#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)) while (_rl_insert_char (1, c))
...@@ -1298,12 +1318,14 @@ rl_vi_change_char (count, key) ...@@ -1298,12 +1318,14 @@ rl_vi_change_char (count, key)
} }
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);
if (count == 0)
rl_backward_char (1, c);
rl_end_undo_group ();
} }
}
rl_end_undo_group ();
return (0); return (0);
} }
...@@ -1313,7 +1335,7 @@ rl_vi_subst (count, key) ...@@ -1313,7 +1335,7 @@ rl_vi_subst (count, key)
{ {
/* If we are redoing, rl_vi_change_to will stuff the last motion char */ /* If we are redoing, rl_vi_change_to will stuff the last motion char */
if (vi_redoing == 0) if (vi_redoing == 0)
rl_stuff_char ((key == 'S') ? 'c' : ' '); /* `S' == `cc', `s' == `c ' */ rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
return (rl_vi_change_to (count, 'c')); return (rl_vi_change_to (count, 'c'));
} }
...@@ -1370,7 +1392,7 @@ rl_vi_overstrike_delete (count, key) ...@@ -1370,7 +1392,7 @@ rl_vi_overstrike_delete (count, key)
int int
rl_vi_replace (count, key) rl_vi_replace (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
int i; int i;
...@@ -1431,7 +1453,7 @@ rl_vi_possible_completions() ...@@ -1431,7 +1453,7 @@ rl_vi_possible_completions()
/* Functions to save and restore marks. */ /* Functions to save and restore marks. */
int int
rl_vi_set_mark (count, key) rl_vi_set_mark (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
int ch; int ch;
...@@ -1451,7 +1473,7 @@ rl_vi_set_mark (count, key) ...@@ -1451,7 +1473,7 @@ rl_vi_set_mark (count, key)
int int
rl_vi_goto_mark (count, key) rl_vi_goto_mark (count, key)
int count __attribute__((unused)), key __attribute__((unused)); int count, key;
{ {
int ch; int ch;
......
...@@ -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>
......
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