Fix Fchar_syntax for non-ASCII in unibyte buffers

Fchar_syntax did not convert unibyte characters to multibyte when the
current buffer was unibyte, in contrast to `char-syntax` in
byte-compiled code (bug#53260).

* src/bytecode.c (exec_byte_code): Call out to Fchar_syntax;
the dynamic frequency is too low to justify inlining here, and it
did lead to implementations diverging.
* src/syntax.c (Fchar_syntax): Convert non-ASCII unibyte values to
multibyte.
* test/src/syntax-tests.el (syntax-char-syntax): New test.
This commit is contained in:
Mattias Engdegård 2022-01-16 11:58:00 +01:00
parent b1488a6582
commit b929bdaeb6
3 changed files with 19 additions and 9 deletions

View file

@ -1167,13 +1167,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
NEXT;
CASE (Bchar_syntax):
{
CHECK_CHARACTER (TOP);
int c = XFIXNAT (TOP);
if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
c = make_char_multibyte (c);
XSETFASTINT (TOP, syntax_code_spec[SYNTAX (c)]);
}
TOP = Fchar_syntax (TOP);
NEXT;
CASE (Bbuffer_substring):

View file

@ -1101,10 +1101,11 @@ this is probably the wrong function to use, because it can't take
`syntax-after' instead. */)
(Lisp_Object character)
{
int char_int;
CHECK_CHARACTER (character);
char_int = XFIXNUM (character);
int char_int = XFIXNAT (character);
SETUP_BUFFER_SYNTAX_TABLE ();
if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
char_int = make_char_multibyte (char_int);
return make_fixnum (syntax_code_spec[SYNTAX (char_int)]);
}

View file

@ -506,4 +506,19 @@ the `parse-partial-sexp's are expected to stop. See
(should (parse-partial-sexp 1 1))
(should-error (parse-partial-sexp 2 1))))
(ert-deftest syntax-char-syntax ()
;; Verify that char-syntax behaves identically in interpreted and
;; byte-compiled code (bug#53260).
(let ((cs (byte-compile (lambda (x) (char-syntax x)))))
;; Use a unibyte buffer with a syntax table using symbol syntax
;; for raw byte 128.
(with-temp-buffer
(set-buffer-multibyte nil)
(let ((st (make-syntax-table)))
(modify-syntax-entry (unibyte-char-to-multibyte 128) "_" st)
(set-syntax-table st)
(should (equal (eval '(char-syntax 128) t) ?_))
(should (equal (funcall cs 128) ?_))))
(list (char-syntax 128) (funcall cs 128))))
;;; syntax-tests.el ends here