From 637dde4aba921435f78d0de769ad74c4f3230aa6 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 14 Mar 2022 10:27:12 +0100 Subject: [PATCH] Don't always escape "." and "?" in `prin1' * src/print.c (print_object): Only escape "." and "?" when appearing as the first character in a symbol (bug#23130). --- etc/NEWS | 16 ++++++++++++++++ src/print.c | 19 ++++++++++++------- test/src/print-tests.el | 8 ++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index b1aac3d6d04..d6b5da3902e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1076,6 +1076,22 @@ Emacs buffers, like indentation and the like. The new ert function * Incompatible Lisp Changes in Emacs 29.1 +--- +** 'prin1' doesn't always escape "." and "?" in symbols any more. +Previously, symbols like 'foo.bar' would be printed by 'prin1' as +"foo\.bar". This now prints as "foo.bar" instead. The Emacs Lisp +reader interprets these strings as referring to the same symbol, so +this is virtually always backwards-compatible, but there may +theoretically be code out there that expects a specific printed +representation. + +The same is the case with the "?" character: The 'foo?' symbol is now +printed as "foo?" instead of "foo\?". + +If the "." and "?" characters are the first character in the symbol, +they will still be escaped, so the '.foo' symbol is still printed as +"\.foo" and the '?bar' symbol is still printed as "\?bar". + +++ ** Remapping 'mode-line' no longer works as expected. 'mode-line' is now the parent face of the new 'mode-line-active' face, diff --git a/src/print.c b/src/print.c index 8cce8a1ad83..704fc278f2d 100644 --- a/src/print.c +++ b/src/print.c @@ -2171,14 +2171,19 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) Lisp_Object name = SYMBOL_NAME (obj); ptrdiff_t size_byte = SBYTES (name); - /* Set CONFUSING if NAME looks like a number, calling - string_to_number for non-obvious cases. */ char *p = SSDATA (name); bool signedp = *p == '-' || *p == '+'; ptrdiff_t len; - bool confusing = ((c_isdigit (p[signedp]) || p[signedp] == '.') - && !NILP (string_to_number (p, 10, &len)) - && len == size_byte); + bool confusing = + /* Set CONFUSING if NAME looks like a number, calling + string_to_number for non-obvious cases. */ + ((c_isdigit (p[signedp]) || p[signedp] == '.') + && !NILP (string_to_number (p, 10, &len)) + && len == size_byte) + /* We don't escape "." or "?" (unless they're the first + character in the symbol name). */ + || *p == '?' + || *p == '.'; if (! NILP (Vprint_gensym) && !SYMBOL_INTERNED_IN_INITIAL_OBARRAY_P (obj)) @@ -2201,8 +2206,8 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag) { if (c == '\"' || c == '\\' || c == '\'' || c == ';' || c == '#' || c == '(' || c == ')' - || c == ',' || c == '.' || c == '`' - || c == '[' || c == ']' || c == '?' || c <= 040 + || c == ',' || c == '`' + || c == '[' || c == ']' || c <= 040 || c == NO_BREAK_SPACE || confusing) { diff --git a/test/src/print-tests.el b/test/src/print-tests.el index 1ef0caf1a46..0bae1959d1b 100644 --- a/test/src/print-tests.el +++ b/test/src/print-tests.el @@ -417,5 +417,13 @@ otherwise, use a different charset." t))) (should (equal (prin1-to-string (make-marker)) "")))) +(ert-deftest test-dots () + (should (equal (prin1-to-string 'foo.bar) "foo.bar")) + (should (equal (prin1-to-string '.foo) "\\.foo")) + (should (equal (prin1-to-string '.foo.) "\\.foo.")) + (should (equal (prin1-to-string 'bar?bar) "bar?bar")) + (should (equal (prin1-to-string '\?bar) "\\?bar")) + (should (equal (prin1-to-string '\?bar?) "\\?bar?"))) + (provide 'print-tests) ;;; print-tests.el ends here -- 2.39.5