summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3int.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3int.dtx208
1 files changed, 139 insertions, 69 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
index db696612204..f0e0cca5938 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx
@@ -7,7 +7,7 @@
% license or (at your option) any later version. The latest version
% of this license is in the file
%
-% http://www.latex-project.org/lppl.txt
+% https://www.latex-project.org/lppl.txt
%
% This file is part of the "l3kernel bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
@@ -21,7 +21,7 @@
% for those people who are interested.
%
%<*driver>
-\documentclass[full]{l3doc}
+\documentclass[full,kernel]{l3doc}
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
@@ -41,7 +41,7 @@
% }^^A
% }
%
-% \date{Released 2017/11/14}
+% \date{Released 2017/12/05}
%
% \maketitle
%
@@ -900,31 +900,46 @@
%
% \section{Internal functions}
%
-% \begin{function}[EXP]{\__int_to_roman:w}
+% \begin{function}[EXP]{\__int_value:w}
% \begin{syntax}
-% \cs{__int_to_roman:w} \meta{integer} \meta{space} \textit{or} \meta{non-expandable token}
+% \cs{__int_value:w} \meta{integer}
+% \cs{__int_value:w} \meta{integer denotation} \meta{optional space}
% \end{syntax}
-% Converts \meta{integer} to it lower case Roman representation. Expansion
-% ends when a space or non-expandable token is found.
-% Note that this function produces a string of letters with category code
-% $12$ and that protected functions \emph{are} expanded by this
-% process. Negative \meta{integer} values result in no output, although
-% the function does not terminate expansion until a suitable endpoint
-% is found in the same way as for positive numbers.
+% Expands the following tokens until an \meta{integer} is formed, and
+% leaves a normalized form (no leading sign except for negative
+% numbers, no leading digit~|0| except for zero) in the input stream
+% as category code $12$ (other) characters. The \meta{integer} can
+% consist of any number of signs (with intervening spaces) followed
+% by
+% \begin{itemize}
+% \item an integer variable (in fact, any \TeX{} register except
+% \tn{toks}) or
+% \item \cs{__int_eval:w} \meta{intexpr} \cs{__int_eval_end:} (or
+% another \eTeX{} expression) or
+% \item explicit digits (or by |'|\meta{octal digits} or |"|\meta{hexadecimal digits} or |`|\meta{character}
+% \end{itemize}
+% In this last case expansion stops once a non-digit is found; if that is a space it is removed as in \texttt{f}-expansion.
+% Note that protected functions \emph{are} expanded by this process
% \begin{texnote}
-% This is the \TeX{} primitive \tn{romannumeral} renamed.
+% This is the \TeX{} primitive \tn{number}.
% \end{texnote}
% \end{function}
%
-% \begin{function}[EXP]{\__int_value:w}
+% \begin{function}[EXP]{\__int_to_roman:w}
% \begin{syntax}
-% \cs{__int_value:w} \meta{integer}
-% \cs{__int_value:w} \meta{tokens} \meta{optional space}
+% \cs{__int_to_roman:w} \meta{integer}
+% \cs{__int_to_roman:w} \meta{integer denotation} \meta{optional space}
% \end{syntax}
-% Expands \meta{tokens} until an \meta{integer} is formed. One space may be
-% gobbled in the process.
+% Converts an \meta{integer} to lower case Roman representation. The
+% \meta{integer} is found as in \cs{__int_value:w} by expanding what
+% follows exhaustively. One (optional) space is lost if the
+% \meta{integer} is given by explicit digits. Note that this function
+% produces a string of letters with category code~$12$. Negative
+% \meta{integer} values result in no output, although the function
+% does not terminate expansion until a suitable endpoint is found in
+% the same way as for positive numbers.
% \begin{texnote}
-% This is the \TeX{} primitive \tn{number}.
+% This is the \TeX{} primitive \tn{romannumeral} renamed.
% \end{texnote}
% \end{function}
%
@@ -943,6 +958,16 @@
% \end{texnote}
% \end{function}
%
+% \begin{function}[EXP]{\__int_eval:n}
+% \begin{syntax}
+% \cs{__int_eval:n} \Arg{intexpr}
+% \end{syntax}
+% By default this expands to \cs{__int_eval:w} \meta{intexpr}
+% \cs{__int_eval_end:} but when debugging is enabled this expands to a
+% more complicated construction that evaluates \meta{intexpr} with
+% parentheses and within a brace group to detect early termination.
+% \end{function}
+%
% \begin{function}{\__prg_compare_error:, \__prg_compare_error:Nw}
% \begin{syntax}
% \cs{__prg_compare_error:}
@@ -1017,12 +1042,23 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\@@_eval:n}
+% Only differ from \cs{int_eval:n} by the absence of \cs{@@_value:w},
+% so as to produce an internal integer rather than expanding into
+% characters. This is for use in other modules.
+% \begin{macrocode}
+\__debug_patch_args:nNNpn
+ { { \__debug_chk_expr:nNnN {#1} \@@_eval:w { } \@@_eval:n } }
+\cs_new:Npn \@@_eval:n #1 { \@@_eval:w #1 \@@_eval_end: }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}[EXP]{\int_abs:n}
-% \begin{macro}[aux, EXP]{\@@_abs:N}
+% \begin{macro}[EXP]{\@@_abs:N}
% \UnitTested
% \begin{macro}[EXP]{\int_max:nn}
% \begin{macro}[EXP]{\int_min:nn}
-% \begin{macro}[aux, EXP]{\@@_maxmin:wwN}
+% \begin{macro}[EXP]{\@@_maxmin:wwN}
% \UnitTested
% \UnitTested
% Functions for $\min$, $\max$, and absolute value with only one
@@ -1086,8 +1122,8 @@
% \UnitTested
% \begin{macro}[EXP]{\int_mod:nn}
% \UnitTested
-% \begin{macro}[aux, EXP]{\@@_div_truncate:NwNw}
-% \begin{macro}[aux, EXP]{\@@_mod:ww}
+% \begin{macro}[EXP]{\@@_div_truncate:NwNw}
+% \begin{macro}[EXP]{\@@_mod:ww}
% As \cs{@@_eval:w} rounds the result of a division we also provide a
% version that truncates the result. We use an auxiliary to make sure
% numerator and denominator are only evaluated once: this comes in
@@ -1178,35 +1214,39 @@
% \end{macro}
%
% \begin{macro}{\int_const:Nn, \int_const:cn}
-% \begin{macro}[aux]{\@@_constdef:Nw}
+% \begin{macro}{\@@_constdef:Nw}
% \begin{variable}{\c__max_constdef_int}
% \UnitTested
% As stated, most constants can be defined as \tn{chardef} or
% \tn{mathchardef} but that's engine dependent. As a result, there is some
% set up code to determine what can be done. No full engine testing just yet
% so everything is a little awkward.
+% We cannot use \cs{int_gset:Nn} because (when |check-declarations| is
+% enabled) this runs some checks that constants would fail.
% \begin{macrocode}
-\__debug_patch_args:nNNpn
+\__debug_patch_args:nnnNNpn
+ { \__debug_chk_var_scope:NN c #1 }
+ { }
{ {#1} { \__debug_chk_expr:nNnN {#2} \@@_eval:w { } \int_const:Nn } }
\cs_new_protected:Npn \int_const:Nn #1#2
{
\int_compare:nNnTF {#2} < \c_zero
{
\int_new:N #1
- \int_gset:Nn #1 {#2}
+ \tex_global:D
}
{
\int_compare:nNnTF {#2} > \c__max_constdef_int
{
\int_new:N #1
- \int_gset:Nn #1 {#2}
+ \tex_global:D
}
{
\__chk_if_free_cs:N #1
- \tex_global:D \@@_constdef:Nw #1 =
- \@@_eval:w #2 \@@_eval_end:
+ \tex_global:D \@@_constdef:Nw
}
}
+ #1 = \@@_eval:w #2 \@@_eval_end:
}
\cs_generate_variant:Nn \int_const:Nn { c }
\if_int_odd:w 0
@@ -1233,7 +1273,9 @@
% \UnitTested
% Functions that reset an \meta{integer} register to zero.
% \begin{macrocode}
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
\cs_new_protected:Npn \int_zero:N #1 { #1 = \c_zero }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
\cs_new_protected:Npn \int_gzero:N #1 { \tex_global:D #1 = \c_zero }
\cs_generate_variant:Nn \int_zero:N { c }
\cs_generate_variant:Nn \int_gzero:N { c }
@@ -1260,11 +1302,14 @@
% {\int_gset_eq:NN, \int_gset_eq:cN, \int_gset_eq:Nc, \int_gset_eq:cc}
% \UnitTested
% Setting equal means using one integer inside the set function of
-% another.
+% another. Check that assigned integer is local/global. No need to
+% check that the other one is defined as \TeX{} does it for us.
% \begin{macrocode}
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
\cs_new_protected:Npn \int_set_eq:NN #1#2 { #1 = #2 }
\cs_generate_variant:Nn \int_set_eq:NN { c }
\cs_generate_variant:Nn \int_set_eq:NN { Nc , cc }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
\cs_new_protected:Npn \int_gset_eq:NN #1#2 { \tex_global:D #1 = #2 }
\cs_generate_variant:Nn \int_gset_eq:NN { c }
\cs_generate_variant:Nn \int_gset_eq:NN { Nc , cc }
@@ -1284,6 +1329,22 @@
%
% \subsection{Setting and incrementing integers}
%
+% Several functions here have a signature |:Nn| and are such that when
+% debugging, the first argument should be checked to be a local/global
+% variable and the second should be wrapped in code for an expression.
+% The temporary function \cs{@@_tmp:w} finds the name |#3| of the
+% function being redefined and writes the appropriate patch.
+% \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1#2#3
+ {
+ \__debug_patch_args:nnnNNpn
+ { #1 ##1 }
+ { }
+ { {##1} { \__debug_chk_expr:nNnN {##2} \@@_eval:w { } #3 } }
+ #2 #3
+ }
+% \end{macrocode}
+%
% \begin{macro}{\int_add:Nn, \int_add:cn}
% \UnitTested
% \begin{macro}{\int_gadd:Nn, \int_gadd:cn}
@@ -1292,20 +1353,23 @@
% \UnitTested
% \begin{macro}{\int_gsub:Nn, \int_gsub:cn}
% \UnitTested
-% Adding and subtracting to and from a counter \ldots
+% Adding and subtracting to and from a counter. For each function,
+% the debugging code produced by \cs{@@_tmp:w} checks that the
+% assigned variable is correctly local/global and wraps the
+% expression in some checking code.
% \begin{macrocode}
-\__debug_patch_args:nNNpn
- { {#1} { \__debug_chk_expr:nNnN {#2} \@@_eval:w { } \int_add:Nn } }
+\@@_tmp:w \__debug_chk_var_local:N
\cs_new_protected:Npn \int_add:Nn #1#2
{ \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: }
-\__debug_patch_args:nNNpn
- { {#1} { \__debug_chk_expr:nNnN {#2} \@@_eval:w { } \int_sub:Nn } }
+\@@_tmp:w \__debug_chk_var_local:N
\cs_new_protected:Npn \int_sub:Nn #1#2
{ \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: }
-\cs_new_protected:Npn \int_gadd:Nn
- { \tex_global:D \int_add:Nn }
-\cs_new_protected:Npn \int_gsub:Nn
- { \tex_global:D \int_sub:Nn }
+\@@_tmp:w \__debug_chk_var_global:N
+\cs_new_protected:Npn \int_gadd:Nn #1#2
+ { \tex_global:D \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: }
+\@@_tmp:w \__debug_chk_var_global:N
+\cs_new_protected:Npn \int_gsub:Nn #1#2
+ { \tex_global:D \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: }
\cs_generate_variant:Nn \int_add:Nn { c }
\cs_generate_variant:Nn \int_gadd:Nn { c }
\cs_generate_variant:Nn \int_sub:Nn { c }
@@ -1327,14 +1391,18 @@
% Incrementing and decrementing of integer registers is done with
% the following functions.
% \begin{macrocode}
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
\cs_new_protected:Npn \int_incr:N #1
{ \tex_advance:D #1 \c_one }
+\__debug_patch:nnNNpn { \__debug_chk_var_local:N #1 } { }
\cs_new_protected:Npn \int_decr:N #1
{ \tex_advance:D #1 - \c_one }
-\cs_new_protected:Npn \int_gincr:N
- { \tex_global:D \int_incr:N }
-\cs_new_protected:Npn \int_gdecr:N
- { \tex_global:D \int_decr:N }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
+\cs_new_protected:Npn \int_gincr:N #1
+ { \tex_global:D \tex_advance:D #1 \c_one }
+\__debug_patch:nnNNpn { \__debug_chk_var_global:N #1 } { }
+\cs_new_protected:Npn \int_gdecr:N #1
+ { \tex_global:D \tex_advance:D #1 - \c_one }
\cs_generate_variant:Nn \int_incr:N { c }
\cs_generate_variant:Nn \int_decr:N { c }
\cs_generate_variant:Nn \int_gincr:N { c }
@@ -1350,14 +1418,16 @@
% \begin{macro}{\int_gset:Nn, \int_gset:cn}
% \UnitTested
% As integers are register-based \TeX{} issues an error
-% if they are not defined. Thus there is no need for the checking
-% code seen with token list variables.
+% if they are not defined. Thus there is no need to check their
+% existence as for token list variables. However, the code that
+% checks whether the assignment is local or global is still needed.
% \begin{macrocode}
-\__debug_patch_args:nNNpn
- { {#1} { \__debug_chk_expr:nNnN {#2} \@@_eval:w { } \int_set:Nn } }
+\@@_tmp:w \__debug_chk_var_local:N
\cs_new_protected:Npn \int_set:Nn #1#2
{ #1 ~ \@@_eval:w #2 \@@_eval_end: }
-\cs_new_protected:Npn \int_gset:Nn { \tex_global:D \int_set:Nn }
+\@@_tmp:w \__debug_chk_var_global:N
+\cs_new_protected:Npn \int_gset:Nn #1#2
+ { \tex_global:D #1 ~ \@@_eval:w #2 \@@_eval_end: }
\cs_generate_variant:Nn \int_set:Nn { c }
\cs_generate_variant:Nn \int_gset:Nn { c }
% \end{macrocode}
@@ -1381,7 +1451,7 @@
%
% \subsection{Integer expression conditionals}
%
-% \begin{macro}[int, EXP]{\__prg_compare_error:, \__prg_compare_error:Nw}
+% \begin{macro}[EXP]{\__prg_compare_error:, \__prg_compare_error:Nw}
% Those functions are used for comparison tests which use a simple
% syntax where only one set of braces is required and additional
% operators such as |!=| and |>=| are supported. The tests first
@@ -1414,9 +1484,9 @@
% \end{macro}
%
% \begin{macro}[pTF, EXP]{\int_compare:n}
-% \begin{macro}[aux, EXP]
+% \begin{macro}[EXP]
% {\@@_compare:w, \@@_compare:Nw, \@@_compare:NNw, \@@_compare:nnN}
-% \begin{macro}[aux, EXP]
+% \begin{macro}[EXP]
% {
% \@@_compare_end_=:NNw,
% \@@_compare_=:NNw,
@@ -1577,8 +1647,8 @@
% \end{macro}
%
% \begin{macro}[EXP, noTF]{\int_case:nn}
-% \begin{macro}[aux]{\@@_case:nnTF}
-% \begin{macro}[aux]{\@@_case:nw, \@@_case_end:nw}
+% \begin{macro}{\@@_case:nnTF}
+% \begin{macro}{\@@_case:nw, \@@_case_end:nw}
% For integer cases, the first task to fully expand the check
% condition. The over all idea is then much the same as for
% \cs{str_case:nn(TF)} as described in \pkg{l3basics}.
@@ -1742,7 +1812,7 @@
% \subsection{Integer step functions}
%
% \begin{macro}{\int_step_function:nnnN}
-% \begin{macro}[aux]{\@@_step:wwwN, \@@_step:NnnnN}
+% \begin{macro}{\@@_step:wwwN, \@@_step:NnnnN}
% Before all else, evaluate the initial value, step, and final value.
% Repeating a function by steps first needs a check on the direction
% of the steps. After that, do the function for the start value then
@@ -1793,7 +1863,7 @@
% \begin{macro}{\int_step_inline:nnnn}
% \begin{macro}{\int_step_variable:nnnNn}
% \UnitTested
-% \begin{macro}[aux]{\@@_step:NNnnnn}
+% \begin{macro}{\@@_step:NNnnnn}
% The approach here is to build a function, with a global integer
% required to make the nesting safe (as seen in other in line
% functions), and map that function using \cs{int_step_function:nnnN}.
@@ -1845,7 +1915,7 @@
%
% \begin{macro}{\int_to_symbols:nnn}
% \UnitTested
-% \begin{macro}[aux]{\@@_to_symbols:nnnn}
+% \begin{macro}{\@@_to_symbols:nnnn}
% For conversion of integers to arbitrary symbols the method is in
% general as follows. The input number (|#1|) is compared to the total
% number of symbols available at each place (|#2|). If the input is larger
@@ -1954,9 +2024,9 @@
%
% \begin{macro}{\int_to_base:nn, \int_to_Base:nn}
% \UnitTested
-% \begin{macro}[aux]{\@@_to_base:nn, \@@_to_Base:nn,
+% \begin{macro}{\@@_to_base:nn, \@@_to_Base:nn,
% \@@_to_base:nnN, \@@_to_Base:nnN, \@@_to_base:nnnN, \@@_to_Base:nnnN}
-% \begin{macro}[aux]{\@@_to_letter:n, \@@_to_Letter:n}
+% \begin{macro}{\@@_to_letter:n, \@@_to_Letter:n}
% \UnitTested
% Converting from base ten (|#1|) to a second base (|#2|) starts with
% computing |#1|: if it is a complicated calculation, we shouldn't
@@ -2129,8 +2199,8 @@
%
% \begin{macro}{\int_to_roman:n, \int_to_Roman:n}
% \UnitTested
-% \begin{macro}[aux]{\@@_to_roman:N, \@@_to_roman:N}
-% \begin{macro}[aux]
+% \begin{macro}{\@@_to_roman:N, \@@_to_roman:N}
+% \begin{macro}
% {
% \@@_to_roman_i:w, \@@_to_roman_v:w, \@@_to_roman_x:w,
% \@@_to_roman_l:w, \@@_to_roman_c:w, \@@_to_roman_d:w,
@@ -2189,7 +2259,7 @@
%
% \subsection{Converting from other formats to integers}
%
-% \begin{macro}[aux,rEXP]{\@@_pass_signs:wn, \@@_pass_signs_end:wn}
+% \begin{macro}[rEXP]{\@@_pass_signs:wn, \@@_pass_signs_end:wn}
% Called as \cs{@@_pass_signs:wn} \meta{signs and digits} \cs{q_stop}
% \Arg{code}, this function leaves in the input stream any sign it
% finds, then inserts the \meta{code} before the first non-sign token
@@ -2212,7 +2282,7 @@
%
% \begin{macro}{\int_from_alph:n}
% \UnitTested
-% \begin{macro}[aux]{\@@_from_alph:nN, \@@_from_alph:N}
+% \begin{macro}{\@@_from_alph:nN, \@@_from_alph:N}
% First take care of signs then loop through the input using the
% \texttt{recursion} quarks. The \cs{@@_from_alph:nN} auxiliary
% collects in its first argument the value obtained so far, and the
@@ -2242,7 +2312,7 @@
%
% \begin{macro}{\int_from_base:nn}
% \UnitTested
-% \begin{macro}[aux]{\@@_from_base:nnN, \@@_from_base:N}
+% \begin{macro}{\@@_from_base:nnN, \@@_from_base:N}
% Leave the signs into the integer expression, then loop through
% characters, collecting the value found so far in the first argument
% of \cs{@@_from_base:nnN}. To convert a single character,
@@ -2323,8 +2393,8 @@
% \begin{macro}{\int_from_roman:n}
% \UnitTested
% \TestMissing{boundary cases / wrong input?}
-% \begin{macro}[aux]{\@@_from_roman:NN}
-% \begin{macro}[aux]{\@@_from_roman_error:w}
+% \begin{macro}{\@@_from_roman:NN}
+% \begin{macro}{\@@_from_roman_error:w}
% The method here is to iterate through the input, finding the
% appropriate value for each letter and building up a sum. This is
% then evaluated by \TeX{}. If any unknown letter is found, skip to
@@ -2376,7 +2446,7 @@
%
% \begin{macro}{\int_show:N, \int_show:c}
% \UnitTested
-% \begin{macro}[aux]{\@@_show:nN}
+% \begin{macro}{\@@_show:nN}
% Diagnostics.
% \begin{macrocode}
\cs_new_eq:NN \int_show:N \__kernel_register_show:N
@@ -2391,7 +2461,7 @@
% expressions: this gives a more unified output.
% \begin{macrocode}
\cs_new_protected:Npn \int_show:n
- { \__msg_show_wrap:Nn \int_eval:n }
+ { \msg_show_eval:Nn \int_eval:n }
% \end{macrocode}
% \end{macro}
%
@@ -2404,10 +2474,10 @@
% \end{macro}
%
% \begin{macro}{\int_log:n}
-% Redirect output of \cs{int_show:n} to the log.
+% Similar to \cs{int_show:n}.
% \begin{macrocode}
\cs_new_protected:Npn \int_log:n
- { \__msg_log_next: \int_show:n }
+ { \msg_log_eval:Nn \int_eval:n }
% \end{macrocode}
% \end{macro}
%