From: Chet Ramey Date: Sat, 3 Jun 2023 18:27:57 +0000 (-0400) Subject: fixes for incomplete multibyte characters; fix for ^C during incremental search in... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5554d06e0abb52a6d56bba0e9f155aa02643274;p=thirdparty%2Freadline.git fixes for incomplete multibyte characters; fix for ^C during incremental search in callback mode; fix for binding do-lowercase-version to something that's not an uppercase letter --- diff --git a/aclocal.m4 b/aclocal.m4 index 2a86c70..96d6383 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1573,13 +1573,15 @@ AC_DEFUN(BASH_CHECK_DEV_FD, [AC_MSG_CHECKING(whether /dev/fd is available) AC_CACHE_VAL(bash_cv_dev_fd, [bash_cv_dev_fd="" -if test -d /dev/fd && (exec test -r /dev/fd/0 < /dev/null) ; then +if test -d /dev/fd && (exec test -r /dev/fd/0 < /dev/null) ; then # check for systems like FreeBSD 5 that only provide /dev/fd/[012] if (exec test -r /dev/fd/3 3lastc); diff --git a/mbutil.c b/mbutil.c index 93d7b7b..95d232f 100644 --- a/mbutil.c +++ b/mbutil.c @@ -361,8 +361,8 @@ _rl_get_char_len (const char *src, mbstate_t *ps) int mb_cur_max; /* Look at no more than MB_CUR_MAX characters */ - l = (size_t)strlen (src); - if (_rl_utf8locale && l > 0 && UTF8_SINGLEBYTE(*src)) + l = strlen (src); + if (_rl_utf8locale && l >= 0 && UTF8_SINGLEBYTE(*src)) tmp = (*src != 0) ? 1 : 0; else { diff --git a/misc.c b/misc.c index 6e9e030..7e3efca 100644 --- a/misc.c +++ b/misc.c @@ -307,6 +307,10 @@ void _rl_start_using_history (void) { using_history (); +#if 1 + if (_rl_saved_line_for_history && _rl_saved_line_for_history->data) + _rl_free_undo_list ((UNDO_LIST *)_rl_saved_line_for_history->data); +#endif _rl_free_saved_history_line (); _rl_history_search_pos = -99; /* some random invalid history position */ } diff --git a/readline.c b/readline.c index 65eb54e..cf70a01 100644 --- a/readline.c +++ b/readline.c @@ -905,8 +905,17 @@ _rl_dispatch_subseq (register int key, Keymap map, int got_subseq) { /* 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; diff --git a/rldefs.h b/rldefs.h index 1ef0fbf..ec3c64a 100644 --- a/rldefs.h +++ b/rldefs.h @@ -73,7 +73,7 @@ extern int _rl_stricmp (const char *, const char *); extern int _rl_strnicmp (const char *, const char *, int); #endif -#if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE) +#if defined (HAVE_STRPBRK) && !defined (HANDLE_MULTIBYTE) # define _rl_strpbrk(a,b) strpbrk((a),(b)) #else extern char *_rl_strpbrk (const char *, const char *); diff --git a/text.c b/text.c index 356cac5..e3e5bb9 100644 --- a/text.c +++ b/text.c @@ -85,7 +85,8 @@ int _rl_optimize_typeahead = 1; /* rl_insert tries to read typeahead */ 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 @@ -992,7 +1031,6 @@ rl_insert (int count, int c) rl_executing_keyseq[rl_key_sequence_length = 0] = '\0'; r = rl_execute_next (n); } - return r; } @@ -1054,6 +1092,8 @@ _rl_insert_next_callback (_rl_callback_generic_arg *data) 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 +1112,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. */ diff --git a/util.c b/util.c index 61c40be..f909daa 100644 --- a/util.c +++ b/util.c @@ -281,9 +281,10 @@ _rl_strindex (const char *s1, const char *s2) return ((char *)NULL); } -#ifndef HAVE_STRPBRK +#if !defined (HAVE_STRPBRK) || defined (HANDLE_MULTIBYTE) /* Find the first occurrence in STRING1 of any character from STRING2. - Return a pointer to the character in STRING1. */ + Return a pointer to the character in STRING1. Understands multibyte + characters. */ char * _rl_strpbrk (const char *string1, const char *string2) {