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:
parent
df61b07822
commit
7128b0de89
3 changed files with 35 additions and 42 deletions
|
@ -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)
|
||||
|
|
69
src/print.c
69
src/print.c
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue