[latex3-commits] [l3svn] r6908 - For now, allow all-m functions to be used in csnames

noreply at latex-project.org noreply at latex-project.org
Mon Feb 13 15:18:33 CET 2017


Author: bruno
Date: 2017-02-13 15:18:32 +0100 (Mon, 13 Feb 2017)
New Revision: 6908

Modified:
   trunk/l3packages/xparse/testfiles/xparse001.lvt
   trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg
   trunk/l3packages/xparse/testfiles/xparse001.tlg
   trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg
   trunk/l3packages/xparse/xparse.dtx
Log:
For now, allow all-m functions to be used in csnames

People use protected xparse functions to store text or
other simple commands and expect them to correctly expand
in csname constructions (or under f-expansion).  This
undocumented behaviour was broken by recent commits and is
now temporarily restored.


Modified: trunk/l3packages/xparse/testfiles/xparse001.lvt
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse001.lvt	2017-02-13 02:01:18 UTC (rev 6907)
+++ trunk/l3packages/xparse/testfiles/xparse001.lvt	2017-02-13 14:18:32 UTC (rev 6908)
@@ -1,5 +1,5 @@
 %
-% Copyright (C) 2009-2012,2014-2016 LaTeX3 Project
+% Copyright (C) 2009-2012,2014-2017 LaTeX3 Project
 %
 
 \documentclass{minimal}
@@ -352,5 +352,15 @@
     \box_show:N \l_tmpa_box
   }
 
