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.
This commit is contained in:
Eli Zaretskii 2016-01-06 20:25:45 +02:00
parent 2f32cb547f
commit c632466284
3 changed files with 38 additions and 9 deletions

View file

@ -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.

View file

@ -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)

View file

@ -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)