]> git.ipfire.org Git - thirdparty/readline.git/commitdiff
fixes for incomplete multibyte characters; fix for ^C during incremental search in...
authorChet Ramey <chet.ramey@case.edu>
Sat, 3 Jun 2023 18:27:57 +0000 (14:27 -0400)
committerChet Ramey <chet.ramey@case.edu>
Sat, 3 Jun 2023 18:27:57 +0000 (14:27 -0400)
aclocal.m4
histexpand.c
isearch.c
mbutil.c
misc.c
readline.c
rldefs.h
text.c
util.c

index 2a86c70c6922068e8f083ff1c89c089bcd16f4fb..96d638373f82e92c6031d6d212a538a3f1ef1155 100644 (file)
@@ -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 3</dev/null) ; then
      bash_cv_dev_fd=standard
    else
      bash_cv_dev_fd=absent
    fi
+elif test "$host_os" = "openedition" && (exec test -r /dev/fd0 < /dev/null); then
+  bash_cv_dev_fd=nodir         # /dev/fdN via character device
 fi
 if test -z "$bash_cv_dev_fd" ; then 
   if test -d /proc/self/fd && (exec test -r /proc/self/fd/0 < /dev/null) ; then
@@ -1596,6 +1598,9 @@ if test $bash_cv_dev_fd = "standard"; then
 elif test $bash_cv_dev_fd = "whacky"; then
   AC_DEFINE(HAVE_DEV_FD)
   AC_DEFINE(DEV_FD_PREFIX, "/proc/self/fd/")
+elif test $bash_cv_dev_fd = "nodir"; then
+  AC_DEFINE(HAVE_DEV_FD)
+  AC_DEFINE(DEV_FD_PREFIX, "/dev/fd")
 fi
 ])
 
index db344b497f010e7130431d10a7e6cbc33e4e489e..425ea7cf1d04fd1825e692f95e5502a21bc793fd 100644 (file)
@@ -1121,7 +1121,7 @@ history_expand (const char *hstring, char **output)
 
          c = tchar;
          memset (mb, 0, sizeof (mb));
-         for (k = 0; k < MB_LEN_MAX; k++)
+         for (k = 0; k < MB_LEN_MAX && i < l; k++)
            {
              mb[k] = (char)c;
              memset (&ps, 0, sizeof (mbstate_t));
index c99072fdd1a855dce602dce0c77497eb88026399..1cc8e806d08e77ec0daef1a04b950df7d4373306 100644 (file)
--- a/isearch.c
+++ b/isearch.c
@@ -919,6 +919,13 @@ _rl_isearch_callback (_rl_search_cxt *cxt)
   int c, r;
 
   c = _rl_search_getchar (cxt);
+
+  if (c < 0)                                   /* EOF */
+    return 1;
+
+  if (RL_ISSTATE (RL_STATE_ISEARCH) == 0)      /* signal could turn it off */
+    return 1;
+
   /* We might want to handle EOF here */
   r = _rl_isearch_dispatch (cxt, cxt->lastc);
 
index 93d7b7bc51addf16c3a9aff0a36786c171289e8e..95d232f75000f2ccd4f1ae0ab10f75e6ccf6c476 100644 (file)
--- 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 6e9e03052651e91bc824c4d587167b12f1f41651..7e3efca4ec187cb801b22f2b061de9901887c88c 100644 (file)
--- 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 */
 }
index 65eb54e9e2db7da3f60ce87677c3f6f5d07111e7..cf70a01dad53f78fdce7a96793e712ce612ba66c 100644 (file)
@@ -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;
index 1ef0fbf7555bdec726cf4b3b2167c5840dbaa0e0..ec3c64a86f44d4323a0a173f5f346fa765d01d0f 100644 (file)
--- 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 356cac5f2b15ee1536679357ccf9aebeec2a1157..e3e5bb9eb0c82582af0b5c28a3ba5fe7993f3e27 100644 (file)
--- 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 61c40be5068489c607847d31f908fe75f9ebfa0c..f909daafc206b17fd5257aff0348b1ee4730ff13 100644 (file)
--- 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)
 {