+\TEST { (ab)using~xparse~commands~in~csnames }
+  {
+    \DeclareDocumentCommand { \foo } { m m } { #1-#2 }
+    \TYPE { \exp_not:c { test- \foo { abc } { def } } }
+    \DeclareDocumentCommand { \foo } { u. } { test-#1 }
+    \TYPE { \exp_not:c { test- \foo abc . } }
+    \DeclareDocumentCommand { \foo } { D... } { test-#1 }
+    \TYPE { \exp_not:c { test- \foo .... } }
+  }
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \END

Modified: trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg	2017-02-13 02:01:18 UTC (rev 6907)
+++ trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg	2017-02-13 14:18:32 UTC (rev 6908)
@@ -35,7 +35,8 @@
 | You have used \RenewDocumentCommand with a command that was never defined.
 | A new command '\foo' will be created.
 |...............................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {}\foo  \foo code {}{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {}\foo  \foo code
+\foo defaults {}.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:->First definition.
@@ -50,8 +51,8 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {m}\foo  \foo code
-{\__xparse_grab_m_1:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code
+\foo defaults {\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1->(#1).
@@ -62,8 +63,8 @@
 . 
 . Redefining command \foo with sig. 'mm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mm}\foo  \foo code
-{\__xparse_grab_m_2:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mm}\foo  \foo code
+\foo defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -74,8 +75,9 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmm}\foo  \foo code
-{\__xparse_grab_m_3:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3->(#1)(#2)(#3).
@@ -86,8 +88,10 @@
 . 
 . Redefining command \foo with sig. 'mmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmm}\foo  \foo code
-{\__xparse_grab_m_4:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4->(#1)(#2)(#3)(#4).
@@ -98,8 +102,10 @@
 . 
 . Redefining command \foo with sig. 'mmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmm}\foo  \foo code
-{\__xparse_grab_m_5:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5->(#1)(#2)(#3)(#4)(#5).
@@ -110,8 +116,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmm}\foo  \foo code
-{\__xparse_grab_m_6:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5#6->(#1)(#2)(#3)(#4)(#5)(#6).
@@ -122,8 +131,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmm}\foo  \foo code
-{\__xparse_grab_m_7:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -135,8 +147,12 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmmm}\foo  \foo code
-{\__xparse_grab_m_8:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmm}\foo 
+\foo code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -148,8 +164,12 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmmmm}\foo  \foo code
-{\__xparse_grab_m_9:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmmm}\foo 
+\foo code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -1166,3 +1186,37 @@
 <argument> \l_tmpa_box 
 l. ...  }
 ============================================================
+============================================================
+TEST 19: (ab)using xparse commands in csnames
+============================================================
+.................................................
+. LaTeX info: "xparse/define-command"
+. 
+. Defining command \foo with sig. 'mm' on line ....
+.................................................
+\test-abc-def 
+.................................................
+. LaTeX info: "xparse/redefine-command"
+. 
+. Redefining command \foo with sig. 'u.' on line ....
+.................................................
+! Missing \endcsname inserted.
+<to be read again> 
+                   \xparse function is not expandable 
+l. ...  }
+The control sequence marked <to be read again> should
+not appear between \csname and \endcsname.
+\test- \xparse function is not expandable \__xparse_start_aux:nNNnnn {u.}\foo code {\__xparse_grab_u:w {.}}{}{}abc.\cs_end: 
+.................................................
+. LaTeX info: "xparse/redefine-command"
+. 
+. Redefining command \foo with sig. 'D...' on line ....
+.................................................
+! Missing \endcsname inserted.
+<to be read again> 
+                   \xparse function is not expandable 
+l. ...  }
+The control sequence marked <to be read again> should
+not appear between \csname and \endcsname.
+\test- \xparse function is not expandable \__xparse_start_aux:nNNnnn {D...}\foo code {\__xparse_grab_D_trailing:w ..}{{..}}{}....\cs_end: 
+============================================================

Modified: trunk/l3packages/xparse/testfiles/xparse001.tlg
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse001.tlg	2017-02-13 02:01:18 UTC (rev 6907)
+++ trunk/l3packages/xparse/testfiles/xparse001.tlg	2017-02-13 14:18:32 UTC (rev 6908)
@@ -35,7 +35,8 @@
 | You have used \RenewDocumentCommand with a command that was never defined.
 | A new command '\foo' will be created.
 |...............................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {}\foo  \foo code {}{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {}\foo  \foo code
+\foo defaults {}.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:->First definition.
@@ -50,8 +51,8 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {m}\foo  \foo code
-{\__xparse_grab_m_1:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code
+\foo defaults {\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1->(#1).
@@ -62,8 +63,8 @@
 . 
 . Redefining command \foo with sig. 'mm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mm}\foo  \foo code
-{\__xparse_grab_m_2:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mm}\foo  \foo code
+\foo defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -74,8 +75,9 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmm}\foo  \foo code
-{\__xparse_grab_m_3:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3->(#1)(#2)(#3).
@@ -86,8 +88,10 @@
 . 
 . Redefining command \foo with sig. 'mmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmm}\foo  \foo code
-{\__xparse_grab_m_4:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4->(#1)(#2)(#3)(#4).
@@ -98,8 +102,10 @@
 . 
 . Redefining command \foo with sig. 'mmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmm}\foo  \foo code
-{\__xparse_grab_m_5:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5->(#1)(#2)(#3)(#4)(#5).
@@ -110,8 +116,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmm}\foo  \foo code
-{\__xparse_grab_m_6:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5#6->(#1)(#2)(#3)(#4)(#5)(#6).
@@ -122,8 +131,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmm}\foo  \foo code
-{\__xparse_grab_m_7:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -135,8 +147,12 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmmm}\foo  \foo code
-{\__xparse_grab_m_8:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmm}\foo 
+\foo code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -148,8 +164,12 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmmmm}\foo  \foo code
-{\__xparse_grab_m_9:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmmm}\foo 
+\foo code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -1162,3 +1182,37 @@
 <argument> \l_tmpa_box 
 l. ...  }
 ============================================================
+============================================================
+TEST 19: (ab)using xparse commands in csnames
+============================================================
+.................................................
+. LaTeX info: "xparse/define-command"
+. 
+. Defining command \foo with sig. 'mm' on line ....
+.................................................
+\test-abc-def 
+.................................................
+. LaTeX info: "xparse/redefine-command"
+. 
+. Redefining command \foo with sig. 'u.' on line ....
+.................................................
+! Missing \endcsname inserted.
+<to be read again> 
+                   \xparse function is not expandable 
+l. ...  }
+The control sequence marked <to be read again> should
+not appear between \csname and \endcsname.
+\test- \xparse function is not expandable \__xparse_start_aux:nNNnnn {u.}\foo code {\__xparse_grab_u:w {.}}{}{}abc.\cs_end: 
+.................................................
+. LaTeX info: "xparse/redefine-command"
+. 
+. Redefining command \foo with sig. 'D...' on line ....
+.................................................
+! Missing \endcsname inserted.
+<to be read again> 
+                   \xparse function is not expandable 
+l. ...  }
+The control sequence marked <to be read again> should
+not appear between \csname and \endcsname.
+\test- \xparse function is not expandable \__xparse_start_aux:nNNnnn {D...}\foo code {\__xparse_grab_D_trailing:w ..}{{..}}{}....\cs_end: 
+============================================================

Modified: trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg	2017-02-13 02:01:18 UTC (rev 6907)
+++ trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg	2017-02-13 14:18:32 UTC (rev 6908)
@@ -35,7 +35,8 @@
 | You have used \RenewDocumentCommand with a command that was never defined.
 | A new command '\foo' will be created.
 |...............................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {}\foo  \foo code {}{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {}\foo  \foo code
+\foo defaults {}.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:->First definition.
@@ -50,8 +51,8 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {m}\foo  \foo code
-{\__xparse_grab_m_1:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code
+\foo defaults {\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1->(#1).
@@ -62,8 +63,8 @@
 . 
 . Redefining command \foo with sig. 'mm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mm}\foo  \foo code
-{\__xparse_grab_m_2:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mm}\foo  \foo code
+\foo defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2->(#1)(#2).
@@ -74,8 +75,9 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmm}\foo  \foo code
-{\__xparse_grab_m_3:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3->(#1)(#2)(#3).
@@ -86,8 +88,10 @@
 . 
 . Redefining command \foo with sig. 'mmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmm}\foo  \foo code
-{\__xparse_grab_m_4:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4->(#1)(#2)(#3)(#4).
@@ -98,8 +102,10 @@
 . 
 . Redefining command \foo with sig. 'mmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmm}\foo  \foo code
-{\__xparse_grab_m_5:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5->(#1)(#2)(#3)(#4)(#5).
@@ -110,8 +116,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmm}\foo  \foo code
-{\__xparse_grab_m_6:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long macro:#1#2#3#4#5#6->(#1)(#2)(#3)(#4)(#5)(#6).
@@ -122,8 +131,11 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmm}\foo  \foo code
-{\__xparse_grab_m_7:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmm}\foo  \foo
+code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -135,8 +147,12 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmmm}\foo  \foo code
-{\__xparse_grab_m_8:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmm}\foo 
+\foo code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -148,8 +164,12 @@
 . 
 . Redefining command \foo with sig. 'mmmmmmmmm' on line ....
 .................................................
-> \foo=\protected macro:->\__xparse_start:nNNnnn {mmmmmmmmm}\foo  \foo code
-{\__xparse_grab_m_9:w }{}{}.
+> \foo=\protected macro:->\__xparse_start_expandable:nNNNn {mmmmmmmmm}\foo 
+\foo code \foo defaults {\__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\protected\long
@@ -1166,3 +1186,37 @@
 <argument> \l_tmpa_box 
 l. ...  }
 ============================================================
+============================================================
+TEST 19: (ab)using xparse commands in csnames
+============================================================
+.................................................
+. LaTeX info: "xparse/define-command"
+. 
+. Defining command \foo with sig. 'mm' on line ....
+.................................................
+\test-abc-def 
+.................................................
+. LaTeX info: "xparse/redefine-command"
+. 
+. Redefining command \foo with sig. 'u.' on line ....
+.................................................
+! Missing \endcsname inserted.
+<to be read again> 
+                   \xparse function is not expandable 
+l. ...  }
+The control sequence marked <to be read again> should
+not appear between \csname and \endcsname.
+\test- \xparse function is not expandable \__xparse_start_aux:nNNnnn {u.}\foo code {\__xparse_grab_u:w {.}}{}{}abc.\cs_end: 
+.................................................
+. LaTeX info: "xparse/redefine-command"
+. 
+. Redefining command \foo with sig. 'D...' on line ....
+.................................................
+! Missing \endcsname inserted.
+<to be read again> 
+                   \xparse function is not expandable 
+l. ...  }
+The control sequence marked <to be read again> should
+not appear between \csname and \endcsname.
+\test- \xparse function is not expandable \__xparse_start_aux:nNNnnn {D...}\foo code {\__xparse_grab_D_trailing:w ..}{{..}}{}....\cs_end: 
+============================================================

Modified: trunk/l3packages/xparse/xparse.dtx
===================================================================
--- trunk/l3packages/xparse/xparse.dtx	2017-02-13 02:01:18 UTC (rev 6907)
+++ trunk/l3packages/xparse/xparse.dtx	2017-02-13 14:18:32 UTC (rev 6908)
@@ -995,6 +995,16 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}{\l_@@_simple_args_bool}
+%   When defining a non-expandable command, indicates whether the
+%   arguments can all safely be grabbed by expandable grabbers.  This is
+%   to support abuses of \pkg{xparse} that use protected functions
+%   inside csname constructions.  Better name welcome.
+%    \begin{macrocode}
+\bool_new:N \l_@@_simple_args_bool
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{variable}{\l_@@_tmp_prop, \l_@@_tmpa_tl, \l_@@_tmpb_tl}
 % \begin{macro}{\@@_tmp:w}
 %   Scratch space.
@@ -1077,13 +1087,17 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_declare_cmd_code:Nnn
   {
-    \bool_if:NTF \l_@@_expandable_bool
+    \bool_if:nTF
+      {
+        \l_@@_expandable_bool ||
+        \l_@@_simple_args_bool && ! \l_@@_environment_bool
+      }
       { \@@_declare_cmd_code_expandable:Nnn }
       { \@@_declare_cmd_code_aux:Nnn }
    }
 %    \end{macrocode}
-%   Standard functions call
-%   \cs{@@_start:nNNnnn}, which receives an auxiliary used for
+%   Standard functions call \cs{@@_start:nNNnnn}, which receives the
+%   argument specification, an auxiliary used for
 %   grabbing arguments, an auxiliary containing the code, and then the
 %   signature, default arguments, and processors.
 %    \begin{macrocode}
@@ -1109,11 +1123,21 @@
           }
       }
   }
+%    \end{macrocode}
+%   Expandable functions and functions whose arguments can be grabbed
+%   expandably call \cs{@@_start_expandable:nNNNn}, which receives the
+%   argument specification, auxiliaries used for grabbing arguments, for
+%   the code, and for default arguments, and finally the signature.
+%   Non-expandable functions that take this branch should nevertheless
+%   be protected, as well as their \texttt{code} function.  They will
+%   only be expanded in contexts such as constructing a csname.
+%    \begin{macrocode}
 \cs_new_protected:Npn \@@_declare_cmd_code_expandable:Nnn #1#2#3
   {
-    \cs_generate_from_arg_count:cNnn
+    \exp_args:Ncc \cs_generate_from_arg_count:NNnn
       { \l_@@_function_tl \c_space_tl code }
-      \cs_set:Npn \l_@@_current_arg_int {#3}
+      { cs_set \bool_if:NF \l_@@_expandable_bool { _protected } :Npn }
+      \l_@@_current_arg_int {#3}
     \bool_if:NT \l_@@_defaults_bool
       {
         \use:x
@@ -1124,7 +1148,8 @@
               { \exp_not:o \l_@@_defaults_tl }
           }
       }
-    \cs_set_nopar:Npx #1
+    \bool_if:NTF \l_@@_expandable_bool
+      { \cs_set_nopar:Npx } { \cs_set_protected_nopar:Npx } #1
       {
         \exp_not:N \@@_start_expandable:nNNNn
           { \exp_not:n {#2} }
@@ -1205,13 +1230,21 @@
 % \subsection{Structure of \pkg{xparse} commands}
 %
 % \begin{macro}{\@@_start:nNNnnn}
+% \begin{macro}[aux]{\@@_start_aux:nNNnnn}
 %   This sets up a few variables to minimize the boilerplate code
 %   included in all \pkg{xparse}-defined commands.  It then runs the
 %   grabbers~|#4|.  Again, the argument specification |#1| is only for
-%   diagnostics.
+%   diagnostics.  The control sequence equal to \cs{scan_stop:} protects
+%   against \texttt{f}-expansion and ensures errors are more reasonable
+%   when an \pkg{xparse} command is placed in a csname.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_start:nNNnnn #1#2#3#4#5#6
+\cs_new_protected:Npx \@@_start:nNNnnn
   {
+    \exp_not:c { xparse~function~is~not~expandable }
+    \exp_not:N \@@_start_aux:nNNnnn
+  }
+\cs_new_protected:Npn \@@_start_aux:nNNnnn #1#2#3#4#5#6
+  {
     \tl_clear:N \l_@@_args_tl
     \tl_set:Nn \l_@@_fn_tl {#2}
     \tl_set:Nn \l_@@_fn_code_tl {#3}
@@ -1221,6 +1254,7 @@
   }
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\@@_run_code:}
 %   After arguments are grabbed, this function is responsible for
@@ -1509,6 +1543,7 @@
     \int_zero:N \l_@@_current_arg_int
     \tl_clear:N \l_@@_last_delimiters_tl
     \tl_clear:N \l_@@_arg_spec_tl
+    \bool_set_true:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n #1
       \q_recursion_tail \q_recursion_tail \q_recursion_tail \q_recursion_stop
     \int_compare:nNnT \l_@@_current_arg_int > 9
@@ -1612,6 +1647,7 @@
       }
     \tl_put_right:Nn \l_@@_arg_spec_tl { > {#1} }
     \int_decr:N \l_@@_current_arg_int
+    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n {#2}
   }
 \cs_new_protected:cpn { @@_normalize_type_+:w } #1
@@ -1619,6 +1655,7 @@
     \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn }
     \tl_put_right:Nn \l_@@_arg_spec_tl { + }
     \int_decr:N \l_@@_current_arg_int
+    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n {#1}
   }
 %    \end{macrocode}
@@ -1649,6 +1686,7 @@
     \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn }
     \tl_put_right:Nn \l_@@_arg_spec_tl { D #1 #2 {#3} }
     \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
+    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n
   }
 \cs_new_protected:Npn \@@_normalize_type_E:w #1#2
@@ -1661,6 +1699,7 @@
       { \@@_bad_arg_spec:wn }
     \tl_put_right:Nn \l_@@_arg_spec_tl { E {#1} {#2} }
     \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
+    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n
   }
 \cs_new_protected:Npn \@@_normalize_E_unique_check:w #1#2 \q_stop
@@ -1677,6 +1716,7 @@
     \@@_normalize_error_if_expandable:N G
     \tl_put_right:Nn \l_@@_arg_spec_tl { G {#1} }
     \tl_put_right:Nn \l_@@_last_delimiters_tl { { } }
+    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n
   }
 \cs_new_protected:Npn \@@_normalize_type_t:w #1
@@ -1685,6 +1725,7 @@
     \quark_if_recursion_tail_stop_do:Nn #1 { \@@_bad_arg_spec:wn }
     \tl_put_right:Nn \l_@@_arg_spec_tl { t #1 }
     \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
+    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n
   }
 %    \end{macrocode}
@@ -1714,6 +1755,7 @@
     \tl_put_right:Nn \l_@@_arg_spec_tl { l }
     \int_incr:N \l_@@_mandatory_args_int
     \tl_clear:N \l_@@_last_delimiters_tl
+    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n
   }
 \cs_new_protected:Npn \@@_normalize_type_m:w
@@ -1733,6 +1775,7 @@
     \tl_put_right:Nn \l_@@_arg_spec_tl { R #1 #2 {#3} }
     \int_incr:N \l_@@_mandatory_args_int
     \tl_clear:N \l_@@_last_delimiters_tl
+    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n
   }
 \cs_new_protected:Npn \@@_normalize_type_u:w #1
@@ -1742,6 +1785,7 @@
     \tl_put_right:Nn \l_@@_arg_spec_tl { u {#1} }
     \int_incr:N \l_@@_mandatory_args_int
     \tl_clear:N \l_@@_last_delimiters_tl
+    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n
   }
 \cs_new_protected:Npn \@@_normalize_type_v:w
@@ -1750,6 +1794,7 @@
     \tl_put_right:Nn \l_@@_arg_spec_tl { v }
     \int_incr:N \l_@@_mandatory_args_int
     \tl_clear:N \l_@@_last_delimiters_tl
+    \bool_set_false:N \l_@@_simple_args_bool
     \@@_normalize_arg_spec_loop:n
   }
 %    \end{macrocode}
@@ -1869,7 +1914,12 @@
     \use:c
       {
          @@_add
-         \bool_if:NT \l_@@_expandable_bool { _expandable }
+         \bool_if:nT
+           {
+             \l_@@_expandable_bool ||
+             \l_@@_simple_args_bool && ! \l_@@_environment_bool
+           }
+           { _expandable }
          _type_  \token_to_str:N #1 :w
       }
   }



More information about the latex3-commits mailing list