[latex3-commits] [latex3/latex3] flag-N-type: Implement N-type flag variables (051b681da)

github at latex-project.org github at latex-project.org
Fri Jan 12 13:44:24 CET 2024


Repository : https://github.com/latex3/latex3
On branch  : flag-N-type
Link       : https://github.com/latex3/latex3/commit/051b681da7cd622c1bf160d0d561f32a242bc650

>---------------------------------------------------------------

commit 051b681da7cd622c1bf160d0d561f32a242bc650
Author: Bruno Le Floch <blflatex at gmail.com>
Date:   Fri Jan 12 13:43:28 2024 +0100

    Implement N-type flag variables
    
    This makes flag variables look much closer to other variable types.


>---------------------------------------------------------------

051b681da7cd622c1bf160d0d561f32a242bc650
 l3kernel/CHANGELOG.md            |   1 +
 l3kernel/doc/source3body.tex     |   2 +-
 l3kernel/l3flag.dtx              | 257 +++++++++++++++++++++++++++++++--------
 l3kernel/testfiles/m3flag002.lvt | 102 ++++++++++++++++
 l3kernel/testfiles/m3flag002.tlg | 178 +++++++++++++++++++++++++++
 5 files changed, 490 insertions(+), 50 deletions(-)

diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md
index deea9033a..bff54eb7a 100644
--- a/l3kernel/CHANGELOG.md
+++ b/l3kernel/CHANGELOG.md
@@ -9,6 +9,7 @@ this project uses date-based 'snapshot' version identifiers.
 
 ### Added
 - `\keys_set_exclude_groups:nnn(nN)` to replace `\keys_set_filter:nnn(nN)`
