@@ -34,6 +34,7 @@ private slots:
3434 void test_crash_case_249 ();
3535 void test_crash_case_289 ();
3636 void test_crash_case_1294_3 ();
37+ void test_has_macro_cycle ();
3738};
3839
3940void
@@ -81,5 +82,35 @@ TestParseTex::test_crash_case_1294_3 () {
8182 check_crash_case (" 1294_3.tex" );
8283}
8384
85+ void
86+ TestParseTex::test_has_macro_cycle () {
87+ // 1. 无参自递归: \def\foo{\foo} -> <assign|foo|<macro|<foo>>>
88+ tree self_rec=
89+ tuple (compound (" assign" , " foo" , compound (" macro" , compound (" foo" ))));
90+ QVERIFY (has_macro_cycle (self_rec));
91+
92+ // 2. 带参自递归: \def\foo#1{\foo{#1}} -> <assign|foo|<macro|x|<foo|<arg|x>>>>
93+ tree param_rec= tuple (compound (
94+ " assign" , " foo" ,
95+ compound (" macro" , " x" , compound (" foo" , compound (" arg" , " x" )))));
96+ QVERIFY (has_macro_cycle (param_rec));
97+
98+ // 3. 相互递归: foo 调 bar, bar 调 foo
99+ tree mutual_rec=
100+ tuple (compound (" assign" , " foo" , compound (" macro" , compound (" bar" ))),
101+ compound (" assign" , " bar" , compound (" macro" , compound (" foo" ))));
102+ QVERIFY (has_macro_cycle (mutual_rec));
103+
104+ // 4. 非递归正常宏: foo 调内置命令,无环
105+ tree normal_macro= tuple (compound (
106+ " assign" , " foo" ,
107+ compound (" macro" , " x" , compound (" bold" , compound (" arg" , " x" )))));
108+ QVERIFY (!has_macro_cycle (normal_macro));
109+
110+ // 5. 普通文档无宏定义
111+ tree no_macro= compound (" document" , " Hello world" );
112+ QVERIFY (!has_macro_cycle (no_macro));
113+ }
114+
84115QTEST_MAIN (TestParseTex)
85116#include " parsetex_test.moc"
0 commit comments