[latex3-commits] [git/LaTeX3-latex3-latex2e] gh239: Guard against "normal" macros and primitives (97e7893c)
PhelypeOleinik
tex.phelype at gmail.com
Wed Jun 3 07:38:37 CEST 2020
Repository : https://github.com/latex3/latex2e
On branch : gh239
Link : https://github.com/latex3/latex2e/commit/97e7893c75c41936d038b745f8fb43fbd0741ee7
>---------------------------------------------------------------
commit 97e7893c75c41936d038b745f8fb43fbd0741ee7
Author: PhelypeOleinik <tex.phelype at gmail.com>
Date: Wed Jun 3 02:38:37 2020 -0300
Guard against "normal" macros and primitives
>---------------------------------------------------------------
97e7893c75c41936d038b745f8fb43fbd0741ee7
base/ltdefns.dtx | 57 ++++++++++++++++++++++++++++++++++++------
base/testfiles/github-0239.lvt | 14 +++++++++++
base/testfiles/github-0239.tlg | 21 ++++++++++++++++
3 files changed, 84 insertions(+), 8 deletions(-)
diff --git a/base/ltdefns.dtx b/base/ltdefns.dtx
index 74577dc5..0a40fac7 100644
--- a/base/ltdefns.dtx
+++ b/base/ltdefns.dtx
@@ -1331,8 +1331,7 @@
% \end{macrocode}
%
% \begin{macro}{\declare at commandcopy}
-% Start by setting \cs{escapechar} to $-1$, then check if the command is
-% already defined. The proper action, if the command is defined or not is
+% Start by checking if the command is already defined. The proper action is
% taken by each specific command above. If all's good, then
% \cs{declare at command@copy} is called with the command being defined and the
% command being copied.
@@ -1347,7 +1346,20 @@
% \begin{macro}{\declare at command@copy at loop}
% \begin{macro}{\declare at command@copy at loop@aux}
% \begin{macro}{\declare at command@copy at do}
+% \begin{macro}{\declare at command@copy at let}
+% \begin{macro}{\declare at command@copy at chk@args}
% \begin{macro}{\@declarecommandcopylisthook}
+% \cs{declare at command@copy at loop} will start by using
+% \cs{declare at command@copy at chk@args} to check if the macro being copied
+% (\verb=#2=) is a parameterless (\cs{protected}) macro. If it is not, a
+% simple \cs{let} is used to copy the definition and we're done. This is so
+% because the high-level commands that are in the scope of this macro are
+% always defined so that the top-level macro doesn't take any argument. This
+% first test is necessary because later on we need to be able to expand the
+% \verb=#2= without the risk of it Breaking Badly, and as a bonus, this speeds
+% up the process in case we used \cs{NewCommandCopy} in a ``normal'' macro.
+%
+% If \cs{declare at command@copy at chk@args} branched to false, then
% \cs{declare at command@copy at loop} will loop over the list of items in the
% \cs{@declarecommandcopylisthook} token list, and process each item with
% \verb=#1= (the command being defined) and \verb=#2= (the command being
@@ -1363,17 +1375,20 @@
% tests that command, branching to true or false. If this macro branched to
% true, then the second macro is used with the two macros (the one being
% copied to, and the one being copied from) to perform the assignment.
-% If none of the tests in the \cs{@declarecommandcopylisthook} token list%
+% If none of the tests in the \cs{@declarecommandcopylisthook} token list
% resulted true, then both macros are just \cs{let} to one another.
% \begin{macrocode}
\def\declare at command@copy#1#2{%
- \expandafter\declare at command@copy at loop\expandafter#2%
- \@declarecommandcopylisthook{\@nnil\@nnil}%
- \@declare at command@end#1#2}
+ \expandafter\declare at command@copy at chk@args\meaning#2:->\@nil
+ {\expandafter\declare at command@copy at loop\expandafter#2%
+ \@declarecommandcopylisthook{\@nnil\@nnil}%
+ \@declare at command@end}%
+ {\declare at command@copy at let}%
+ #1#2}%
\def\declare at command@copy at loop#1#2{\declare at command@copy at loop@aux#1#2}
\def\declare at command@copy at loop@aux#1#2#3{%
\ifx\@nnil#2%
- \declare at command@copy at do\let
+ \declare at command@copy at do\declare at command@copy at let
\else
#2{#1}%
{\declare at command@copy at do{#3}}%
@@ -1384,6 +1399,16 @@
\@declare at command@end#4#5{%
\fi
#1#4#5}
+\def\declare at command@copy at let#1#2{\let#1=#2\relax}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\declare at command@copy at chk@args#1:->#2\@nil{%
+ \@expl at str@if at eq@@nnTF{#1}{macro}%
+ {\@firstoftwo}%
+ {\@expl at str@if at eq@@nnTF{#1}{\protected macro}%
+ {\@firstoftwo}%
+ {\@secondoftwo}}}
% \end{macrocode}
%
% The initial definition of \cs{@declarecommandcopylisthook} contains the
@@ -1492,7 +1517,7 @@
\def\copy at kernel@robust at command#1#2{%
\@if at newcommand#2%
{\@copy at newcommand#1#2}%
- {\let#1#2}}
+ {\declare at command@copy at let#1#2}}
% \end{macrocode}
%
% \begin{macro}{\@if at newcommand}
@@ -1545,6 +1570,22 @@
\def\@@expl at cs@to at str@@w#1\@@expl at cs@to at str@@N{-\number\fi\expandafter\z@}
% \end{macrocode}
%
+% Define a poorman's (not expandable) \cs{str\string_if\string_eq:nnTF} for a
+% while. This should disappear as soon as this macro is defined in
+% \texttt{ltexpl.dtx} as a copy of \cs{str\string_if\string_eq:nnTF}.
+% \begin{macrocode}
+\def\@expl at str@if at eq@@nnTF#1#2{%
+ \begingroup
+ \edef\x{\detokenize{#1}}%
+ \edef\y{\detokenize{#2}}%
+ \expandafter\endgroup
+ \ifx\x\y
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi}
+% \end{macrocode}
+%
% Now the rollback code.
% \begin{macrocode}
%</2ekernel|latexrelease>
diff --git a/base/testfiles/github-0239.lvt b/base/testfiles/github-0239.lvt
index 975e32e1..c3b38a7f 100644
--- a/base/testfiles/github-0239.lvt
+++ b/base/testfiles/github-0239.lvt
@@ -104,5 +104,19 @@
\expandafter\noexpand\csname\string\cmdd\endcsname{}}%
\expandafter\def\csname\string\cmdd\endcsname[#1]{boo}}
+
+% Test letting other control sequences
+\def\test{\testt\tmp{tmp}}
+
+\test\cmda{\newcount\cmda}
+
+\test\cmdb{\let\cmdb\undefined}
+
+\test\cmdc{\let\cmdc\relax}
+
+\test\cmdd{\let\cmdd\detokenize}
+
+\test\cmde{\def\cmde#1#2#3#4#5#6#7#8#9{}}
+
\end{document}
diff --git a/base/testfiles/github-0239.tlg b/base/testfiles/github-0239.tlg
index 145f0eb9..5bb9e9b2 100644
--- a/base/testfiles/github-0239.tlg
+++ b/base/testfiles/github-0239.tlg
@@ -70,4 +70,25 @@ LaTeX Info: Redefining \cmdc on input line ....
\+ =\relax|
\\+=macro:[#1]->boo|
\\+ =\relax|
+\cmda=\count...
+\tmp=\count179|
+\tmp =\relax|
+\\tmp=\relax|
+\\tmp =\relax|
+\tmp=undefined|
+\tmp =\relax|
+\\tmp=\relax|
+\\tmp =\relax|
+\tmp=\relax|
+\tmp =\relax|
+\\tmp=\relax|
+\\tmp =\relax|
+\tmp=\detokenize|
+\tmp =\relax|
+\\tmp=\relax|
+\\tmp =\relax|
+\tmp=macro:#1#2#3#4#5#6#7#8#9->|
+\tmp =\relax|
+\\tmp=\relax|
+\\tmp =\relax|
(github-0239.aux)
More information about the latex3-commits
mailing list.