Omit needless "\ " after multibyte then newline

* src/print.c: Include <c-ctype.h>, for c_isxdigit.
(print_object): When print-escape-multibyte is non-nil and a
multibyte character is followed by a newline or formfeed, followed
by a hex digit, don't output a needless "\ " before the hex digit.
* test/automated/print-tests.el (print-hex-backslash): New test.
This commit is contained in:
Paul Eggert 2015-04-22 10:58:13 -07:00
parent df61b07822
commit 7128b0de89
3 changed files with 35 additions and 42 deletions

View file

@ -3024,7 +3024,7 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
ch = read_escape (readcharfun, 1);
/* CH is -1 if \ newline has just been seen. */
/* CH is -1 if \ newline or \ space has just been seen. */
if (ch == -1)
{
if (p == read_buffer)

View file

@ -37,6 +37,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "termhooks.h" /* For struct terminal. */
#include "font.h"
#include <c-ctype.h>
#include <float.h>
#include <ftoastr.h>
@ -1385,9 +1386,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
register ptrdiff_t i, i_byte;
struct gcpro gcpro1;
ptrdiff_t size_byte;
/* 1 means we must ensure that the next character we output
/* True means we must ensure that the next character we output
cannot be taken as part of a hex character escape. */
bool need_nonhex = 0;
bool need_nonhex = false;
bool multibyte = STRING_MULTIBYTE (obj);
GCPRO1 (obj);
@ -1411,60 +1412,46 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
QUIT;
if (c == '\n' && print_escape_newlines)
print_c_string ("\\n", printcharfun);
else if (c == '\f' && print_escape_newlines)
print_c_string ("\\f", printcharfun);
else if (multibyte
&& (CHAR_BYTE8_P (c)
|| (! ASCII_CHAR_P (c) && print_escape_multibyte)))
if (multibyte
? (CHAR_BYTE8_P (c) && (c = CHAR_TO_BYTE8 (c), true))
: (SINGLE_BYTE_CHAR_P (c) && ! ASCII_CHAR_P (c)
&& print_escape_nonascii))
{
/* When multibyte is disabled,
print multibyte string chars using hex escapes.
For a char code that could be in a unibyte string,
when found in a multibyte string, always use a hex escape
so it reads back as multibyte. */
char outbuf[50];
int len;
if (CHAR_BYTE8_P (c))
len = sprintf (outbuf, "\\%03o", CHAR_TO_BYTE8 (c));
else
{
len = sprintf (outbuf, "\\x%04x", c);
need_nonhex = 1;
}
strout (outbuf, len, len, printcharfun);
}
else if (! multibyte
&& SINGLE_BYTE_CHAR_P (c) && ! ASCII_CHAR_P (c)
&& print_escape_nonascii)
{
/* When printing in a multibyte buffer
or when explicitly requested,
/* When printing a raw 8-bit byte in a multibyte buffer, or
(when requested) a non-ASCII character in a unibyte buffer,
print single-byte non-ASCII string chars
using octal escapes. */
char outbuf[5];
int len = sprintf (outbuf, "\\%03o", c);
strout (outbuf, len, len, printcharfun);
need_nonhex = false;
}
else if (multibyte
&& ! ASCII_CHAR_P (c) && print_escape_multibyte)
{
/* When requested, print multibyte chars using hex escapes. */
char outbuf[sizeof "\\x" + INT_STRLEN_BOUND (c)];
int len = sprintf (outbuf, "\\x%04x", c);
strout (outbuf, len, len, printcharfun);
need_nonhex = true;
}
else
{
/* If we just had a hex escape, and this character
could be taken as part of it,
output `\ ' to prevent that. */
if (need_nonhex)
{
need_nonhex = 0;
if ((c >= 'a' && c <= 'f')
|| (c >= 'A' && c <= 'F')
|| (c >= '0' && c <= '9'))
print_c_string ("\\ ", printcharfun);
}
if (need_nonhex && c_isxdigit (c))
print_c_string ("\\ ", printcharfun);
if (c == '\"' || c == '\\')
if (c == '\n' && print_escape_newlines
? (c = 'n', true)
: c == '\f' && print_escape_newlines
? (c = 'f', true)
: c == '\"' || c == '\\')
printchar ('\\', printcharfun);
printchar (c, printcharfun);
need_nonhex = false;
}
}
printchar ('\"', printcharfun);

View file

@ -21,6 +21,12 @@
(require 'ert)
(ert-deftest print-hex-backslash ()
(should (string= (let ((print-escape-multibyte t)
(print-escape-newlines t))
(prin1-to-string "\u00A2\ff"))
"\"\\x00a2\\ff\"")))
(ert-deftest terpri ()
(should (string= (with-output-to-string
(princ 'abc)