+- Flags with N-type names, like other variable types
 
 ### Changed
 - Set `l3doc` option `kernel` off as-standard (issue \#1403)
diff --git a/l3kernel/doc/source3body.tex b/l3kernel/doc/source3body.tex
index b81fd3259..5ccc14019 100644
--- a/l3kernel/doc/source3body.tex
+++ b/l3kernel/doc/source3body.tex
@@ -321,7 +321,7 @@ following variable types:
   \item[\texttt{box}] Box register.
   \item[\texttt{coffin}] A \enquote{box with handles} --- a higher-level
     data type for carrying out \texttt{box} alignment operations.
-  \item[\texttt{flag}] Integer that can be incremented expandably.
+  \item[\texttt{flag}] Non-negative integer that can be incremented expandably.
   \item[\texttt{fparray}] Fixed-size array of floating point values.
   \item[\texttt{intarray}] Fixed-size array of integers.
   \item[\texttt{ior}/\texttt{iow}] An input or output stream, for
diff --git a/l3kernel/l3flag.dtx b/l3kernel/l3flag.dtx
index e1d9808b8..5946e0596 100644
--- a/l3kernel/l3flag.dtx
+++ b/l3kernel/l3flag.dtx
@@ -54,16 +54,13 @@
 % cases, booleans or integers should be preferred to flags because they
 % are very significantly faster.
 %
-% A flag can hold any non-negative value, which we call its
+% A flag can hold any (small) non-negative value, which we call its
 % \meta{height}. In expansion-only contexts, a flag can only be
 % \enquote{raised}: this increases the \meta{height} by $1$. The \meta{height}
 % can also be queried expandably. However, decreasing it, or setting it
 % to zero requires non-expandable assignments.
 %
-% Flag variables are always local. They are referenced by a \meta{flag
-% name} such as \texttt{fp_overflow}.  The \meta{flag name} is used as
-% part of \cs{use:c} constructions hence is expanded at point of use.
-% It must expand to character tokens only, with no spaces.
+% Flag variables are always local.
 %
 % A typical use case of flags would be to keep track of whether an
 % exceptional condition has occurred during expandable processing, and
@@ -74,94 +71,107 @@
 % error message describing incorrect inputs that were encountered.
 %
 % Flags should not be used without carefully considering the fact that
-% raising a flag takes a time and memory proportional to its height.
-% Flags should not be used unless unavoidable.
+% raising a flag takes a time and memory proportional to its height and
+% that the memory cannot be reclaimed even if the flag is cleared.
+% Flags should not be used unless it is unavoidable.
+%
+% In earlier versions, flags were referenced by an \texttt{n}-type
+% \meta{flag name} such as \texttt{fp_overflow}, used as part of
+% \cs{use:c} constructions.  All of the commands described below have
+% \texttt{n}-type analogues that can still appear in old code, but the
+% \texttt{N}-type commands are to be preferred moving forward.
 %
 % \section{Setting up flags}
 %
-% \begin{function}{\flag_new:n}
+% \begin{function}[added = 2024-01-15]{\flag_new:N, \flag_new:c}
 %   \begin{syntax}
-%     \cs{flag_new:n} \Arg{flag name}
+%     \cs{flag_new:N} \meta{flag~var}
 %   \end{syntax}
-%   Creates a new flag with a name given by \meta{flag name}, or raises
-%   an error if the name is already taken. The \meta{flag name} may not
-%   contain spaces. The declaration is global, but flags are always
-%   local variables. The \meta{flag} initially has zero height.
+%   Creates a new \meta{flag~var}, or raises an error if the name is
+%   already taken. The declaration is global, but flags are always local
+%   variables. The \meta{flag~var} initially has zero height.
 % \end{function}
 %
-% \begin{function}{\flag_clear:n}
+% \begin{function}[added = 2024-01-15]{\flag_clear:N, \flag_clear:c}
 %   \begin{syntax}
-%     \cs{flag_clear:n} \Arg{flag name}
+%     \cs{flag_clear:N} \meta{flag~var}
 %   \end{syntax}
-%   The \meta{flag}'s height is set to zero. The assignment is local.
+%   Sets the height of the \meta{flag~var} to zero. The assignment is local.
 % \end{function}
 %
-% \begin{function}{\flag_clear_new:n}
+% \begin{function}[added = 2024-01-15]{\flag_clear_new:N, \flag_clear_new:c}
 %   \begin{syntax}
-%     \cs{flag_clear_new:n} \Arg{flag name}
+%     \cs{flag_clear_new:N} \meta{flag~var}
 %   \end{syntax}
-%   Ensures that the \meta{flag} exists globally by applying
-%   \cs{flag_new:n} if necessary, then applies \cs{flag_clear:n}, setting
+%   Ensures that the \meta{flag~var} exists globally by applying
+%   \cs{flag_new:N} if necessary, then applies \cs{flag_clear:N}, setting
 %   the height to zero locally.
 % \end{function}
 %
-% \begin{function}{\flag_show:n}
+% \begin{function}[added = 2024-01-15]{\flag_show:N, \flag_show:c}
 %   \begin{syntax}
-%     \cs{flag_show:n} \Arg{flag name}
+%     \cs{flag_show:N} \meta{flag~var}
 %   \end{syntax}
-%   Displays the \meta{flag}'s height in the terminal.
+%   Displays the height of the \meta{flag~var} in the terminal.
 % \end{function}
 %
-% \begin{function}{\flag_log:n}
+% \begin{function}[added = 2024-01-15]{\flag_log:N, \flag_log:c}
 %   \begin{syntax}
-%     \cs{flag_log:n} \Arg{flag name}
+%     \cs{flag_log:N} \meta{flag~var}
 %   \end{syntax}
-%   Writes the \meta{flag}'s height to the log file.
+%   Writes the height of the \meta{flag~var} in the log file.
 % \end{function}
 %
 % \section{Expandable flag commands}
 %
-% \begin{function}[EXP,pTF]{\flag_if_exist:n}
+% \begin{function}[EXP, pTF, added = 2024-01-15]{\flag_if_exist:N, \flag_if_exist:c}
 %   \begin{syntax}
-%     \cs{flag_if_exist_p:n} \Arg{flag name}
-%     \cs{flag_if_exist:nTF} \Arg{flag name} \Arg{true code} \Arg{false code}
+%     \cs{flag_if_exist_p:N} \meta{flag~var}
+%     \cs{flag_if_exist:NTF} \meta{flag~var} \Arg{true code} \Arg{false code}
 %   \end{syntax}
-%   This function returns \texttt{true} if the \meta{flag name}
-%   references a flag that has been defined previously, and
-%   \texttt{false} otherwise.
+%   This function returns \texttt{true} if the \meta{flag~var} is
+%   currently defined, and \texttt{false} otherwise. This does not check
+%   that the \meta{flag~var} really is a flag variable.
 % \end{function}
 %
-% \begin{function}[EXP,pTF]{\flag_if_raised:n}
+% \begin{function}[EXP, pTF, added = 2024-01-15]{\flag_if_raised:N, \flag_if_raised:c}
 %   \begin{syntax}
-%     \cs{flag_if_raised_p:n} \Arg{flag name}
-%     \cs{flag_if_raised:nTF} \Arg{flag name} \Arg{true code} \Arg{false code}
+%     \cs{flag_if_raised_p:N} \meta{flag~var}
+%     \cs{flag_if_raised:NTF} \meta{flag~var} \Arg{true code} \Arg{false code}
 %   \end{syntax}
-%   This function returns \texttt{true} if the \meta{flag} has non-zero
-%   height, and \texttt{false} if the \meta{flag} has zero height.
+%   This function returns \texttt{true} if the \meta{flag~var} has non-zero
+%   height, and \texttt{false} if the \meta{flag~var} has zero height.
 % \end{function}
 %
-% \begin{function}[EXP]{\flag_height:n}
+% \begin{function}[EXP, added = 2024-01-15]{\flag_height:N, \flag_height:c}
 %   \begin{syntax}
-%     \cs{flag_height:n} \Arg{flag name}
+%     \cs{flag_height:N} \meta{flag~var}
 %   \end{syntax}
-%   Expands to the height of the \meta{flag} as an integer denotation.
+%   Expands to the height of the \meta{flag~var} as an integer denotation.
 % \end{function}
 %
-% \begin{function}[EXP]{\flag_raise:n}
+% \begin{function}[EXP, added = 2024-01-15]{\flag_raise:N, \flag_raise:c}
 %   \begin{syntax}
-%     \cs{flag_raise:n} \Arg{flag name}
+%     \cs{flag_raise:N} \meta{flag~var}
 %   \end{syntax}
-%   The \meta{flag}'s height is increased by $1$ locally.
+%   The height of \meta{flag~var} is increased by $1$ locally.
 % \end{function}
 %
-% \begin{function}[EXP, added = 2023-04-25]{\flag_ensure_raised:n}
+% \begin{function}[EXP, added = 2024-01-15]{\flag_ensure_raised:N, \flag_ensure_raised:c}
 %   \begin{syntax}
-%     \cs{flag_ensure_raised:n} \Arg{flag name}
+%     \cs{flag_ensure_raised:N} \meta{flag~var}
 %   \end{syntax}
-%   Ensures the \meta{flag} is raised by making its height at least~$1$,
+%   Ensures the \meta{flag~var} is raised by making its height at least~$1$,
 %   locally.
 % \end{function}
 %
+% \begin{variable}[added = 2024-01-15]{\l_tmpa_flag, \l_tmpb_flag}
+%   Scratch flag for local assignment. These are never used by
+%   the kernel code, and so are safe for use with any \LaTeX3-defined
+%   function. However, they may be overwritten by other non-kernel
+%   code and so should only be used for short-term storage.
+% \end{variable}
+%
 % \end{documentation}
 %
 % \begin{implementation}
@@ -178,7 +188,158 @@
 %
 % \TestFiles{m3flag001}
 %
-% \subsection{Non-expandable flag commands}
+% \subsection{Protected flag commands}
+%
+% The height $h$ of a flag (which is initially zero) is stored by
+% setting control sequences of the form \cs[no-index]{\meta{flag
+% name}\meta{integer}} to \tn{relax} for $0\leq\meta{integer}<h$.  These
+% control sequences are produced by \cs{cs:w} \meta{flag~var}
+% \meta{integer} \cs{cs_end:}, namely the \meta{flag~var} is actually a
+% (protected) macro expanding to its own csname.
+%
+% \begin{macro}{\flag_new:N, \flag_new:c}
+%   Evaluate the csname of~|#1| for use in constructing the various
+%   indexed macros.
+%   \begin{macrocode}
+\cs_new_protected:Npn \flag_new:N #1
+  { \cs_new_protected:Npe #1 { \cs_to_str:N #1 } }
+\cs_generate_variant:Nn \flag_new:N { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_tmpa_flag, \l_tmpb_flag}
+%   Two flag variables for scratch use.
+%    \begin{macrocode}
+\flag_new:N \l_tmpa_flag
+\flag_new:N \l_tmpb_flag
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\flag_clear:N, \flag_clear:c}
+% \begin{macro}{\@@_clear:wN}
+%   Undefine control sequences, starting from the |0| flag, upwards,
+%   until reaching an undefined control sequence.  We don't use
+%   \cs{cs_undefine:c} because that would act globally.
+%    \begin{macrocode}
+\cs_new_protected:Npn \flag_clear:N #1
+  {
+    \@@_clear:wN 0 ; #1
+    \prg_break_point:
+  }
+\cs_generate_variant:Nn \flag_clear:N { c }
+\cs_new_protected:Npn \@@_clear:wN #1 ; #2
+  {
+    \if_cs_exist:w #2 #1 \cs_end: \else:
+      \prg_break:n
+    \fi:
+    \cs_set_eq:cN { #2 #1 } \tex_undefined:D
+    \exp_after:wN \@@_clear:wN
+    \int_value:w \int_eval:w \c_one_int + #1 ; #2
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\flag_clear_new:N, \flag_clear_new:c}
+%   As for other datatypes, clear the \meta{flag~var} or create a new one,
+%   as appropriate.
+%    \begin{macrocode}
+\cs_new_protected:Npn \flag_clear_new:N #1
+  { \flag_if_exist:NTF #1 { \flag_clear:N } { \flag_new:N } #1 }
+\cs_generate_variant:Nn \flag_clear_new:N { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\flag_show:N, \flag_show:c, \flag_log:N, \flag_log:c, \@@_show:NN}
+%   Show the height (terminal or log file) using appropriate \pkg{l3msg}
+%   auxiliaries.
+%    \begin{macrocode}
+\cs_new_protected:Npn \flag_show:N { \@@_show:NN \tl_show:n }
+\cs_generate_variant:Nn \flag_show:N { c }
+\cs_new_protected:Npn \flag_log:N { \@@_show:NN \tl_log:n }
+\cs_generate_variant:Nn \flag_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+  {
+    \__kernel_chk_defined:NT #2
+      { \exp_args:Ne #1 { \tl_to_str:n { #2 height } = \flag_height:N #2 } }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Expandable flag commands}
+%
+% \begin{macro}[EXP, pTF]{\flag_if_exist:N, \flag_if_exist:c}
+%   Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
+%    \begin{macrocode}
+\prg_new_eq_conditional:NNn \flag_if_exist:N \cs_if_exist:N
+  { TF , T , F , p }
+\prg_new_eq_conditional:NNn \flag_if_exist:c \cs_if_exist:c
+  { TF , T , F , p }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP, pTF]{\flag_if_raised:N, \flag_if_raised:c}
+%   Test if the flag has a non-zero height, by checking the |0| control sequence.
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \flag_if_raised:N #1 { p , T , F , TF }
+  {
+    \if_cs_exist:w #1 0 \cs_end:
+      \prg_return_true:
+    \else:
+      \prg_return_false:
+    \fi:
+  }
+\prg_generate_conditional_variant:Nnn \flag_if_raised:N
+  { c } { p , T , F , TF }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\flag_height:N, \flag_height:c}
+% \begin{macro}[EXP]{\@@_height_loop:wN, \@@_height_end:wN}
+%   Extract the value of the flag by going through all of the
+%   control sequences starting from |0|.
+%    \begin{macrocode}
+\cs_new:Npn \flag_height:N #1 { \@@_height_loop:wN 0; #1 }
+\cs_new:Npn \@@_height_loop:wN #1 ; #2
+  {
+    \if_cs_exist:w #2 #1 \cs_end: \else:
+      \exp_after:wN \@@_height_end:wN
+    \fi:
+    \exp_after:wN \@@_height_loop:wN
+    \int_value:w \int_eval:w \c_one_int + #1 ; #2
+  }
+\cs_new:Npn \@@_height_end:wN #1 + #2 ; #3 {#2}
+\cs_generate_variant:Nn \flag_height:N { c }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\flag_raise:N, \flag_raise:c}
+%   Change the appropriate control sequence to \tn{relax} by expanding a
+%   \cs{cs:w} \ldots{} \cs{cs_end:} construction, then pass it to
+%   \cs{use_none:n} to avoid leaving anything in the input stream.
+%    \begin{macrocode}
+\cs_new:Npn \flag_raise:N #1
+  { \exp_after:wN \use_none:n \cs:w #1 \flag_height:N #1 \cs_end: }
+\cs_generate_variant:Nn \flag_raise:N { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\flag_ensure_raised:N, \flag_ensure_raised:c}
+%   Pass the control sequence with name \meta{flag name}\texttt{0} to
+%   \cs{use_none:n}.  Constructing the control sequence ensures that it
+%   changes from being undefined (if it was so) to being \tn{relax}.
+%    \begin{macrocode}
+\cs_new:Npn \flag_ensure_raised:N #1
+  { \exp_after:wN \use_none:n \cs:w #1 0 \cs_end: }
+\cs_generate_variant:Nn \flag_ensure_raised:N { c }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Old \texttt{n}-type flag commands}
+%
+% Here we keep the old flag commands unchanged since our policy is to no
+% longer delete depecrated functions.
 %
 % The height $h$ of a flag (initially zero) is stored by setting control
 % sequences of the form \cs[no-index]{flag \meta{name} \meta{integer}}
@@ -252,8 +413,6 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{Expandable flag commands}
-%
 % \begin{macro}[EXP, pTF]{\flag_if_exist:n}
 %   A flag exist if the corresponding trap \cs[no-index]{flag \meta{flag
 %   name}:n} is defined.
diff --git a/l3kernel/testfiles/m3flag002.lvt b/l3kernel/testfiles/m3flag002.lvt
new file mode 100644
index 000000000..1e50966ad
--- /dev/null
+++ b/l3kernel/testfiles/m3flag002.lvt
@@ -0,0 +1,102 @@
+%
+% Copyright (C) The LaTeX Project
+%
+
+\documentclass{minimal}
+\input{regression-test}
+
+\ExplSyntaxOn
+\debug_on:n { check-declarations , deprecation , log-functions }
+\ExplSyntaxOff
+
+\begin{document}
+
+\START
+\AUTHOR{Bruno Le Floch}
+\ExplSyntaxOn
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\OMIT
+\def\foo{foo}
+\TIMO
+
+\TEST { flag_new }
+  {
+    {
+      \flag_if_exist:NT \l_A_flag { \ERROR }
+      \flag_new:N \l_A_flag
+      \TYPE { \cs_meaning:N \l_A_flag }
+    }
+    \flag_if_exist:NF \l_A_flag { \ERROR }
+    \TYPE { \cs_meaning:N \l_A_flag }
+    \flag_new:N \l_A_flag
+    \flag_new:N \l_B_flag
+  }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\OMIT
+\flag_new:N \l_C_flag
+\cs_new:Npn \test:
+  {
+    \flag_if_raised:NTF \l_C_flag { T } { F } ~
+    \flag_height:N \l_C_flag \c_space_tl
+    \cs_meaning:c { l_C_flag 0 } ~
+    \cs_meaning:c { l_C_flag 1 } ~
+    \cs_meaning:c { l_C_flag 2 } ~ \NEWLINE
+  }
+\TIMO
+
+\TEST { raise,~test,~height }
+  {
+    { \TYPE { \prg_replicate:nn {3} { \test: \flag_raise:N \l_C_flag } } }
+    \TYPE { \test: }
+  }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\TEST { zero }
+  {
+    \TYPE { \test: \flag_raise:N \l_C_flag \test: }
+    {
+      \prg_replicate:nn {10} { \flag_raise:N \l_C_flag }
+      \flag_clear:N \l_C_flag
+      \TYPE { \test: \prg_replicate:nn {10} { \flag_raise:N \l_C_flag } \test: }
+    }
+    \TYPE { \test: }
+  }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\TEST { show,~log }
+  {
+    \flag_raise:N \l_C_flag
+    \flag_ensure_raised:N \l_C_flag
+    \flag_show:N \l_C_flag
+    \flag_clear:N \l_C_flag
+    \flag_ensure_raised:N \l_C_flag
+    \flag_raise:N \l_C_flag
+    \flag_raise:N \l_C_flag
+    \flag_log:N \l_C_flag
+    \flag_log:N \l_other_flag
+  }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\TEST { undefined }
+  {
+    \flag_clear:N \l_other_flag
+    \flag_raise:N \l_other_flag
+    \TYPE { | \flag_raise:N \l_other_flag | }
+    \TYPE { | \flag_ensure_raised:N \l_other_flag | }
+    \TYPE { | \flag_height:N \l_other_flag | }
+    \TYPE { | \flag_if_raised:NTF \l_other_flag {T} {F} | }
+    \TYPE { | \flag_if_raised:NT \l_other_flag {T} | }
+    \TYPE { | \flag_if_raised:NF \l_other_flag {F} | }
+    \TYPE { | \bool_if:nTF { \flag_if_raised_p:N \l_other_flag } {T} {F} | }
+  }
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\TEST { tmpa, tmpb }
+  {
+    \flag_show:N \l_tmpa_flag
+    \flag_show:N \l_tmpb_flag
+  }
+
+\END
diff --git a/l3kernel/testfiles/m3flag002.tlg b/l3kernel/testfiles/m3flag002.tlg
new file mode 100644
index 000000000..7b61eeb42
--- /dev/null
+++ b/l3kernel/testfiles/m3flag002.tlg
@@ -0,0 +1,178 @@
+This is a generated file for the LaTeX (2e + expl3) validation system.
+Don't change this file in any respect.
+Author: Bruno Le Floch
+============================================================
+TEST 1: flag_new
+============================================================
+Defining \l_A_flag on line ...
+\protected\long macro:->l_A_flag
+\protected\long macro:->l_A_flag
+! LaTeX Error: Control sequence \l_A_flag already defined.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+This is a coding error.
+LaTeX has been asked to create a new control sequence '\l_A_flag' but this
+name has already been used elsewhere.
+The current meaning is:
+  \protected\long macro:->l_A_flag
+Defining \l_A_flag on line ...
+Defining \l_B_flag on line ...
+============================================================
+============================================================
+TEST 2: raise, test, height
+============================================================
+F 0 undefined undefined undefined 
+T 1 \relax undefined undefined 
+T 2 \relax \relax undefined 
+F 0 undefined undefined undefined 
+============================================================
+============================================================
+TEST 3: zero
+============================================================
+F 0 undefined undefined undefined 
+T 1 \relax undefined undefined 
+F 0 undefined undefined undefined 
+T 10 \relax \relax \relax 
+F 0 undefined undefined undefined 
+============================================================
+============================================================
+TEST 4: show, log
+============================================================
+> \l_C_flag height=1.
+<recently read> }
+l. ...  }
+> \l_C_flag height=3.
+! LaTeX Error: Variable \l_other_flag undefined.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+This is a coding error.
+LaTeX has been asked to show a variable \l_other_flag, but this has not been
+defined yet.
+============================================================
+============================================================
+TEST 5: undefined
+============================================================
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+||
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+||
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+|1|
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+|T|
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+|T|
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+||
+! Undefined control sequence.
+<argument> \l_other_flag 
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+|T|
+============================================================
+============================================================
+TEST 6: tmpa,tmpb
+============================================================
+> \l_tmpa_flag height=0.
+<recently read> }
+l. ...  }
+> \l_tmpb_flag height=0.
+<recently read> }
+l. ...  }
+============================================================





More information about the latex3-commits mailing list.