Subject: bug#30405: 26.0.91; Incorrect apostrophe translation in ImageMagick error message

From: Paul Eggert <[email-masked]>
Date: Sun, 11 Feb 2018 12:36:47 -0800

Eli Zaretskii wrote:
>    emacs -Q
>    M-x set-variable RET unibyte-display-via-language-environment RET t RET
>    M-: (set-buffer-multibyte nil) RET
>    C-q 0242 SPC
> 
> This should display ¢.
> 
> So I think we can get rid of making echo-area buffers unibyte, as long
> as we make sure that variable is nil (which it is by default).

Getting rid of it sounds good, but why do we need to worry about 
unibyte-display-via-language-environment? For me, the attached patch does 
display that test as ¢, and it fixes the other test cases reported so far in 
Bug#30405. And yet this patch works without worrying about 
unibyte-display-via-language-environment, even if I run Emacs in a unibyte 
locale like en_US.iso885915 (a practice that's no longer common).

For what it's worth, I'm testing on Ubuntu 16.04 and on Fedora 27, built 
--without-imagicmagick so that I can reproduce the original problem.
From 1ba9c7c8a0fe8c2ec6866a1dfb6b8c340d7d2139 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sun, 11 Feb 2018 12:26:43 -0800
Subject: [PATCH] Echo area multibyteness is independent of buffer

This fixes a problem where ImageMagick-related diagnostics
were mangled (Bug#30405).
* src/print.c (PRINTPREPARE, printchar, strout):
* src/xdisp.c (setup_echo_area_for_printing, set_message_1):
Don't mess with the multibyteness of the echo buffer.
* src/xdisp.c (message_enable_multibyte): Remove.
All uses removed.
---
 src/lisp.h  |  2 +-
 src/print.c | 17 +++++------------
 src/xdisp.c | 22 ++--------------------
 3 files changed, 8 insertions(+), 33 deletions(-)

diff --git a/src/lisp.h b/src/lisp.h
index a7f0a1d..2c5aaa0 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3613,7 +3613,7 @@ extern Lisp_Object echo_area_buffer[2];
 extern void add_to_log (char const *, ...);
 extern void vadd_to_log (char const *, va_list);
 extern void check_message_stack (void);
-extern void setup_echo_area_for_printing (bool);
+extern void setup_echo_area_for_printing (void);
 extern bool push_message (void);
 extern void pop_message_unwind (void);
 extern Lisp_Object restore_message_unwind (Lisp_Object);
diff --git a/src/print.c b/src/print.c
index b3c0f6f..fbf51aa 100644
--- a/src/print.c
+++ b/src/print.c
@@ -98,8 +98,6 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
    ptrdiff_t old_point_byte = -1, start_point_byte = -1;		\
    ptrdiff_t specpdl_count = SPECPDL_INDEX ();				\
    bool free_print_buffer = 0;						\
-   bool multibyte							\
-     = !NILP (BVAR (current_buffer, enable_multibyte_characters));	\
    Lisp_Object original = printcharfun;					\
    if (NILP (printcharfun)) printcharfun = Qt;				\
    if (BUFFERP (printcharfun))						\
@@ -154,7 +152,7 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
        print_buffer_pos_byte = 0;					\
      }									\
    if (EQ (printcharfun, Qt) && ! noninteractive)			\
-     setup_echo_area_for_printing (multibyte);
+     setup_echo_area_for_printing ();
 
 #define PRINTFINISH							\
    if (NILP (printcharfun))						\
@@ -303,12 +301,9 @@ printchar (unsigned int ch, Lisp_Object fun)
 	}
       else
 	{
-	  bool multibyte_p
-	    = !NILP (BVAR (current_buffer, enable_multibyte_characters));
-
-	  setup_echo_area_for_printing (multibyte_p);
+	  setup_echo_area_for_printing ();
 	  insert_char (ch);
-	  message_dolog ((char *) str, len, 0, multibyte_p);
+	  message_dolog ((char *) str, len, 0, true);
 	}
     }
 }
@@ -360,11 +355,9 @@ strout (const char *ptr, ptrdiff_t size, ptrdiff_t size_byte,
 	 here, that's the reason we don't call printchar to do the
 	 job.  */
       int i;
-      bool multibyte_p
-	= !NILP (BVAR (current_buffer, enable_multibyte_characters));
 
-      setup_echo_area_for_printing (multibyte_p);
-      message_dolog (ptr, size_byte, 0, multibyte_p);
+      setup_echo_area_for_printing ();
+      message_dolog (ptr, size_byte, 0, true);
 
       if (size == size_byte)
 	{
diff --git a/src/xdisp.c b/src/xdisp.c
index 7c90d32..236a4ae 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -445,11 +445,6 @@ Lisp_Object echo_area_window;
 
 static Lisp_Object Vmessage_stack;
 
-/* True means multibyte characters were enabled when the echo area
-   message was specified.  */
-
-static bool message_enable_multibyte;
-
 /* At each redisplay cycle, we should refresh everything there is to refresh.
    To do that efficiently, we use many optimizations that try to make sure we
    don't waste too much time updating things that haven't changed.
@@ -10947,11 +10942,10 @@ unwind_with_echo_area_buffer (Lisp_Object vector)
 }

-/* Set up the echo area for use by print functions.  MULTIBYTE_P
-   means we will print multibyte.  */
+/* Set up the echo area for use by print functions.  */
 
 void
-setup_echo_area_for_printing (bool multibyte_p)
+setup_echo_area_for_printing (void)
 {
   /* If we can't find an echo area any more, exit.  */
   if (! FRAME_LIVE_P (XFRAME (selected_frame)))
@@ -10982,11 +10976,6 @@ setup_echo_area_for_printing (bool multibyte_p)
 	}
       TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
 
-      /* Set up the buffer for the multibyteness we need.  */
-      if (multibyte_p
-	  != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
-	Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
-
       /* Raise the frame containing the echo area.  */
       if (minibuffer_auto_raise)
 	{
@@ -11409,8 +11398,6 @@ set_message (Lisp_Object string)
 {
   eassert (STRINGP (string));
 
-  message_enable_multibyte = STRING_MULTIBYTE (string);
-
   with_echo_area_buffer (0, -1, set_message_1, 0, string);
   message_buf_print = false;
   help_echo_showing_p = false;
@@ -11431,11 +11418,6 @@ set_message_1 (ptrdiff_t a1, Lisp_Object string)
 {
   eassert (STRINGP (string));
 
-  /* Change multibyteness of the echo buffer appropriately.  */
-  if (message_enable_multibyte
-      != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
-    Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
-
   bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
   if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
     bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
-- 
2.7.4