From c63246628461f748d66a8a07ba008de2e00fd33a Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 6 Jan 2016 20:25:45 +0200 Subject: [PATCH] Obey coding-system-for-write when writing stdout/stderr in batch * src/print.c (printchar_to_stream): * src/xdisp.c (message_to_stderr): If coding-system-for-write has a non-nil value, use it to encode output in preference to locale-coding-system. See the discussions in http://lists.gnu.org/archive/html/emacs-devel/2016-01/msg00048.html for the details. * doc/lispref/os.texi (Terminal Output): Document how to send non-ASCII text via 'send-string-to-terminal'. (Batch Mode): Document how text written to standard streams is encoded. Fix inaccuracy regarding which output streams are used by output functions in batch mode. --- doc/lispref/os.texi | 24 +++++++++++++++++------- src/print.c | 12 +++++++++++- src/xdisp.c | 11 ++++++++++- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 969c1d6e1ea..7206cd4ef86 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -2085,6 +2085,8 @@ than optimal. To fix the problem, set @code{baud-rate}. @defun send-string-to-terminal string &optional terminal This function sends @var{string} to @var{terminal} without alteration. Control characters in @var{string} have terminal-dependent effects. +(If you need to display non-ASCII text on the terminal, encode it +using one of the functions described in @ref{Explicit Encoding}.) This function operates only on text terminals. @var{terminal} may be a terminal object, a frame, or @code{nil} for the selected frame's terminal. In batch mode, @var{string} is sent to @code{stdout} when @@ -2252,13 +2254,21 @@ loads the library named @var{file}, or @samp{-f @var{function}}, which calls @var{function} with no arguments, or @samp{--eval @var{form}}. Any Lisp program output that would normally go to the echo area, -either using @code{message}, or using @code{prin1}, etc., with @code{t} -as the stream, goes instead to Emacs's standard error descriptor when -in batch mode. Similarly, input that would normally come from the -minibuffer is read from the standard input descriptor. -Thus, Emacs behaves much like a noninteractive -application program. (The echo area output that Emacs itself normally -generates, such as command echoing, is suppressed entirely.) +either using @code{message}, or using @code{prin1}, etc., with +@code{t} as the stream, goes instead to Emacs's standard descriptors +when in batch mode: @code{message} writes to the standard error +descriptor, while @code{prin1} and other print functions write to the +standard output. Similarly, input that would normally come from the +minibuffer is read from the standard input descriptor. Thus, Emacs +behaves much like a noninteractive application program. (The echo +area output that Emacs itself normally generates, such as command +echoing, is suppressed entirely.) + +Non-ASCII text written to the standard output or error descriptors is +by default encoded using @code{locale-coding-system} (@pxref{Locales}) +if it is non-@code{nil}; this can be overridden by binding +@code{coding-system-for-write} to a coding system of you choice +(@pxref{Explicit Encoding}). @defvar noninteractive This variable is non-@code{nil} when Emacs is running in batch mode. diff --git a/src/print.c b/src/print.c index 975675014d9..269d8f250e2 100644 --- a/src/print.c +++ b/src/print.c @@ -200,6 +200,13 @@ printchar_to_stream (unsigned int ch, FILE *stream) { Lisp_Object dv IF_LINT (= Qnil); ptrdiff_t i = 0, n = 1; + Lisp_Object coding_system = Vlocale_coding_system; + bool encode_p = false; + + if (!NILP (Vcoding_system_for_write)) + coding_system = Vcoding_system_for_write; + if (!NILP (coding_system)) + encode_p = true; if (CHAR_VALID_P (ch) && DISP_TABLE_P (Vstandard_display_table)) { @@ -228,8 +235,11 @@ printchar_to_stream (unsigned int ch, FILE *stream) unsigned char mbstr[MAX_MULTIBYTE_LENGTH]; int len = CHAR_STRING (ch, mbstr); Lisp_Object encoded_ch = - ENCODE_SYSTEM (make_multibyte_string ((char *) mbstr, 1, len)); + make_multibyte_string ((char *) mbstr, 1, len); + if (encode_p) + encoded_ch = code_convert_string_norecord (encoded_ch, + coding_system, true); fwrite (SSDATA (encoded_ch), 1, SBYTES (encoded_ch), stream); #ifdef WINDOWSNT if (print_output_debug_flag && stream == stderr) diff --git a/src/xdisp.c b/src/xdisp.c index b18bfd0d49d..ee748bd8680 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10206,7 +10206,16 @@ message_to_stderr (Lisp_Object m) } if (STRINGP (m)) { - Lisp_Object s = ENCODE_SYSTEM (m); + Lisp_Object coding_system = Vlocale_coding_system; + Lisp_Object s; + + if (!NILP (Vcoding_system_for_write)) + coding_system = Vcoding_system_for_write; + if (!NILP (coding_system)) + s = code_convert_string_norecord (m, coding_system, true); + else + s = m; + fwrite (SDATA (s), SBYTES (s), 1, stderr); } if (!cursor_in_echo_area) -- 2.39.5