[latex3-commits] [git/LaTeX3-latex3-latex3] master: Avoid reuse of LuaTeX catcodetable, document the code more precisely (6a15080a8)
Joseph Wright
joseph.wright at morningstar2.co.uk
Thu Jul 16 12:13:16 CEST 2020
Repository : https://github.com/latex3/latex3
On branch : master
Link : https://github.com/latex3/latex3/commit/6a15080a81cb6338d77b1cfcfe5b1b977d95ca9b
>---------------------------------------------------------------
commit 6a15080a81cb6338d77b1cfcfe5b1b977d95ca9b
Author: Bruno Le Floch <bruno at le-floch.fr>
Date: Thu Jul 2 16:27:59 2020 +0200
Avoid reuse of LuaTeX catcodetable, document the code more precisely
>---------------------------------------------------------------
6a15080a81cb6338d77b1cfcfe5b1b977d95ca9b
l3kernel/l3cctab.dtx | 79 ++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 68 insertions(+), 11 deletions(-)
diff --git a/l3kernel/l3cctab.dtx b/l3kernel/l3cctab.dtx
index dbecf9fb7..558ec9929 100644
--- a/l3kernel/l3cctab.dtx
+++ b/l3kernel/l3cctab.dtx
@@ -361,17 +361,69 @@
%
% \subsection{Using category code tables}
%
-% \begin{macro}{\cctab_select:N, \cctab_select:c}
% \begin{variable}{\g_@@_internal_cctab}
+% \begin{macro}[EXP]{\@@_internal_cctab_name:}
+% In \LuaTeX{}, we must ensure that the saved tables are read-only.
+% This is done by applying the saved table, then switching immediately
+% to a scratch table. Any later catcode assignment will affect that
+% scratch table rather than the saved one. If we simply switched to
+% the saved tables, then \cs{char_set_catcode_other:N} in the example
+% below would change \cs{c_document_cctab} and a later use of that
+% table would give the wrong category code to |_|.
+% \begin{verbatim}
+% \use:n
+% {
+% \cctab_begin:N \c_document_cctab
+% \char_set_catcode_other:N \_
+% \cctab_end:
+% \cctab_begin:N \c_document_cctab
+% \int_compare:nTF { \char_value_catcode:n { `_ } = 8 }
+% { \TRUE } { \ERROR }
+% \cctab_end:
+% }
+% \end{verbatim}
+% We must also make sure that a scratch table is never reused in a
+% nested group: in the following example, the scratch table used by
+% the first \cs{cctab_begin:N} would be changed globally by the second
+% one issuing \tn{savecatcodetable}, and after \cs{group_end:} the
+% wrong category codes (those of \cs{c_str_cctab}) would be imposed.
+% Note that the inner \cs{cctab_end:} restores the correct catcodes
+% only locally, so the problem really comes up because of the
+% different grouping level. The simplest is to use a scratch table
+% labeled by the \tn{currentgrouplevel}. We initialize one of them as
+% an example.
+% \begin{verbatim}
+% \use:n
+% {
+% \cctab_begin:N \c_document_cctab
+% \group_begin:
+% \cctab_begin:N \c_str_cctab
+% \cctab_end:
+% \group_end:
+% \cctab_end:
+% }
+% \end{verbatim}
+% \begin{macrocode}
+\sys_if_engine_luatex:T
+ {
+ \@@_new:N \g_@@_internal_cctab
+ \cs_new:Npn \@@_internal_cctab_name:
+ {
+ g_@@_internal
+ \tex_romannumeral:D \tex_currentgrouplevel:D
+ _cctab
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{variable}
+%
+% \begin{macro}{\cctab_select:N, \cctab_select:c}
% \begin{macro}{\@@_select:N}
% The public function simply checks the \meta{cctab~var} exists before
% using the engine-dependent \cs{@@_select:N}. Skipping these checks
% would result in low-level engine-dependent errors. First, the
-% \LuaTeX{} case. The aim here is to ensure that the saved tables are
-% read-only. This is done by applying the saved table, then switching
-% immediately to a scratch table \cs{g_@@_internal_cctab}. Any later
-% catcode assignment will affect that scratch table rather than the
-% saved one. In other engines, selecting a catcode table is a matter
+% \LuaTeX{} case. In other engines, selecting a catcode table is a matter
% of doing $256$ catcode assignments and setting the \tn{endlinechar}.
% \begin{macrocode}
\cs_new_protected:Npn \cctab_select:N #1
@@ -379,15 +431,16 @@
\cs_generate_variant:Nn \cctab_select:N { c }
\sys_if_engine_luatex:TF
{
- \@@_new:N \g_@@_internal_cctab
\cs_new_protected:Npn \@@_select:N #1
{
\tex_catcodetable:D #1
- \tex_savecatcodetable:D \g_@@_internal_cctab
- \tex_catcodetable:D \g_@@_internal_cctab
\prop_get:NVNTF \g_@@_endlinechar_prop #1 \l_@@_internal_tl
{ \int_set:Nn \tex_endlinechar:D { \l_@@_internal_tl } }
{ \int_set:Nn \tex_endlinechar:D { 13 } }
+ \cs_if_exist:cF { \@@_internal_cctab_name: }
+ { \exp_args:Nc \@@_new:N { \@@_internal_cctab_name: } }
+ \exp_args:Nc \tex_savecatcodetable:D { \@@_internal_cctab_name: }
+ \exp_args:Nc \tex_catcodetable:D { \@@_internal_cctab_name: }
}
}
{
@@ -404,7 +457,6 @@
}
% \end{macrocode}
% \end{macro}
-% \end{variable}
% \end{macro}
%
% \begin{variable}{\g_@@_next_cctab}
@@ -414,7 +466,12 @@
% a table number (in \LuaTeX{}) or name (in other engines) into
% \cs{l_@@_internal_tl}. In \LuaTeX{} this simply calls \cs{@@_new:N}
% and uses the resulting catcodetable number; in other engines we need
-% to give a name to the intarray variable and use that.
+% to give a name to the intarray variable and use that. In \LuaTeX{},
+% to restore catcodes at \cs{cctab_end:} we cannot just set
+% \tn{catcodetable} to its value before \cs{cctab_begin:N}, because
+% that table may have been altered by other code in the mean time. So
+% we must make sure to save the catcodes in a table we control and
+% restore them at \cs{cctab_end:}.
% \begin{macrocode}
\sys_if_engine_luatex:TF
{
More information about the latex3-commits
mailing list.