]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve handling of coding-system mnemonic indicators
authorEli Zaretskii <eliz@gnu.org>
Sun, 23 Aug 2020 18:23:45 +0000 (21:23 +0300)
committerEli Zaretskii <eliz@gnu.org>
Sun, 23 Aug 2020 18:23:45 +0000 (21:23 +0300)
This fixes assertion violations when the mnemonic is
given as a string, and allows non-ASCII characters be
used as mode-line mnemonic of a coding-system.
* src/xdisp.c (decode_mode_spec_coding): Handle multibyte
characters as coding-system's mnemonic.
(display_mode_element): If decode_mode_spec returns a multibyte
string, display it as multibyte.
* src/coding.c (Fdefine_coding_system_internal)
(Fcoding_system_put): If :mnemonic is a string, use its first
character.  This avoids assertion violations if someone uses a
string as the mnemonic of a coding-system.

src/coding.c
src/xdisp.c

index 51bd441de9db1bc98d06f05e0b50b2afc4bc427e..221a9cad898dc269d760d7dba71f3a0da9793393 100644 (file)
@@ -10895,7 +10895,10 @@ usage: (define-coding-system-internal ...)  */)
   ASET (attrs, coding_attr_base_name, name);
 
   Lisp_Object val = args[coding_arg_mnemonic];
-  if (! STRINGP (val))
+  /* decode_mode_spec_coding assumes the mnemonic is a single character.  */
+  if (STRINGP (val))
+    val = make_fixnum (STRING_CHAR (SDATA (val)));
+  else
     CHECK_CHARACTER (val);
   ASET (attrs, coding_attr_mnemonic, val);
 
@@ -11408,7 +11411,10 @@ DEFUN ("coding-system-put", Fcoding_system_put, Scoding_system_put,
   attrs = AREF (spec, 0);
   if (EQ (prop, QCmnemonic))
     {
-      if (! STRINGP (val))
+      /* decode_mode_spec_coding assumes the mnemonic is a single character.  */
+      if (STRINGP (val))
+       val = make_fixnum (STRING_CHAR (SDATA (val)));
+      else
        CHECK_CHARACTER (val);
       ASET (attrs, coding_attr_mnemonic, val);
     }
index e2ebbbdce72e06de4b9d8c046ee38541e5efe072..9d2bec379dc67d22cada1f7214b66ccb7868971a 100644 (file)
@@ -25637,6 +25637,11 @@ display_mode_element (struct it *it, int depth, int field_width, int precision,
                    spec = decode_mode_spec (it->w, c, field, &string);
                    eassert (NILP (string) || STRINGP (string));
                    multibyte = !NILP (string) && STRING_MULTIBYTE (string);
+                   /* Non-ASCII characters in SPEC should cause mode-line
+                      element be displayed as a multibyte string.  */
+                   ptrdiff_t nbytes = strlen (spec);
+                   if (multibyte_chars_in_text (spec, nbytes) != nbytes)
+                     multibyte = true;
 
                    switch (mode_line_target)
                      {
@@ -26255,9 +26260,10 @@ decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag)
       attrs = AREF (val, 0);
       eolvalue = AREF (val, 2);
 
-      *buf++ = multibyte
-       ? XFIXNAT (CODING_ATTR_MNEMONIC (attrs))
-       : ' ';
+      if (multibyte)
+       buf += CHAR_STRING (XFIXNAT (CODING_ATTR_MNEMONIC (attrs)), buf);
+      else
+       *buf++ = ' ';
 
       if (eol_flag)
        {