readline: integrate upstream patches

- Add convenience script to update them
- Update package URL

Signed-off-by: Aleksey Vasilenko <aleksey.vasilenko@gmail.com>
This commit is contained in:
Aleksey Vasilenko 2024-08-25 18:57:01 +03:00
parent ae5489e578
commit daff93952b
17 changed files with 844 additions and 2 deletions

View File

@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=readline
PKG_VERSION:=8.2
PKG_RELEASE:=2
PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=@GNU/readline
@ -32,7 +32,7 @@ define Package/libreadline
CATEGORY:=Libraries
TITLE:=Command lines edition library
DEPENDS:=+libncursesw
URL:=http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html
URL:=https://tiswww.case.edu/php/chet/readline/rltop.html
ABI_VERSION:=8
endef

View File

@ -0,0 +1,16 @@
#!/bin/sh
pkgver=$(grep -Po "(?<=PKG_VERSION:=)(.*)" Makefile)
patchlevel=13
i=1
while [ $i -le $patchlevel ]; do
patch=$(printf "%03d" $i)
url=https://ftp.gnu.org/gnu/readline/readline-$pkgver-patches/readline${pkgver//./}-$patch
## Download patch and remove 'patch -p0' requirement
curl $url | sed \
-e 's/..\/readline-'${pkgver}'.*\//a\//g' \
-e 's!^--- !&b/!' \
-e '/patch -p0/d' > patches/$patch-readline.patch
i=$((i+1))
done

View File

@ -0,0 +1,36 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-001
Bug-Reported-by: Kan-Ru Chen <koster@debian.org>
Bug-Reference-ID:
Bug-Reference-URL: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1021109
Bug-Description:
Starting a readline application with an invalid locale specification for
LC_ALL/LANG/LC_CTYPE can cause it crash on the first call to readline.
--- a/nls.c
+++ b/nls.c
@@ -141,6 +141,10 @@ _rl_init_locale (void)
if (lspec == 0)
lspec = "";
ret = setlocale (LC_CTYPE, lspec); /* ok, since it does not change locale */
+ if (ret == 0 || *ret == 0)
+ ret = setlocale (LC_CTYPE, (char *)NULL);
+ if (ret == 0 || *ret == 0)
+ ret = RL_DEFAULT_LOCALE;
#else
ret = (lspec == 0 || *lspec == 0) ? RL_DEFAULT_LOCALE : lspec;
#endif
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-0
+1

View File

@ -0,0 +1,39 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-002
Bug-Reported-by: srobertson@peratonlabs.com
Bug-Reference-ID:
Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-09/msg00049.html
Bug-Description:
It's possible for readline to try to zero out a line that's not null-
terminated, leading to a memory fault.
--- a/display.c
+++ b/display.c
@@ -2683,11 +2683,8 @@ rl_forced_update_display (void)
register char *temp;
if (visible_line)
- {
- temp = visible_line;
- while (*temp)
- *temp++ = '\0';
- }
+ memset (visible_line, 0, line_size);
+
rl_on_new_line ();
forced_display++;
(*rl_redisplay_function) ();
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-1
+2

View File

