Skip to content

Commit 0b4b380

Browse files
committed
Make warning about unescaped character literals more helpful.
See Bug#31676. * lisp/emacs-lisp/byte-run.el (byte-run--unescaped-character-literals-warning): New defun. * src/lread.c (load_warn_unescaped_character_literals): Use new defun. (syms_of_lread): Define symbol for new defun. * lisp/emacs-lisp/bytecomp.el (byte-compile-from-buffer): Use new defun. * test/src/lread-tests.el (lread-tests--unescaped-char-literals): test/lisp/emacs-lisp/bytecomp-tests.el (bytecomp-tests--unescaped-char-literals): Adapt unit tests.
1 parent 8aadf6e commit 0b4b380

File tree

5 files changed

+33
-25
lines changed

5 files changed

+33
-25
lines changed

lisp/emacs-lisp/byte-run.el

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,21 @@ is enabled."
494494
;; The implementation for the interpreter is basically trivial.
495495
(car (last body)))
496496

497+
498+
(defun byte-run--unescaped-character-literals-warning ()
499+
"Return a warning about unescaped character literals.
500+
If there were any unescaped character literals in the last form
501+
read, return an appropriate warning message as a string.
502+
Otherwise, return nil. For internal use only."
503+
;; This is called from lread.c and therefore needs to be preloaded.
504+
(if lread--unescaped-character-literals
505+
(let ((sorted (sort lread--unescaped-character-literals #'<)))
506+
(format-message "unescaped character literals %s detected, %s expected!"
507+
(mapconcat (lambda (char) (format "`?%c'" char))
508+
sorted ", ")
509+
(mapconcat (lambda (char) (format "`?\\%c'" char))
510+
sorted ", ")))))
511+
497512

498513
;; I nuked this because it's not a good idea for users to think of using it.
499514
;; These options are a matter of installation preference, and have nothing to

lisp/emacs-lisp/bytecomp.el

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2082,14 +2082,9 @@ With argument ARG, insert value in current buffer after the form."
20822082
(not (eobp)))
20832083
(setq byte-compile-read-position (point)
20842084
byte-compile-last-position byte-compile-read-position)
2085-
(let* ((lread--unescaped-character-literals nil)
2086-
(form (read inbuffer)))
2087-
(when lread--unescaped-character-literals
2088-
(byte-compile-warn
2089-
"unescaped character literals %s detected!"
2090-
(mapconcat (lambda (char) (format "`?%c'" char))
2091-
(sort lread--unescaped-character-literals #'<)
2092-
", ")))
2085+
(let ((form (read inbuffer))
2086+
(warning (byte-run--unescaped-character-literals-warning)))
2087+
(when warning (byte-compile-warn "%s" warning))
20932088
(byte-compile-toplevel-file-form form)))
20942089
;; Compile pending forms at end of file.
20952090
(byte-compile-flush-pending)

src/lread.c

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,18 +1034,12 @@ load_error_old_style_backquotes (void)
10341034
static void
10351035
load_warn_unescaped_character_literals (Lisp_Object file)
10361036
{
1037-
if (NILP (Vlread_unescaped_character_literals)) return;
1038-
CHECK_CONS (Vlread_unescaped_character_literals);
1039-
Lisp_Object format =
1040-
build_string ("Loading `%s': unescaped character literals %s detected!");
1041-
Lisp_Object separator = build_string (", ");
1042-
Lisp_Object inner_format = build_string ("`?%c'");
1043-
CALLN (Fmessage,
1044-
format, file,
1045-
Fmapconcat (list3 (Qlambda, list1 (Qchar),
1046-
list3 (Qformat, inner_format, Qchar)),
1047-
Fsort (Vlread_unescaped_character_literals, Qlss),
1048-
separator));
1037+
Lisp_Object warning
1038+
= call0 (Qbyte_run_unescaped_character_literals_warning);
1039+
if (NILP (warning))
1040+
return;
1041+
Lisp_Object format = build_string ("Loading `%s': %s");
1042+
CALLN (Fmessage, format, file, warning);
10491043
}
10501044

10511045
DEFUN ("get-load-suffixes", Fget_load_suffixes, Sget_load_suffixes, 0, 0, 0,
@@ -5014,9 +5008,9 @@ For internal use only. */);
50145008
DEFSYM (Qlread_unescaped_character_literals,
50155009
"lread--unescaped-character-literals");
50165010

5017-
DEFSYM (Qlss, "<");
5018-
DEFSYM (Qchar, "char");
5019-
DEFSYM (Qformat, "format");
5011+
/* Defined in lisp/emacs-lisp/byte-run.el. */
5012+
DEFSYM (Qbyte_run_unescaped_character_literals_warning,
5013+
"byte-run--unescaped-character-literals-warning");
50205014

50215015
DEFVAR_BOOL ("load-prefer-newer", load_prefer_newer,
50225016
doc: /* Non-nil means `load' prefers the newest version of a file.

test/lisp/emacs-lisp/bytecomp-tests.el

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,9 @@ literals (Bug#20852)."
540540
(should (equal (cdr err)
541541
(list (concat "unescaped character literals "
542542
"`?\"', `?(', `?)', `?;', `?[', `?]' "
543-
"detected!"))))))))
543+
"detected, "
544+
"`?\\\"', `?\\(', `?\\)', `?\\;', `?\\[', "
545+
"`?\\]' expected!"))))))))
544546

545547
(ert-deftest bytecomp-tests--old-style-backquotes ()
546548
"Check that byte compiling warns about old-style backquotes."

test/src/lread-tests.el

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ literals (Bug#20852)."
140140
(should (equal (lread-tests--last-message)
141141
(concat (format-message "Loading `%s': " file-name)
142142
"unescaped character literals "
143-
"`?\"', `?(', `?)', `?;', `?[', `?]' detected!")))))
143+
"`?\"', `?(', `?)', `?;', `?[', `?]' detected, "
144+
"`?\\\"', `?\\(', `?\\)', `?\\;', `?\\[', `?\\]' "
145+
"expected!")))))
144146

145147
(ert-deftest lread-tests--funny-quote-symbols ()
146148
"Check that 'smart quotes' or similar trigger errors in symbol names."

0 commit comments

Comments
 (0)