Handle #@00 in new reader in a compatible way (bug#63722)
This was a regression from Emacs 28. * src/lread.c (skip_lazy_string, read0): Make #@00 read as nil, which is a quirk from the old reader that we preserve for compatibility. * test/src/lread-tests.el (lread-skip-to-eof): Verify it. Reported by Richard Newton.
This commit is contained in:
parent
c0d7447e9d
commit
f535c0e49d
2 changed files with 27 additions and 6 deletions
17
src/lread.c
17
src/lread.c
|
@ -3400,8 +3400,9 @@ read_bool_vector (Lisp_Object readcharfun)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip (and optionally remember) a lazily-loaded string
|
/* Skip (and optionally remember) a lazily-loaded string
|
||||||
preceded by "#@". */
|
preceded by "#@". Return true if this was a normal skip,
|
||||||
static void
|
false if we read #@00 (which skips to EOF). */
|
||||||
|
static bool
|
||||||
skip_lazy_string (Lisp_Object readcharfun)
|
skip_lazy_string (Lisp_Object readcharfun)
|
||||||
{
|
{
|
||||||
ptrdiff_t nskip = 0;
|
ptrdiff_t nskip = 0;
|
||||||
|
@ -3427,9 +3428,9 @@ skip_lazy_string (Lisp_Object readcharfun)
|
||||||
digits++;
|
digits++;
|
||||||
if (digits == 2 && nskip == 0)
|
if (digits == 2 && nskip == 0)
|
||||||
{
|
{
|
||||||
/* #@00 means "skip to end" */
|
/* #@00 means "read nil and skip to end" */
|
||||||
skip_dyn_eof (readcharfun);
|
skip_dyn_eof (readcharfun);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3476,6 +3477,8 @@ skip_lazy_string (Lisp_Object readcharfun)
|
||||||
else
|
else
|
||||||
/* Skip that many bytes. */
|
/* Skip that many bytes. */
|
||||||
skip_dyn_bytes (readcharfun, nskip);
|
skip_dyn_bytes (readcharfun, nskip);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Given a lazy-loaded string designator VAL, return the actual string.
|
/* Given a lazy-loaded string designator VAL, return the actual string.
|
||||||
|
@ -3933,8 +3936,10 @@ read0 (Lisp_Object readcharfun, bool locate_syms)
|
||||||
/* #@NUMBER is used to skip NUMBER following bytes.
|
/* #@NUMBER is used to skip NUMBER following bytes.
|
||||||
That's used in .elc files to skip over doc strings
|
That's used in .elc files to skip over doc strings
|
||||||
and function definitions that can be loaded lazily. */
|
and function definitions that can be loaded lazily. */
|
||||||
skip_lazy_string (readcharfun);
|
if (skip_lazy_string (readcharfun))
|
||||||
goto read_obj;
|
goto read_obj;
|
||||||
|
obj = Qnil; /* #@00 skips to EOF and yields nil. */
|
||||||
|
break;
|
||||||
|
|
||||||
case '$':
|
case '$':
|
||||||
/* #$ -- reference to lazy-loaded string */
|
/* #$ -- reference to lazy-loaded string */
|
||||||
|
|
|
@ -339,4 +339,20 @@ literals (Bug#20852)."
|
||||||
(should (byte-code-function-p f))
|
(should (byte-code-function-p f))
|
||||||
(should (equal (aref f 4) "My little\ndoc string\nhere"))))))
|
(should (equal (aref f 4) "My little\ndoc string\nhere"))))))
|
||||||
|
|
||||||
|
(ert-deftest lread-skip-to-eof ()
|
||||||
|
;; Check the special #@00 syntax that, for compatibility, reads as
|
||||||
|
;; nil while absorbing the remainder of the input.
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert "#@00 and the rest\n"
|
||||||
|
"should be ignored) entirely\n")
|
||||||
|
(goto-char (point-min))
|
||||||
|
(should (equal (read (current-buffer)) nil))
|
||||||
|
(should (eobp))
|
||||||
|
;; Add an unbalanced bracket to the beginning and try again;
|
||||||
|
;; we should get an error.
|
||||||
|
(goto-char (point-min))
|
||||||
|
(insert "( ")
|
||||||
|
(goto-char (point-min))
|
||||||
|
(should-error (read (current-buffer)) :type 'end-of-file)))
|
||||||
|
|
||||||
;;; lread-tests.el ends here
|
;;; lread-tests.el ends here
|
||||||
|
|
Loading…
Add table
Reference in a new issue