feat(pproc): 实现预处理器宏连接操作符功能
- 修改concatenate_tokens函数以支持null参数检查,避免空指针访问 - 添加concact辅助函数来处理##连接操作的逻辑 - 重构expand_function_macro中##操作符的实现,支持GNU扩展特性 - 实现对可变参数宏中##操作的正确处理,包括逗号删除逻辑 - 改进object宏中的##连接操作处理 - 添加多个单元测试用例验证连接操作符的正确性 - 修复字符串连接时的边界条件处理 refactor(tests): 重命名预处理器单元测试文件 - 将test_unit.c重命名为test_pproc_unit.c以更明确标识测试范围
This commit is contained in:
@@ -116,6 +116,9 @@ static void test_define_concat_operator(void) {
|
||||
"helloworld\n");
|
||||
CHECK_PP_OUTPUT_EXACT("#define JOIN(pre,suf) pre ## suf\nJOIN(var, 123)\n",
|
||||
"var123\n");
|
||||
CHECK_PP_OUTPUT_EXACT("#define CONCAT a ## b ## c\nCONCAT\n", "abc\n");
|
||||
CHECK_PP_OUTPUT_EXACT(
|
||||
"#define CONCAT(a, b, c) a ## b ## c\nCONCAT(x, y, z)\n", "xyz\n");
|
||||
}
|
||||
|
||||
static void test_define_nested_macros(void) {
|
||||
@@ -131,7 +134,7 @@ static void test_define_nested_macros(void) {
|
||||
CHECK_PP_OUTPUT_EXACT("#undef A\n", "");
|
||||
|
||||
CHECK_PP_OUTPUT_EXACT(" # define A 1\nA", "1");
|
||||
// CHECK_PP_OUTPUT_EXACT(" # define A 1 \nA", "1"); // TODO
|
||||
// CHECK_PP_OUTPUT_EXACT(" # define A 1 \nA", "1");
|
||||
|
||||
CHECK_PP_OUTPUT_EXACT("#define CONCAT(str) __scc_##str\nCONCAT(int)",
|
||||
"__scc_int");
|
||||
@@ -140,6 +143,9 @@ static void test_define_nested_macros(void) {
|
||||
|
||||
CHECK_PP_OUTPUT_EXACT("#define CONCAT(str) __scc_ ## str\nCONCAT(int)",
|
||||
"__scc_int");
|
||||
CHECK_PP_OUTPUT_EXACT(
|
||||
"#define CONCAT(a, b) a ## b\nCONCAT(x, )\nCONCAT(,y)\nCONCAT(,)\n",
|
||||
"x\ny\n\n");
|
||||
|
||||
// TEST_CASE("TODO"); /*FALSE*/
|
||||
// CHECK_PP_OUTPUT_EXACT("#define str(x) # x\n"
|
||||
@@ -496,7 +502,7 @@ static void test_gnu_comma_variadic_deletion(void) {
|
||||
// 可变参数非空,逗号保留
|
||||
CHECK_PP_OUTPUT_EXACT("#define FOO(fmt, ...) printf(fmt, ## __VA_ARGS__)\n"
|
||||
"FOO(\"%d\", 42)\n",
|
||||
"printf(\"%d\",42)\n");
|
||||
"printf(\"%d\", 42)\n");
|
||||
// 带空白变体
|
||||
CHECK_PP_OUTPUT_EXACT("#define FOO(fmt,...) printf(fmt,##__VA_ARGS__)\n"
|
||||
"FOO(\"%d\", 42)\n",
|
||||
@@ -515,45 +521,42 @@ static void test_c99_docs(void) {
|
||||
// 6.10.3.5 Scope of macrodefinitions
|
||||
TEST_CASE("EXAMPLE 3 To illustrate the rules for redefinition and "
|
||||
"reexamination, the sequence");
|
||||
/*
|
||||
CHECK_PP_OUTPUT_EXACT(
|
||||
"#define x 3\n"
|
||||
"#define f(a) f(x * (a))\n"
|
||||
"#undef x\n"
|
||||
"#define x 2\n"
|
||||
"#define g f\n"
|
||||
"#define z z[0]\n"
|
||||
"#define h g(~\n"
|
||||
"#define m(a) a(w)\n"
|
||||
"#define w 0,1\n"
|
||||
"#define t(a) a\n"
|
||||
"#define p() int\n"
|
||||
"#define q(x) x\n"
|
||||
"#define r(x,y) x ## y\n"
|
||||
"#define str(x) # x\n"
|
||||
"f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);\n"
|
||||
"g(x+(3,4)-w) | h 5) & m\n"
|
||||
" (f)^m(m);\n"
|
||||
"p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };\n"
|
||||
"char c[2][6] = { str(hello), str() };\n",
|
||||
"f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);\n"
|
||||
"f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);\n"
|
||||
"int i[] = { 1, 23, 4, 5, };\n"
|
||||
"char c[2][6] = { \"hello\", \"\" };\n");
|
||||
*/
|
||||
"#define x 3\n"
|
||||
"#define f(a) f(x * (a))\n"
|
||||
"#undef x\n"
|
||||
"#define x 2\n"
|
||||
"#define g f\n"
|
||||
"#define z z[0]\n"
|
||||
"#define h g(~\n"
|
||||
"#define m(a) a(w)\n"
|
||||
"#define w 0,1\n"
|
||||
"#define t(a) a\n"
|
||||
"#define p() int\n"
|
||||
"#define q(x) x\n"
|
||||
"#define r(x,y) x ## y\n"
|
||||
"#define str(x) # x\n"
|
||||
"f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);\n"
|
||||
"g(x+(3,4)-w) | h 5) & m\n"
|
||||
" (f)^m(m);\n"
|
||||
"p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };\n"
|
||||
"char c[2][6] = { str(hello), str() };\n",
|
||||
"f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);\n"
|
||||
"f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);\n"
|
||||
"int i[] = { 1, 23, 4, 5, };\n"
|
||||
"char c[2][6] = { \"hello\", \"\" };\n");
|
||||
|
||||
TEST_CASE("EXAMPLE 4 To illustrate the rules for creating character string "
|
||||
"literals and concatenating tokens, the sequence");
|
||||
|
||||
TEST_CASE("EXAMPLE 5 To illustrate the rules for placemarker preprocessing "
|
||||
"tokens, the sequence");
|
||||
/*
|
||||
CHECK_PP_OUTPUT_EXACT("#define t(x,y,z) x ## y ## z\n"
|
||||
"int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),\n"
|
||||
"\t\t\tt(10,,), t(,11,), t(,,12), t(,,) };\n",
|
||||
|
||||
"int j[] = { 123, 45, 67, 89,\n"
|
||||
"\t\t\t10, 11, 12, };\n");
|
||||
*/
|
||||
"\t\t\t10, 11, 12, };\n");
|
||||
|
||||
TEST_CASE("EXAMPLE 6 To demonstrate the redefinition rules, the following "
|
||||
"sequence is valid.");
|
||||
Reference in New Issue
Block a user