summaryrefslogtreecommitdiff
path: root/src/print.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/print.c')
-rw-r--r--src/print.c62
1 files changed, 37 insertions, 25 deletions
diff --git a/src/print.c b/src/print.c
index af1e85f6e7b..a8bbb9d37a1 100644
--- a/src/print.c
+++ b/src/print.c
@@ -313,6 +313,25 @@ printchar (unsigned int ch, Lisp_Object fun)
}
}
+/* Output an octal escape for C. If C is less than '\100' consult the
+ following character (if any) to see whether to use three octal
+ digits to avoid misinterpretation of the next character. The next
+ character after C will be taken from DATA, starting at byte
+ location I, if I is less than SIZE. Use PRINTCHARFUN to output
+ each character. */
+
+static void
+octalout (unsigned char c, unsigned char *data, ptrdiff_t i, ptrdiff_t size,
+ Lisp_Object printcharfun)
+{
+ int digits = (c > '\77' || (i < size && '0' <= data[i] && data[i] <= '7')
+ ? 3
+ : c > '\7' ? 2 : 1);
+ printchar ('\\', printcharfun);
+ do
+ printchar ('0' + ((c >> (3 * --digits)) & 7), printcharfun);
+ while (digits != 0);
+}
/* Output SIZE characters, SIZE_BYTE bytes from string PTR using
method PRINTCHARFUN. PRINTCHARFUN nil means output to
@@ -1367,32 +1386,33 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag,
case PVEC_BOOL_VECTOR:
{
EMACS_INT size = bool_vector_size (obj);
- ptrdiff_t size_in_chars = bool_vector_bytes (size);
- ptrdiff_t real_size_in_chars = size_in_chars;
+ ptrdiff_t size_in_bytes = bool_vector_bytes (size);
+ ptrdiff_t real_size_in_bytes = size_in_bytes;
+ unsigned char *data = bool_vector_uchar_data (obj);
int len = sprintf (buf, "#&%"pI"d\"", size);
strout (buf, len, len, printcharfun);
- /* Don't print more characters than the specified maximum.
+ /* Don't print more bytes than the specified maximum.
Negative values of print-length are invalid. Treat them
like a print-length of nil. */
if (NATNUMP (Vprint_length)
- && XFASTINT (Vprint_length) < size_in_chars)
- size_in_chars = XFASTINT (Vprint_length);
+ && XFASTINT (Vprint_length) < size_in_bytes)
+ size_in_bytes = XFASTINT (Vprint_length);
- for (ptrdiff_t i = 0; i < size_in_chars; i++)
+ for (ptrdiff_t i = 0; i < size_in_bytes; i++)
{
maybe_quit ();
- unsigned char c = bool_vector_uchar_data (obj)[i];
+ unsigned char c = data[i];
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 (c > '\177')
+ else if (c > '\177'
+ || (print_escape_control_characters && c_iscntrl (c)))
{
/* Use octal escapes to avoid encoding issues. */
- int len = sprintf (buf, "\\%o", c);
- strout (buf, len, len, printcharfun);
+ octalout (c, data, i + 1, size_in_bytes, printcharfun);
}
else
{
@@ -1402,7 +1422,7 @@ print_vectorlike (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag,
}
}
- if (size_in_chars < real_size_in_chars)
+ if (size_in_bytes < real_size_in_bytes)
print_c_string (" ...", printcharfun);
printchar ('\"', printcharfun);
}
@@ -1854,9 +1874,7 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
(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 + 0u);
- strout (outbuf, len, len, printcharfun);
+ octalout (c, SDATA (obj), i_byte, size_byte, printcharfun);
need_nonhex = false;
}
else if (multibyte
@@ -1870,7 +1888,6 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
}
else
{
- bool still_need_nonhex = false;
/* If we just had a hex escape, and this character
could be taken as part of it,
output `\ ' to prevent that. */
@@ -1884,22 +1901,16 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
? (c = 'n', true)
: c == '\f' && print_escape_newlines
? (c = 'f', true)
- : c == '\0' && print_escape_control_characters
- ? (c = '0', still_need_nonhex = true)
: c == '\"' || c == '\\')
{
printchar ('\\', printcharfun);
printchar (c, printcharfun);
}
else if (print_escape_control_characters && c_iscntrl (c))
- {
- char outbuf[1 + 3 + 1];
- int len = sprintf (outbuf, "\\%03o", c + 0u);
- strout (outbuf, len, len, printcharfun);
- }
+ octalout (c, SDATA (obj), i_byte, size_byte, printcharfun);
else
printchar (c, printcharfun);
- need_nonhex = still_need_nonhex;
+ need_nonhex = false;
}
}
printchar ('\"', printcharfun);
@@ -1971,7 +1982,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
|| c == ';' || c == '#' || c == '(' || c == ')'
|| c == ',' || c == '.' || c == '`'
|| c == '[' || c == ']' || c == '?' || c <= 040
- || confusing)
+ || confusing
+ || (i == 1 && confusable_symbol_character_p (c)))
{
printchar ('\\', printcharfun);
confusing = false;
@@ -2366,7 +2378,7 @@ This affects only `prin1'. */);
DEFVAR_BOOL ("print-quoted", print_quoted,
doc: /* Non-nil means print quoted forms with reader syntax.
I.e., (quote foo) prints as \\='foo, (function foo) as #\\='foo. */);
- print_quoted = 0;
+ print_quoted = true;
DEFVAR_LISP ("print-gensym", Vprint_gensym,
doc: /* Non-nil means print uninterned symbols so they will read as uninterned.