@ -0,0 +1,34 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-003
Bug-Reported-by: Stefan Klinger <readline-gnu.org@stefan-klinger.de>
Bug-Reference-ID:
Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-readline/2023-08/msg00018.html
Bug-Description:
The custom color prefix that readline uses to color possible completions
must have a leading `.'.
--- a/colors.c
+++ b/colors.c
@@ -73,7 +73,7 @@
static bool is_colored (enum indicator_no type);
static void restore_default_color (void);
-#define RL_COLOR_PREFIX_EXTENSION "readline-colored-completion-prefix"
+#define RL_COLOR_PREFIX_EXTENSION ".readline-colored-completion-prefix"
COLOR_EXT_TYPE *_rl_color_ext_list = 0;
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-2
+3

View File

@ -0,0 +1,52 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-004
Bug-Reported-by: Henry Bent <henry.r.bent@gmail.com>
Bug-Reference-ID:
Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-11/msg00044.html
Bug-Description:
There are systems that supply one of select or pselect, but not both.
--- a/input.c
+++ b/input.c
@@ -151,7 +151,9 @@ int rl_timeout_remaining (unsigned int *
int _rl_timeout_init (void);
int _rl_timeout_sigalrm_handler (void);
+#if defined (RL_TIMEOUT_USE_SELECT)
int _rl_timeout_select (int, fd_set *, fd_set *, fd_set *, const struct timeval *, const sigset_t *);
+#endif
static void _rl_timeout_handle (void);
#if defined (RL_TIMEOUT_USE_SIGALRM)
@@ -248,7 +250,7 @@ rl_gather_tyi (void)
register int tem, result;
int chars_avail, k;
char input;
-#if defined(HAVE_SELECT)
+#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
fd_set readfds, exceptfds;
struct timeval timeout;
#endif
@@ -805,7 +807,7 @@ rl_getc (FILE *stream)
int result;
unsigned char c;
int fd;
-#if defined (HAVE_PSELECT)
+#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
sigset_t empty_set;
fd_set readfds;
#endif
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-3
+4

View File

@ -0,0 +1,41 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-005
Bug-Reported-by: Simon Marchi <simon.marchi@polymtl.ca>
Bug-Reference-ID:
Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-readline/2022-09/msg00005.html
Bug-Description:
If an application is using readline in callback mode, and a signal arrives
after readline checks for it in rl_callback_read_char() but before it
restores the application's signal handlers, it won't get processed until the
next time the application calls rl_callback_read_char(). Readline needs to
check for and resend any pending signals after restoring the application's
signal handlers.
--- a/callback.c
+++ b/callback.c
@@ -115,7 +115,10 @@ rl_callback_handler_install (const char
#define CALLBACK_READ_RETURN() \
do { \
if (rl_persistent_signal_handlers == 0) \
- rl_clear_signals (); \
+ { \
+ rl_clear_signals (); \
+ if (_rl_caught_signal) _rl_signal_handler (_rl_caught_signal); \
+ } \
return; \
} while (0)
#else
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-4
+5

View File

@ -0,0 +1,90 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-006
Bug-Reported-by: Tom de Vries <tdevries@suse.de>
Bug-Reference-ID:
Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-readline/2022-09/msg00001.html
Bug-Description:
This is a variant of the same issue as the one fixed by patch 5. In this
case, the signal arrives and is pending before readline calls rl_getc().
When this happens, the pending signal will be handled by the loop, but may
alter or destroy some state that the callback uses. Readline needs to treat
this case the same way it would if a signal interrupts pselect/select, so
compound operations like searches and reading numeric arguments get cleaned
up properly.
--- a/input.c
+++ b/input.c
@@ -804,7 +804,7 @@ rl_read_key (void)
int
rl_getc (FILE *stream)
{
- int result;
+ int result, ostate, osig;
unsigned char c;
int fd;
#if defined (HAVE_PSELECT) || defined (HAVE_SELECT)
@@ -815,8 +815,22 @@ rl_getc (FILE *stream)
fd = fileno (stream);
while (1)
{
+ osig = _rl_caught_signal;
+ ostate = rl_readline_state;
+
RL_CHECK_SIGNALS ();
+#if defined (READLINE_CALLBACKS)
+ /* Do signal handling post-processing here, but just in callback mode
+ for right now because the signal cleanup can change some of the
+ callback state, and we need to either let the application have a
+ chance to react or abort some current operation that gets cleaned
+ up by rl_callback_sigcleanup(). If not, we'll just run through the
+ loop again. */
+ if (osig != 0 && (ostate & RL_STATE_CALLBACK))
+ goto postproc_signal;
+#endif
+
/* We know at this point that _rl_caught_signal == 0 */
#if defined (__MINGW32__)
@@ -880,6 +894,9 @@ rl_getc (FILE *stream)
/* fprintf(stderr, "rl_getc: result = %d errno = %d\n", result, errno); */
handle_error:
+ osig = _rl_caught_signal;
+ ostate = rl_readline_state;
+
/* If the error that we received was EINTR, then try again,
this is simply an interrupted system call to read (). We allow
the read to be interrupted if we caught SIGHUP, SIGTERM, or any
@@ -920,8 +937,17 @@ handle_error:
RL_CHECK_SIGNALS ();
#endif /* SIGALRM */
+postproc_signal:
+ /* POSIX says read(2)/pselect(2)/select(2) don't return EINTR for any
+ reason other than being interrupted by a signal, so we can safely
+ call the application's signal event hook. */
if (rl_signal_event_hook)
(*rl_signal_event_hook) ();
+#if defined (READLINE_CALLBACKS)
+ else if (osig == SIGINT && (ostate & RL_STATE_CALLBACK) && (ostate & (RL_STATE_ISEARCH|RL_STATE_NSEARCH|RL_STATE_NUMERICARG)))
+ /* just these cases for now */
+ _rl_abort_internal ();
+#endif
}
}
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-5
+6

View File

@ -0,0 +1,38 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-007
Bug-Reported-by: Kevin Pulo <kev@pulo.com.au>
Bug-Reference-ID:
Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-readline/2022-11/msg00002.html
Bug-Description:
If readline is called with no prompt, it should display a newline if return
is typed on an empty line. It should still suppress the final newline if
return is typed on the last (empty) line of a multi-line command.
--- a/display.c
+++ b/display.c
@@ -3338,9 +3338,9 @@ _rl_update_final (void)
puts_face (&last_line[_rl_screenwidth - 1 + woff],
&last_face[_rl_screenwidth - 1 + woff], 1);
}
- _rl_vis_botlin = 0;
- if (botline_length > 0 || _rl_last_c_pos > 0)
+ if ((_rl_vis_botlin == 0 && botline_length == 0) || botline_length > 0 || _rl_last_c_pos > 0)
rl_crlf ();
+ _rl_vis_botlin = 0;
fflush (rl_outstream);
rl_display_fixed++;
}
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-6
+7

View File

@ -0,0 +1,59 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-008
Bug-Reported-by:
Bug-Reference-ID:
Bug-Reference-URL:
Bug-Description:
Add missing prototypes for several function declarations.
--- a/text.c
+++ b/text.c
@@ -1764,8 +1764,7 @@ _rl_char_search (int count, int fdir, in
#if defined (READLINE_CALLBACKS)
static int
-_rl_char_search_callback (data)
- _rl_callback_generic_arg *data;
+_rl_char_search_callback (_rl_callback_generic_arg *data)
{
_rl_callback_func = 0;
_rl_want_redisplay = 1;
--- a/bind.c
+++ b/bind.c
@@ -1167,9 +1167,7 @@ _rl_init_file_error (va_alist)
/* **************************************************************** */
static int
-parse_comparison_op (s, indp)
- const char *s;
- int *indp;
+parse_comparison_op (const char *s, int *indp)
{
int i, peekc, op;
--- a/rltty.c
+++ b/rltty.c
@@ -80,8 +80,7 @@ static int ksrflow;
/* Dummy call to force a backgrounded readline to stop before it tries
to get the tty settings. */
static void
-set_winsize (tty)
- int tty;
+set_winsize (int tty)
{
#if defined (TIOCGWINSZ)
struct winsize w;
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-7
+8

View File

@ -0,0 +1,57 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-009
Bug-Reported-by: Stefan H. Holek <stefan@epy.co.at>
Bug-Reference-ID: <50F8DA45-B7F3-4DE1-AB94-19AE42649CDC@epy.co.at>
Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-readline/2022-10/msg00021.html
Bug-Description:
Fix issue where the directory name portion of the word to be completed (the
part that is passed to opendir()) requires both tilde expansion and dequoting.
Readline only performed tilde expansion in this case, so filename completion
would fail.
--- a/complete.c
+++ b/complete.c
@@ -2526,7 +2526,8 @@ rl_filename_completion_function (const c
temp = tilde_expand (dirname);
xfree (dirname);
dirname = temp;
- tilde_dirname = 1;
+ if (*dirname != '~')
+ tilde_dirname = 1; /* indicate successful tilde expansion */
}
/* We have saved the possibly-dequoted version of the directory name
@@ -2545,11 +2546,16 @@ rl_filename_completion_function (const c
xfree (users_dirname);
users_dirname = savestring (dirname);
}
- else if (tilde_dirname == 0 && rl_completion_found_quote && rl_filename_dequoting_function)
+ else if (rl_completion_found_quote && rl_filename_dequoting_function)
{
- /* delete single and double quotes */
+ /* We already ran users_dirname through the dequoting function.
+ If tilde_dirname == 1, we successfully performed tilde expansion
+ on dirname. Now we need to reconcile those results. We either
+ just copy the already-dequoted users_dirname or tilde expand it
+ if we tilde-expanded dirname. */
+ temp = tilde_dirname ? tilde_expand (users_dirname) : savestring (users_dirname);
xfree (dirname);
- dirname = savestring (users_dirname);
+ dirname = temp;
}
directory = opendir (dirname);
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-8
+9

View File

@ -0,0 +1,55 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-010
Bug-Reported-by: Martin Castillo <castilma@uni-bremen.de>
Bug-Reference-ID: <2d42153b-cf65-caba-dff1-cd3bc6268c7e@uni-bremen.de>
Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-readline/2023-01/msg00000.html
Bug-Description:
Fix the case where text to be completed from the line buffer (quoted) is
compared to the common prefix of the possible matches (unquoted) and the
quoting makes the former appear to be longer than the latter. Readline
assumes the match doesn't add any characters to the word and doesn't display
multiple matches.
--- a/complete.c
+++ b/complete.c
@@ -2031,9 +2031,25 @@ rl_complete_internal (int what_to_do)
text = rl_copy_text (start, end);
matches = gen_completion_matches (text, start, end, our_func, found_quote, quote_char);
+ /* If TEXT contains quote characters, it will be dequoted as part of
+ generating the matches, and the matches will not contain any quote
+ characters. We need to dequote TEXT before performing the comparison.
+ Since compare_match performs the dequoting, and we only want to do it
+ once, we don't call compare_matches after dequoting TEXT; we call
+ strcmp directly. */
/* nontrivial_lcd is set if the common prefix adds something to the word
being completed. */
- nontrivial_lcd = matches && compare_match (text, matches[0]) != 0;
+ if (rl_filename_completion_desired && rl_filename_quoting_desired &&
+ rl_completion_found_quote && rl_filename_dequoting_function)
+ {
+ char *t;
+ t = (*rl_filename_dequoting_function) (text, rl_completion_quote_character);
+ xfree (text);
+ text = t;
+ nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
+ }
+ else
+ nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
if (what_to_do == '!' || what_to_do == '@')
tlen = strlen (text);
xfree (text);
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-9
+10

View File

@ -0,0 +1,62 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-011
Bug-Reported-by: Grisha Levit <grishalevit@gmail.com>
Bug-Reference-ID: <CAMu=BrqWa_iNkiEwchpFmtrUhFrAanOO8pjy7VCKqRKUvqdsbw@mail.gmail.com>
Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2024-02/msg00075.html
Bug-Description:
Some systems (e.g., macOS) send signals early on in interactive initialization,
so readline should retry a failed open of the init file.
--- a/bind.c
+++ b/bind.c
@@ -978,11 +978,20 @@ _rl_read_file (char *filename, size_t *s
char *buffer;
int i, file;
- file = -1;
- if (((file = open (filename, O_RDONLY, 0666)) < 0) || (fstat (file, &finfo) < 0))
+ file = open (filename, O_RDONLY, 0666);
+ /* If the open is interrupted, retry once */
+ if (file < 0 && errno == EINTR)
{
+ RL_CHECK_SIGNALS ();
+ file = open (filename, O_RDONLY, 0666);
+ }
+
+ if ((file < 0) || (fstat (file, &finfo) < 0))
+ {
+ i = errno;
if (file >= 0)
close (file);
+ errno = i;
return ((char *)NULL);
}
@@ -991,10 +1000,13 @@ _rl_read_file (char *filename, size_t *s
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
+ i = errno;
if (file >= 0)
close (file);
#if defined (EFBIG)
errno = EFBIG;
+#else
+ errno = i;
#endif
return ((char *)NULL);
}
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-10
+11

View File

@ -0,0 +1,74 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-012
Bug-Reported-by: Grisha Levit <grishalevit@gmail.com>
Bug-Reference-ID: <CAMu=BroaH+41uumYt89FPqt8Fsatj-d6mZzmPV2HZYjtcbvbvw@mail.gmail.com>
Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-readline/2023-11/msg00019.html
Bug-Description:
If a user happens to bind do-lowercase-version to something that isn't a
capital letter, so _rl_to_lower doesn't change anything and the result is
still bound to do-lowercase-version, readline can recurse infinitely.
--- a/readline.c
+++ b/readline.c
@@ -899,8 +899,17 @@ _rl_dispatch_subseq (register int key, K
{
/* Special case rl_do_lowercase_version (). */
if (func == rl_do_lowercase_version)
- /* Should we do anything special if key == ANYOTHERKEY? */
- return (_rl_dispatch (_rl_to_lower ((unsigned char)key), map));
+ {
+ /* Should we do anything special if key == ANYOTHERKEY? */
+ newkey = _rl_to_lower ((unsigned char)key);
+ if (newkey != key)
+ return (_rl_dispatch (newkey, map));
+ else
+ {
+ rl_ding (); /* gentle failure */
+ return 0;
+ }
+ }
rl_executing_keymap = map;
rl_executing_key = key;
@@ -1109,7 +1118,11 @@ _rl_subseq_result (int r, Keymap map, in
type = m[ANYOTHERKEY].type;
func = m[ANYOTHERKEY].function;
if (type == ISFUNC && func == rl_do_lowercase_version)
- r = _rl_dispatch (_rl_to_lower ((unsigned char)key), map);
+ {
+ int newkey = _rl_to_lower ((unsigned char)key);
+ /* check that there is actually a lowercase version to avoid infinite recursion */
+ r = (newkey != key) ? _rl_dispatch (newkey, map) : 1;
+ }
else if (type == ISFUNC)
{
/* If we shadowed a function, whatever it is, we somehow need a
--- a/isearch.c
+++ b/isearch.c
@@ -428,7 +428,11 @@ add_character:
{
f = cxt->keymap[c].function;
if (f == rl_do_lowercase_version)
- f = cxt->keymap[_rl_to_lower (c)].function;
+ {
+ f = cxt->keymap[_rl_to_lower (c)].function;
+ if (f == rl_do_lowercase_version)
+ f = rl_insert;
+ }
}
if (f == rl_reverse_search_history)
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-11
+12

View File

@ -0,0 +1,189 @@
READLINE PATCH REPORT
=====================
Readline-Release: 8.2
Patch-ID: readline82-013
Bug-Reported-by: Grisha Levit <grishalevit@gmail.com>
Bug-Reference-ID: <CAMu=Brrv5qKY6LPfw8PxqNXNO8rNsZo0Fb=BcFb-uHObWPqnrw@mail.gmail.
Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2023-04/msg00082.html
Bug-Description:
When readline is accumulating bytes until it reads a complete multibyte
character, reading a byte that makes the multibyte character invalid can
result in discarding the bytes in the partial character.
--- a/text.c
+++ b/text.c
@@ -85,7 +85,8 @@ int _rl_optimize_typeahead = 1; /* rl_in
int
rl_insert_text (const char *string)
{
- register int i, l;
+ register int i;
+ size_t l;
l = (string && *string) ? strlen (string) : 0;
if (l == 0)
@@ -704,7 +705,11 @@ static mbstate_t ps = {0};
/* Insert the character C at the current location, moving point forward.
If C introduces a multibyte sequence, we read the whole sequence and
- then insert the multibyte char into the line buffer. */
+ then insert the multibyte char into the line buffer.
+ If C == 0, we immediately insert any pending partial multibyte character,
+ assuming that we have read a character that doesn't map to self-insert.
+ This doesn't completely handle characters that are part of a multibyte
+ character but map to editing functions. */
int
_rl_insert_char (int count, int c)
{
@@ -718,11 +723,28 @@ _rl_insert_char (int count, int c)
static int stored_count = 0;
#endif
+#if !defined (HANDLE_MULTIBYTE)
if (count <= 0)
return 0;
+#else
+ if (count < 0)
+ return 0;
+ if (count == 0)
+ {
+ if (pending_bytes_length == 0)
+ return 0;
+ if (stored_count <= 0)
+ stored_count = count;
+ else
+ count = stored_count;
-#if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX == 1 || rl_byte_oriented)
+ memcpy (incoming, pending_bytes, pending_bytes_length);
+ incoming[pending_bytes_length] = '\0';
+ incoming_length = pending_bytes_length;
+ pending_bytes_length = 0;
+ memset (&ps, 0, sizeof (mbstate_t));
+ }
+ else if (MB_CUR_MAX == 1 || rl_byte_oriented)
{
incoming[0] = c;
incoming[1] = '\0';
@@ -730,6 +752,9 @@ _rl_insert_char (int count, int c)
}
else if (_rl_utf8locale && (c & 0x80) == 0)
{
+ if (pending_bytes_length)
+ _rl_insert_char (0, 0);
+
incoming[0] = c;
incoming[1] = '\0';
incoming_length = 1;
@@ -764,7 +789,8 @@ _rl_insert_char (int count, int c)
incoming[1] = '\0';
incoming_length = 1;
pending_bytes_length--;
- memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
+ if (pending_bytes_length)
+ memmove (pending_bytes, pending_bytes + 1, pending_bytes_length);
/* Clear the state of the byte sequence, because in this case the
effect of mbstate is undefined. */
memset (&ps, 0, sizeof (mbstate_t));
@@ -827,7 +853,11 @@ _rl_insert_char (int count, int c)
rl_insert_text (string);
xfree (string);
+#if defined (HANDLE_MULTIBYTE)
+ return (pending_bytes_length != 0);
+#else
return 0;
+#endif
}
if (count > TEXT_COUNT_MAX)
@@ -860,6 +890,8 @@ _rl_insert_char (int count, int c)
xfree (string);
incoming_length = 0;
stored_count = 0;
+
+ return (pending_bytes_length != 0);
#else /* !HANDLE_MULTIBYTE */
char str[TEXT_COUNT_MAX+1];
@@ -873,9 +905,9 @@ _rl_insert_char (int count, int c)
rl_insert_text (str);
count -= decreaser;
}
-#endif /* !HANDLE_MULTIBYTE */
return 0;
+#endif /* !HANDLE_MULTIBYTE */
}
if (MB_CUR_MAX == 1 || rl_byte_oriented)
@@ -903,9 +935,11 @@ _rl_insert_char (int count, int c)
rl_insert_text (incoming);
stored_count = 0;
}
-#endif
-
+
+ return (pending_bytes_length != 0);
+#else
return 0;
+#endif
}
/* Overwrite the character at point (or next COUNT characters) with C.
@@ -983,6 +1017,11 @@ rl_insert (int count, int c)
break;
}
+ /* If we didn't insert n and there are pending bytes, we need to insert
+ them if _rl_insert_char didn't do that on its own. */
+ if (r == 1 && rl_insert_mode == RL_IM_INSERT)
+ r = _rl_insert_char (0, 0); /* flush partial multibyte char */
+
if (n != (unsigned short)-2) /* -2 = sentinel value for having inserted N */
{
/* setting rl_pending_input inhibits setting rl_last_func so we do it
@@ -1054,6 +1093,8 @@ _rl_insert_next_callback (_rl_callback_g
int
rl_quoted_insert (int count, int key)
{
+ int r;
+
/* Let's see...should the callback interface futz with signal handling? */
#if defined (HANDLE_SIGNALS)
if (RL_ISSTATE (RL_STATE_CALLBACK) == 0)
@@ -1072,15 +1113,17 @@ rl_quoted_insert (int count, int key)
/* A negative count means to quote the next -COUNT characters. */
if (count < 0)
{
- int r;
-
do
r = _rl_insert_next (1);
while (r == 0 && ++count < 0);
- return r;
}
+ else
+ r = _rl_insert_next (count);
- return _rl_insert_next (count);
+ if (r == 1)
+ _rl_insert_char (0, 0); /* insert partial multibyte character */
+
+ return r;
}
/* Insert a tab character. */
--- a/patchlevel
+++ b/patchlevel
@@ -1,3 +1,3 @@
# Do not edit -- exists only for use by patch
-12
+13