]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix yes-or-no-p with multibyte spaces
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 17 Sep 2024 22:22:02 +0000 (15:22 -0700)
committerEshel Yaron <me@eshelyaron.com>
Wed, 18 Sep 2024 10:49:21 +0000 (12:49 +0200)
Problem reported by Thomas Klausner (Bug#73307).
Emacs shouldn’t use ctype.h, as it doesn’t work for multibyte
chars and it doesn’t work with Emacs’s locale model anyway.
* src/fns.c: Include syntax.h, not ctype.h.
(Fyes_or_no_p): Check the character category with SYNTAX, not
with isspace, which assumes the current locale and works only
with single-byte characters.

(cherry picked from commit 43cde03fa5a663a1509a762077c11eb57a60cee8)

src/fns.c

index 5881f147fd896d05de69a2ee98457e731537903b..be9faa3af066b98ffcb35bb3e2774e86de3d32a8 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -26,7 +26,6 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #include <intprops.h>
 #include <vla.h>
 #include <errno.h>
-#include <ctype.h>
 #include <math.h>
 
 #include "lisp.h"
@@ -36,6 +35,7 @@ along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
 #include "composite.h"
 #include "buffer.h"
 #include "intervals.h"
+#include "syntax.h"
 #include "window.h"
 #include "puresize.h"
 #include "gnutls.h"
@@ -3574,13 +3574,15 @@ by a mouse, or by some window-system gesture, or via a menu.  */)
   if (use_short_answers)
     return call1 (Qy_or_n_p, prompt);
 
-  {
-    char *s = SSDATA (prompt);
-    ptrdiff_t len = strlen (s);
-    if ((len > 0) && !isspace (s[len - 1]))
-      prompt = CALLN (Fconcat, prompt, build_string (" "));
-  }
-  prompt = CALLN (Fconcat, prompt, Vyes_or_no_prompt);
+  ptrdiff_t promptlen = SCHARS (prompt);
+  bool prompt_ends_in_nonspace
+    = (0 < promptlen
+       && (SYNTAX (XFIXNAT (Faref (prompt, make_fixnum (promptlen - 1))))
+          != Swhitespace));
+  AUTO_STRING (space_string, " ");
+  prompt = CALLN (Fconcat, prompt,
+                 prompt_ends_in_nonspace ? space_string : empty_unibyte_string,
+                 Vyes_or_no_prompt);
 
   specpdl_ref count = SPECPDL_INDEX ();
   /* Preserve the actual command that eventually called `yes-or-no-p'