diff options
author | Karl Berry <karl@freefriends.org> | 2017-07-21 22:02:53 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2017-07-21 22:02:53 +0000 |
commit | 51d74983b14a9c2832b6bfbdcac4e99243aabbb6 (patch) | |
tree | 05fdccae9fc0c2c4cbd2371ae2b9cc1b73ea615c /Master/texmf-dist/source/latex/l3kernel/l3basics.dtx | |
parent | 71fb1b25309a75d246b0896063f0940332c85919 (diff) |
l3 (21jul17)
git-svn-id: svn://tug.org/texlive/trunk@44864 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3basics.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3basics.dtx | 683 |
1 files changed, 425 insertions, 258 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index 260e328e5c8..573b39c470f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx @@ -41,7 +41,7 @@ % }^^A % } % -% \date{Released 2017/07/15} +% \date{Released 2017/07/19} % % \maketitle % @@ -1149,15 +1149,6 @@ % % \section{Internal kernel functions} % -% \begin{function}{\__chk_if_exist_cs:N, \__chk_if_exist_cs:c} -% \begin{syntax} -% \cs{__chk_if_exist_cs:N} \meta{cs} -% \end{syntax} -% This function checks that \meta{cs} exists according to the -% criteria for \cs{cs_if_exist_p:N}, and if not raises a kernel-level -% error. -% \end{function} -% % \begin{function}{\__chk_if_free_cs:N, \__chk_if_free_cs:c} % \begin{syntax} % \cs{__chk_if_free_cs:N} \meta{cs} @@ -1167,51 +1158,6 @@ % error. % \end{function} % -% \begin{function}{\__chk_if_exist_var:N} -% \begin{syntax} -% \cs{__chk_if_exist_var:N} \meta{var} -% \end{syntax} -% This function checks that \meta{var} is defined according to the -% criteria for \cs{cs_if_free_p:N}, and if not raises a kernel-level -% error. This function is only created if the package option -% \texttt{check-declarations} is active. -% \end{function} -% -% \begin{function}{\__debug_log:x} -% \begin{syntax} -% \cs{__debug_log:x} \Arg{message text} -% \end{syntax} -% Only defined when debugging is enabled (hence only in package mode -% with the right options). If the \texttt{log-functions} option is -% active, this function writes the \meta{message text} to the log file -% using \cs{iow_log:x}. Otherwise, the \meta{message text} is ignored -% using \cs{use_none:n}. -% \end{function} -% -% \begin{function}{\__debug_suspend_log:, \__debug_resume_log:} -% \begin{syntax} -% \cs{__debug_suspend_log:} \ldots{} \cs{__debug_log:x} \ldots{} \cs{__debug_resume_log:} -% \end{syntax} -% Any \cs{__debug_log:x} command between \cs{__debug_suspend_log:} and -% \cs{__debug_resume_log:} is suppressed. These two commands can be -% nested and do nothing when debugging is disabled. -% \end{function} -% -% \begin{function}{\__debug_patch:nnNw} -% \begin{syntax} -% \cs{__debug_patch:nnNw} \Arg{before} \Arg{after} \meta{definition} \ldots{} -% \end{syntax} -% If debugging is enabled (by one of few \pkg{expl3} options that -% imply \texttt{enable-debug}), adds the \meta{before} and -% \meta{after} tokens (which can involve |#1| and so on) in the -% \meta{definition} that follows. Otherwise ignore the \meta{before} -% and \meta{after} code and perform the \meta{definition} with no -% patching. The \meta{definition} must start with \cs{cs_new:Npn} or -% \cs{cs_set:Npn} or \cs{cs_gset:Npn} or \cs{prg_new_conditional:Npnn} -% or their protected counterparts. Other cases could be added as -% needed. -% \end{function} -% % \begin{function}[EXP]{\__cs_count_signature:N, \__cs_count_signature:c} % \begin{syntax} % \cs{__cs_count_signature:N} \meta{function} @@ -1266,6 +1212,108 @@ % normally (spaces, characters with category other). % \end{function} % +% \begin{function}{\__debug:TF} +% \begin{syntax} +% \cs{__debug:TF} \Arg{true code} \Arg{false code} +% \end{syntax} +% Runs the \meta{true code} if debugging is enabled, namely only in +% \LaTeXe{} package mode with one of the options +% \texttt{check-declarations}, \texttt{enable-debug}, or +% \texttt{log-functions}. Otherwise runs the \meta{false code}. The +% |T| and |F| variants are not provided for this low-level +% conditional. +% \end{function} +% +% \begin{function}{\__debug_chk_cs_exist:N, \__debug_chk_cs_exist:c} +% \begin{syntax} +% \cs{__debug_chk_cs_exist:N} \meta{cs} +% \end{syntax} +% This function is only created if debugging is enabled. It checks +% that \meta{cs} exists according to the criteria for +% \cs{cs_if_exist_p:N}, and if not raises a kernel-level error. +% \end{function} +% +% \begin{function}{\__debug_chk_var_exist:N} +% \begin{syntax} +% \cs{__debug_chk_var_exist:N} \meta{var} +% \end{syntax} +% This function is only created if debugging is enabled. It checks +% that \meta{var} is defined according to the criteria for +% \cs{cs_if_exist_p:N}, and if not raises a kernel-level error. +% \end{function} +% +% \begin{function}{\__debug_log:x} +% \begin{syntax} +% \cs{__debug_log:x} \Arg{message text} +% \end{syntax} +% If the \texttt{log-functions} option is active, this function writes +% the \meta{message text} to the log file using \cs{iow_log:x}. +% Otherwise, the \meta{message text} is ignored using \cs{use_none:n}. +% This function is only created if debugging is enabled. +% \end{function} +% +% \begin{function}{\__debug_suspend_log:, \__debug_resume_log:} +% \begin{syntax} +% \cs{__debug_suspend_log:} \ldots{} \cs{__debug_log:x} \ldots{} \cs{__debug_resume_log:} +% \end{syntax} +% Any \cs{__debug_log:x} command between \cs{__debug_suspend_log:} and +% \cs{__debug_resume_log:} is suppressed. These two commands can be +% nested. These functions are only created if debugging is enabled. +% \end{function} +% +% \begin{function}{\__debug_patch:nnNNpn} +% \begin{syntax} +% \cs{__debug_patch:nnNNpn} \Arg{before} \Arg{after} +% \meta{definition} \meta{function} \meta{parameters} \Arg{code} +% \end{syntax} +% If debugging is not enabled, this function ignores the \meta{before} +% and \meta{after} code and performs the \meta{definition} with no +% patching. Otherwise it replaces \meta{code} by \meta{before} +% \meta{code} \meta{after} (which can involve |#1| and so on) in the +% \meta{definition} that follows. The \meta{definition} must start +% with \cs{cs_new:Npn} or \cs{cs_set:Npn} or \cs{cs_gset:Npn} or their +% \texttt{_protected} counterparts. Other cases can be added as +% needed. +% \end{function} +% +% \begin{function}{\__debug_patch_conditional:nNNpnn} +% \begin{syntax} +% \cs{__debug_patch_conditional:nNNpn} \Arg{before} +% \meta{definition} \meta{conditional} \meta{parameters} \Arg{type} \Arg{code} +% \end{syntax} +% Similar to \cs{__debug_patch:nnNNpn} for conditionals, namely +% \meta{definition} must be \cs{prg_new_conditional:Npnn} or its +% \texttt{_protected} counterpart. There is no \meta{after} code +% because that would interfere with the action of the conditional. +% \end{function} +% +% \begin{function} +% {\__debug_patch_args:nNNpn, \__debug_patch_conditional_args:nNNpnn} +% \begin{syntax} +% \cs{__debug_patch_args:nNNpn} \Arg{arguments} +% \meta{definition} \meta{function} \meta{parameters} \Arg{code} +% \end{syntax} +% Like \cs{__debug_patch:nnNNpn}, this tweaks the following +% definition, but from the \enquote{inside out} (and if debugging is +% not enabled, the \meta{arguments} are ignored). It replaces |#1|, +% |#2| and so on in the \meta{code} of the definition as indicated by +% the \meta{arguments}. More precisely, a temporary function is +% defined using the \meta{definition} with the \meta{parameters} and +% \meta{code}, then the result of expanding that function once in +% front of the \meta{arguments} is used instead of the \meta{code} +% when defining the actual function. For instance, +% \begin{quote} +% \cs{__debug_patch_args:nNNpn} |{ { (#1) } }| \\ +% \cs{cs_new:Npn} \cs{int_eval:n} |#1| \\ +% ~~|{ \__int_value:w \__int_eval:w #1 \__int_eval_end: }| +% \end{quote} +% replaces |#1| by |(#1)| in the definition of \cs{int_eval:n} when +% debugging is enabled. This fails if the \meta{code} contains~|##|. +% The \cs{__debug_patch_conditional_args:nNNpnn} function is for use +% before \cs{prg_new_conditional:Npnn} or its \texttt{_protected} +% counterpart. +% \end{function} +% % \begin{function}{\__kernel_register_show:N, \__kernel_register_show:c} % \begin{syntax} % \cs{__kernel_register_show:N} \meta{register} @@ -1665,6 +1713,313 @@ % \end{macrocode} % \end{macro} % +% \subsection{Debugging and patching later definitions} +% +% \begin{macro}[int]{\__debug:TF} +% A more meaningful test of whether debugging is enabled than messing +% up with guards. We can also more easily change the logic in one +% place then. At present, debugging is disabled in the format and in +% generic mode, while in \LaTeXe{} mode it is enabled if one of the +% options \texttt{enable-debug}, \texttt{log-functions} or +% \texttt{check-declarations} was given. +% \begin{macrocode} +\cs_set_protected:Npn \__debug:TF #1#2 {#2} +%<*package> +\tex_ifodd:D \l@expl@enable@debug@bool + \cs_set_protected:Npn \__debug:TF #1#2 {#1} +\fi: +%</package> +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\debug_on:n, \debug_off:n} +% +% \begin{macrocode} +\__debug:TF + { + \cs_set_protected:Npn \debug_on:n #1 + { + \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} } + { + \cs_if_exist_use:cF { __debug_##1_on: } + { \__msg_kernel_error:nnn { kernel } { debug } {##1} } + } + } + \cs_set_protected:Npn \debug_off:n #1 + { + \exp_args:No \clist_map_inline:nn { \tl_to_str:n {#1} } + { + \cs_if_exist_use:cF { __debug_##1_off: } + { \__msg_kernel_error:nnn { kernel } { debug } {##1} } + } + } + } + { + \cs_set_protected:Npn \debug_on:n #1 + { + \__msg_kernel_error:nnx { kernel } { enable-debug } + { \tl_to_str:n { \debug_on:n {#1} } } + } + \cs_set_protected:Npn \debug_off:n #1 + { + \__msg_kernel_error:nnx { kernel } { enable-debug } + { \tl_to_str:n { \debug_off:n {#1} } } + } + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[aux] +% {\__debug_check-declarations_on:, \__debug_check-declarations_off:} +% \begin{macro}[int]{\__debug_chk_var_exist:N} +% \begin{macro}[int]{\__debug_chk_cs_exist:N, \__debug_chk_cs_exist:c} +% When debugging is not active these two functions produce an +% error. Otherwise they set up \cs{__debug_chk_var_exist:N} and +% \cs{__debug_chk_cs_exist:N}, two functions that test (when +% \texttt{check-declarations} is active) that their argument is +% defined. +% \begin{macrocode} +\__debug:TF + { + \exp_args:Nc \cs_set_protected:Npn { __debug_check-declarations_on: } + { + \cs_set_protected:Npn \__debug_chk_var_exist:N ##1 + { + \cs_if_exist:NF ##1 + { + \__msg_kernel_error:nnx { kernel } { non-declared-variable } + { \token_to_str:N ##1 } + } + } + \cs_set_protected:Npn \__debug_chk_cs_exist:N ##1 + { + \cs_if_exist:NF ##1 + { + \__msg_kernel_error:nnx { kernel } { command-not-defined } + { \token_to_str:N ##1 } + } + } + } + \exp_args:Nc \cs_set_protected:Npn { __debug_check-declarations_off: } + { + \cs_set_protected:Npn \__debug_chk_var_exist:N ##1 { } + \cs_set_protected:Npn \__debug_chk_cs_exist:N ##1 { } + } + \cs_set_protected:Npn \__debug_chk_cs_exist:c + { \exp_args:Nc \__debug_chk_cs_exist:N } + \tex_ifodd:D \l@expl@check@declarations@bool + \use:c { __debug_check-declarations_on: } + \else: + \use:c { __debug_check-declarations_off: } + \fi: + } + { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[aux]{\__debug_log-functions_on:, \__debug_log-functions_off:} +% \begin{macro}[int]{\__debug_log:x, \__debug_suspend_log:, \__debug_resume_log:} +% These two functions +% (corresponding to the \pkg{expl3} option \texttt{log-functions}) +% control whether \cs{__debug_log:x} writes to the log file or not. +% Since \cs{iow_log:x} does not yet have its final definition we do +% not use \cs{cs_set_eq:NN} (not defined yet anyway). The +% \cs{__debug_suspend_log:} function disables \cs{__debug_log:x} until +% the matching \cs{__debug_resume_log:}. These two commands are used +% to improve the logging for datatypes with multiple parts, currently +% only coffins. They should come in pairs, which can be nested (this +% complicates the code here and is currently unused). The function +% \cs{exp_not:o} is defined in \pkg{l3expan} later on but +% \cs{__debug_suspend_log:} and \cs{__debug_resume_log:} are not used +% before that point. Once everything is defined, turn logging on or +% off depending on what option was given. +% When debugging is not enabled, simply produce an error. +% \begin{macrocode} +\__debug:TF + { + \exp_args:Nc \cs_set_protected:Npn { __debug_log-functions_on: } + { + \cs_set_protected:Npn \__debug_log:x { \iow_log:x } + \cs_set_protected:Npn \__debug_suspend_log: + { + \cs_set_protected:Npx \__debug_resume_log: + { + \cs_set_protected:Npn \__debug_resume_log: + { \exp_not:o { \__debug_resume_log: } } + \cs_set_protected:Npn \__debug_log:x + { \exp_not:o { \__debug_log:x } } + } + \cs_set_protected:Npn \__debug_log:x { \use_none:n } + } + \cs_set_protected:Npn \__debug_resume_log: { } + } + \exp_args:Nc \cs_set_protected:Npn { __debug_log-functions_off: } + { + \cs_set_protected:Npn \__debug_log:x { \use_none:n } + \cs_set_protected:Npn \__debug_suspend_log: { } + \cs_set_protected:Npn \__debug_resume_log: { } + } + \tex_ifodd:D \l@expl@log@functions@bool + \use:c { __debug_log-functions_on: } + \else: + \use:c { __debug_log-functions_off: } + \fi: + } + { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\__debug_deprecation_on:, \__debug_deprecation_off:} +% \begin{variable}{\g__debug_deprecation_on_tl, \g__debug_deprecation_off_tl} +% Some commands were more recently deprecated and not yet removed; +% only make these into errors if the user requests it. This relies on +% two token lists, filled up by calls to +% \cs{__debug_deprecation:nnNNpn} in each module. +% \begin{macrocode} +\__debug:TF + { + \cs_set_protected:Npn \__debug_deprecation_on: + { \g__debug_deprecation_on_tl } + \cs_set_protected:Npn \__debug_deprecation_off: + { \g__debug_deprecation_off_tl } + \cs_set_nopar:Npn \g__debug_deprecation_on_tl { } + \cs_set_nopar:Npn \g__debug_deprecation_off_tl { } + } + { } +% \end{macrocode} +% \end{variable} +% \end{macro} +% +% \begin{macro}[int]{\__debug_deprecation:nnNNpn} +% \begin{macro}[aux]{\__debug_deprecation_aux:nnNnn} +% Grab a definition (at present, must be \cs{cs_new_protected:Npn}). +% Add to \cs{g__debug_deprecation_on_tl} some code that makes the +% defined macro |#3| outer (and defines it as an error). Add to +% \cs{g__debug_deprecation_off_tl} the definition itself. In both +% cases we undefine the token with \cs{tex_let:D} to avoid taking a +% potentially outer macro as the argument of some \pkg{expl3} +% function. Finally define the macro itself to produce a warning then +% redefine and call itself. The macro initially takes no parameters: +% together with the \texttt{x}-expanding assignment and \cs{exp_not:n} +% this gives a convenient way of storing the macro's definition in +% itself in order to only produce the warning once for each macro. +% If debugging is disabled, \cs{__debug_deprecation:nnNNpn} lets the +% definition happen. +% \begin{macrocode} +\__debug:TF + { + \cs_set_protected:Npn \__debug_deprecation:nnNNpn #1#2#3#4#5# + { + \if_meaning:w \cs_new_protected:Npn #3 + \else: + \__msg_kernel_error:nnx { kernel } { debug-unpatchable } + { \token_to_str:N #3 ~(for~deprecation) } + \fi: + \__debug_deprecation_aux:nnNnn {#1} {#2} #4 {#5} + } + \cs_set_protected:Npn \__debug_deprecation_aux:nnNnn #1#2#3#4#5 + { + \tl_gput_right:Nn \g__debug_deprecation_on_tl + { + \tex_let:D #3 \scan_stop: + \__deprecation_error:Nnn #3 {#2} {#1} + } + \tl_gput_right:Nn \g__debug_deprecation_off_tl + { + \tex_let:D #3 \scan_stop: + \cs_set_protected:Npn #3 #4 {#5} + } + \cs_new_protected:Npx #3 + { + \exp_not:N \__msg_kernel_warning:nnxxx + { kernel } { deprecated-command } + {#1} { \token_to_str:N #3 } { \tl_to_str:n {#2} } + \exp_not:n { \cs_gset_protected:Npn #3 #4 {#5} } + \exp_not:N #3 + } + } + } + { \cs_set_protected:Npn \__debug_deprecation:nnNNpn #1#2 { } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int] +% {\__debug_patch:nnNNpn, \__debug_patch_conditional:nNNpnn} +% \begin{macro}[aux] +% {\__debug_patch_aux:nnNNnn, \__debug_patch_aux:nNNnnn} +% When debugging is not enabled, \cs{__debug_patch:nnNNpn} and +% \cs{__debug_patch_conditional:nNNpnn} throw the patch away. +% Otherwise they can be followed by \cs{cs_new:Npn} (or similar), and +% \cs{prg_new_conditional:Npnn} (or similar), respectively. In each +% case, grab the name of the function to be defined and its parameters +% then insert tokens before and/or after the definition. +% \begin{macrocode} +\__debug:TF + { + \cs_set_protected:Npn \__debug_patch:nnNNpn #1#2#3#4#5# + { \__debug_patch_aux:nnNNnn {#1} {#2} #3 #4 {#5} } + \cs_set_protected:Npn \__debug_patch_conditional:nNNpnn #1#2#3#4# + { \__debug_patch_aux:nNNnnn {#1} #2 #3 {#4} } + \cs_set_protected:Npn \__debug_patch_aux:nnNNnn #1#2#3#4#5#6 + { #3 #4 #5 { #1 #6 #2 } } + \cs_set_protected:Npn \__debug_patch_aux:nNNnnn #1#2#3#4#5#6 + { #2 #3 #4 {#5} { #1 #6 } } + } + { + \cs_set_protected:Npn \__debug_patch:nnNNpn #1#2 { } + \cs_set_protected:Npn \__debug_patch_conditional:nNNpnn #1 { } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int] +% {\__debug_patch_args:nNNpn, \__debug_patch_conditional_args:nNNpnn} +% \begin{macro}[aux] +% { +% \__debug_tmp:w, +% \__debug_patch_args_aux:nNNnn, +% \__debug_patch_args_aux:nNNnnn +% } +% See \cs{__debug_patch:nnNNpn}. The first argument is something like +% |{#1}{(#2)}|. Define a temporary macro using the \meta{parameters} +% and \meta{code} of the definition that follows, then expand that +% temporary macro in front of the first argument to obtain new +% \meta{code}. Then perform the definition as if that new \meta{code} +% was directly typed in the file. To make it easy to expand in the +% definition, treat it as a \enquote{pre}-code to an empty definition. +% \begin{macrocode} +\__debug:TF + { + \cs_set_protected:Npn \__debug_patch_args:nNNpn #1#2#3#4# + { \__debug_patch_args_aux:nNNnn {#1} #2 #3 {#4} } + \cs_set_protected:Npn \__debug_patch_conditional_args:nNNpnn #1#2#3#4# + { \__debug_patch_args_aux:nNNnnn {#1} #2 #3 {#4} } + \cs_set_protected:Npn \__debug_patch_args_aux:nNNnn #1#2#3#4#5 + { + \cs_set:Npn \__debug_tmp:w #4 {#5} + \exp_after:wN \__debug_patch_aux:nnNNnn \exp_after:wN + { \__debug_tmp:w #1 } { } #2 #3 {#4} { } + } + \cs_set_protected:Npn \__debug_patch_args_aux:nNNnnn #1#2#3#4#5#6 + { + \cs_set:Npn \__debug_tmp:w #4 {#6} + \exp_after:wN \__debug_patch_aux:nNNnnn \exp_after:wN + { \__debug_tmp:w #1 } #2 #3 {#4} {#5} { } + } + } + { + \cs_set_protected:Npn \__debug_patch_args:nNNpn #1 { } + \cs_set_protected:Npn \__debug_patch_conditional_args:nNNpnn #1 { } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \subsection{Conditional processing and definitions} % % Underneath any predicate function (|_p|) or other conditional forms @@ -1995,26 +2350,22 @@ #5 {#1} {#2} {#3} {#4} \__prg_set_eq_conditional_loop:nnnnNw {#1} {#2} {#3} {#4} #5 } +\__debug_patch:nnNNpn + { \__debug_chk_cs_exist:c { #5 _p : #6 } } { } \cs_set:Npn \__prg_set_eq_conditional_p_form:wNnnnn #1 \q_stop #2#3#4#5#6 - { - \__chk_if_exist_cs:c { #5 _p : #6 } - #2 { #3 _p : #4 } { #5 _p : #6 } - } + { #2 { #3 _p : #4 } { #5 _p : #6 } } +\__debug_patch:nnNNpn + { \__debug_chk_cs_exist:c { #5 : #6 TF } } { } \cs_set:Npn \__prg_set_eq_conditional_TF_form:wNnnnn #1 \q_stop #2#3#4#5#6 - { - \__chk_if_exist_cs:c { #5 : #6 TF } - #2 { #3 : #4 TF } { #5 : #6 TF } - } + { #2 { #3 : #4 TF } { #5 : #6 TF } } +\__debug_patch:nnNNpn + { \__debug_chk_cs_exist:c { #5 : #6 T } } { } \cs_set:Npn \__prg_set_eq_conditional_T_form:wNnnnn #1 \q_stop #2#3#4#5#6 - { - \__chk_if_exist_cs:c { #5 : #6 T } - #2 { #3 : #4 T } { #5 : #6 T } - } + { #2 { #3 : #4 T } { #5 : #6 T } } +\__debug_patch:nnNNpn + { \__debug_chk_cs_exist:c { #5 : #6 F } } { } \cs_set:Npn \__prg_set_eq_conditional_F_form:wNnnnn #1 \q_stop #2#3#4#5#6 - { - \__chk_if_exist_cs:c { #5 : #6 F } - #2 { #3 : #4 F } { #5 : #6 F } - } + { #2 { #3 : #4 F } { #5 : #6 F } } % \end{macrocode} % \end{macro} % \end{macro} @@ -2278,7 +2629,7 @@ % \end{macrocode} % \end{macro} % -% \subsection{Checking and patching (new) functions} +% \subsection{Preliminaries for new functions} % % We provide two kinds of functions that can be used to define % control sequences. On the one hand we have functions that check @@ -2338,130 +2689,6 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\debug_log_functions_on:, \debug_log_functions_off:} -% \begin{macro}[int]{\__debug_log:x, \__debug_suspend_log:, \__debug_resume_log:} -% When debugging is not enabled at all (including in the format), the -% \cs[index=debug_log_functions_on:]{debug_log_functions_on/off:} -% functions simply produce errors, while \cs{__debug_suspend_log:} and -% \cs{__debug_resume_log:} do nothing. -% \begin{macrocode} -\cs_set_protected:Npn \debug_log_functions_on: - { - \__msg_kernel_error:nnx { kernel } { enable-debug } - { \token_to_str:N \debug_log_functions_on: } - } -\cs_set_protected:Npn \debug_log_functions_off: - { - \__msg_kernel_error:nnx { kernel } { enable-debug } - { \token_to_str:N \debug_log_functions_off: } - } -\cs_set_protected:Npn \__debug_suspend_log: { } -\cs_set_protected:Npn \__debug_resume_log: { } -% \end{macrocode} -% Otherwise, they set up \cs{__debug_log:x}, -% \cs{__debug_suspend_log:}, and \cs{__debug_resume_log:} to have the -% following behaviour. The function \cs{__debug_log:x} is used to -% write some information to the \texttt{log} file in case the -% \texttt{log-function} option is active and to otherwise ignore its -% argument. Using this function rather than directly using -% \cs{iow_log:x} allows for \cs{__debug_suspend_log:} which disables -% such messages until the matching \cs{__debug_resume_log:}. These -% two commands are used to improve the logging for datatypes with -% multiple parts (currently only coffins). They should come in pairs, -% which can be nested. The function \cs{exp_not:o} is defined in -% \pkg{l3expan} later on but \cs{__debug_suspend_log:} and -% \cs{__debug_resume_log:} are not used before that point. Once -% everything is defined, turn logging on or off depending on what -% option was given. -% \begin{macrocode} -%<*package> -\tex_ifodd:D \l@expl@enable@debug@bool - \cs_set_protected:Npn \debug_log_functions_on: - { - \cs_set_protected:Npn \__debug_log:x { \iow_log:x } - \cs_set_protected:Npn \__debug_suspend_log: - { - \cs_set_protected:Npx \__debug_resume_log: - { - \cs_set_protected:Npn \__debug_resume_log: - { \exp_not:o { \__debug_resume_log: } } - \cs_set_protected:Npn \__debug_log:x - { \exp_not:o { \__debug_log:x } } - } - \cs_set_protected:Npn \__debug_log:x { \use_none:n } - } - \cs_set_protected:Npn \__debug_resume_log: { } - } - \cs_set_protected:Npn \debug_log_functions_off: - { - \cs_set_protected:Npn \__debug_log:x { \use_none:n } - \cs_set_protected:Npn \__debug_suspend_log: { } - \cs_set_protected:Npn \__debug_resume_log: { } - } - \tex_ifodd:D \l@expl@log@functions@bool - \debug_log_functions_on: - \else: - \debug_log_functions_off: - \fi: -\fi: -%</package> -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[int]{\__debug_patch:nnNw} -% \begin{macro}[aux] -% { -% \__debug_patch_param:NNnnNnp, -% \__debug_patch_new:nnNNnn, -% \__debug_patch_new_conditional:nnNNnnn -% } -% When debugging is not enabled, \cs{__debug_patch:nnNw} throws the -% patch away. Otherwise it can be followed by \cs{cs_new:Npn} or -% \cs{prg_new_conditional:Npnn} or their protected counterparts. In -% each case, grab the name of the function to be defined and its -% parameters using \cs{__debug_patch_param:w} then insert tokens -% before and after the definition. Of course for a conditional one -% should likely not insert anything after the code. -% \begin{macrocode} -\cs_set_protected:Npn \__debug_patch:nnNw #1#2 { } -%<*package> -\tex_ifodd:D \l@expl@enable@debug@bool - \cs_set_protected:Npn \__debug_patch:nnNw #1#2#3 - { - \tex_ifcase:D - \if_meaning:w #3 \cs_new_protected:Npn 1~ \fi: - \if_meaning:w #3 \cs_new:Npn 1~ \fi: - \if_meaning:w #3 \cs_set_protected:Npn 1~ \fi: - \if_meaning:w #3 \cs_set:Npn 1~ \fi: - \if_meaning:w #3 \cs_gset_protected:Npn 1~ \fi: - \if_meaning:w #3 \cs_gset:Npn 1~ \fi: - \if_meaning:w #3 \prg_new_protected_conditional:Npnn 2~ \fi: - \if_meaning:w #3 \prg_new_conditional:Npnn 2~ \fi: - \__msg_kernel_error:nnx { kernel } { debug-unpatchable } - { \token_to_str:N #3 } - \or: - \exp_after:wN \__debug_patch_param:NNnnNnp - \exp_after:wN \__debug_patch_new:nnNNnn - \else: - \exp_after:wN \__debug_patch_param:NNnnNnp - \exp_after:wN \__debug_patch_new_conditional:nnNNnnn - \fi: - \use_none:nn {#1} {#2} #3 - } - \cs_set_protected:Npn \__debug_patch_param:NNnnNnp #1#2#3#4#5#6#7# - { #1 {#3} {#4} #5 #6 {#7} } - \cs_set_protected:Npn \__debug_patch_new:nnNNnn #1#2#3#4#5#6 - { #3 #4 #5 { #1 #6 #2 } } - \cs_set_protected:Npn \__debug_patch_new_conditional:nnNNnnn - #1#2#3#4#5#6#7 - { #3 #4 #5 {#6} { #1 #7 #2 } } -\fi: -%</package> -% \end{macrocode} -% \end{macro} -% \end{macro} -% % \begin{macro}[int]{\__chk_if_free_cs:N, \__chk_if_free_cs:c} % This command is called by \cs{cs_new_nopar:Npn} and \cs{cs_new_eq:NN} % \emph{etc.}\ @@ -2471,7 +2698,7 @@ % issued. We have to make sure we don't put the argument into the % conditional processing since it may be an |\if...| type function! % \begin{macrocode} -\__debug_patch:nnNw { } +\__debug_patch:nnNNpn { } { \__debug_log:x { Defining~\token_to_str:N #1~ \msg_line_context: } } \cs_set_protected:Npn \__chk_if_free_cs:N #1 { @@ -2486,66 +2713,6 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\debug_check_declarations_on:, \debug_check_declarations_off:} -% \begin{macro}[int]{\__chk_if_exist_var:N} -% When debugging is not active these two user functions produce an -% error. Otherwise they set up \cs{__chk_if_exist_var:N}, a function -% which when \texttt{check-declarations} is active tests that a given -% variable is defined. -% \begin{macrocode} -\cs_set_protected:Npn \debug_check_declarations_on: - { - \__msg_kernel_error:nnx { kernel } { enable-debug } - { \token_to_str:N \debug_check_declarations_on: } - } -\cs_set_protected:Npn \debug_check_declarations_off: - { - \__msg_kernel_error:nnx { kernel } { enable-debug } - { \token_to_str:N \debug_check_declarations_off: } - } -%<*package> -\tex_ifodd:D \l@expl@enable@debug@bool - \cs_set_protected:Npn \debug_check_declarations_on: - { - \cs_set_protected:Npn \__chk_if_exist_var:N ##1 - { - \cs_if_exist:NF ##1 - { - \__msg_kernel_error:nnx { check } { non-declared-variable } - { \token_to_str:N ##1 } - } - } - } - \cs_set_protected:Npn \debug_check_declarations_off: - { \cs_set_protected:Npn \__chk_if_exist_var:N ##1 { } } - \tex_ifodd:D \l@expl@check@declarations@bool - \debug_check_declarations_on: - \else: - \debug_check_declarations_off: - \fi: -\fi: -%</package> -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[int]{\__chk_if_exist_cs:N, \__chk_if_exist_cs:c} -% This function issues an error message when the control sequence -% in its argument does not exist. -% \begin{macrocode} -\cs_set_protected:Npn \__chk_if_exist_cs:N #1 - { - \cs_if_exist:NF #1 - { - \__msg_kernel_error:nnx { kernel } { command-not-defined } - { \token_to_str:N #1 } - } - } -\cs_set_protected:Npn \__chk_if_exist_cs:c - { \exp_args:Nc \__chk_if_exist_cs:N } -% \end{macrocode} -% \end{macro} -% % \subsection{Defining new functions} % % \begin{macro} @@ -2745,7 +2912,7 @@ \exp_args:Nx \__cs_parm_from_arg_count_test:nnF { \exp_after:wN \exp_not:n - \if_case:w \__int_eval:w #2 \__int_eval_end: + \if_case:w \__int_eval:w (#2) \__int_eval_end: { } \or: { ##1 } \or: { ##1##2 } |