[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.