From 72ef3964ce24457c2f7cd011f4f991ed3a657e46 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Fri, 27 Feb 2026 17:06:04 +0800 Subject: [PATCH] =?UTF-8?q?refactor(pproc):=20=E9=87=8D=E6=9E=84=E9=A2=84?= =?UTF-8?q?=E5=A4=84=E7=90=86=E5=99=A8=E6=9D=A1=E4=BB=B6=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 提取条件判断逻辑到独立函数 scc_pproc_parse_if_need_skip - 使用辅助函数 in_if, in_elif, in_else, in_endif 简化条件处理 - 添加宏 __SCC_PPROC_LOG_PNT 统一错误和警告处理逻辑 - 增加嵌套条件测试用例验证非活动状态下的正确行为 --- libs/pproc/include/scc_pproc.h | 1 + libs/pproc/src/pproc_directive.c | 71 +++++---------- libs/pproc/src/pproc_if.c | 145 ++++++++++++++++++------------- libs/pproc/tests/test_unit.c | 45 ++++++++++ 4 files changed, 152 insertions(+), 110 deletions(-) diff --git a/libs/pproc/include/scc_pproc.h b/libs/pproc/include/scc_pproc.h index a186121..3f41d19 100644 --- a/libs/pproc/include/scc_pproc.h +++ b/libs/pproc/include/scc_pproc.h @@ -68,6 +68,7 @@ static inline void scc_pproc_add_include_path_cstr(scc_pproc_t *pp, void scc_pproc_handle_directive(scc_pproc_t *pp); +cbool scc_pproc_parse_if_need_skip(scc_pproc_t *pp, scc_tok_type_t type); cbool scc_pproc_parse_if_defined(scc_pproc_t *pp, scc_tok_type_t type, const scc_lexer_tok_t *tok); cbool scc_pproc_parse_if_condition(scc_pproc_t *pp, scc_tok_type_t type, diff --git a/libs/pproc/src/pproc_directive.c b/libs/pproc/src/pproc_directive.c index 089922f..627d0a8 100644 --- a/libs/pproc/src/pproc_directive.c +++ b/libs/pproc/src/pproc_directive.c @@ -251,28 +251,7 @@ void scc_pproc_handle_directive(scc_pproc_t *pp) { } scc_tok_type_t type = keywords[ret].tok_type; - if (scc_vec_size(pp->if_stack) != 0) { - scc_pproc_if_t *top = - &scc_vec_at(pp->if_stack, scc_vec_size(pp->if_stack) - 1); - pp->enable = top->active; - } - // 非条件指令,且当前不活动时直接跳过整行 - int is_conditional = 0; - switch (type) { - case SCC_PP_TOK_IFDEF: - case SCC_PP_TOK_IFNDEF: - case SCC_PP_TOK_ELIFDEF: - case SCC_PP_TOK_ELIFNDEF: - case SCC_PP_TOK_ELSE: - case SCC_PP_TOK_ENDIF: - case SCC_PP_TOK_IF: - case SCC_PP_TOK_ELIF: - is_conditional = 1; - break; - default: - break; - } - if (!is_conditional && !pp->enable) { + if (scc_pproc_parse_if_need_skip(pp, type)) { scc_lexer_skip_until_newline(pp->cur_ring); return; } @@ -361,34 +340,30 @@ void scc_pproc_handle_directive(scc_pproc_t *pp) { return; } case SCC_PP_TOK_LINE: + goto ERROR; case SCC_PP_TOK_EMBED: goto ERROR; - case SCC_PP_TOK_ERROR: - scc_lexer_tok_drop(&tok); - while (1) { - ok = scc_lexer_next_non_blank(pp->cur_ring, &tok); - if (tok.type == SCC_TOK_ENDLINE || ok == false) { - return; - } - if (scc_get_tok_subtype(tok.type) == SCC_TOK_SUBTYPE_LITERAL) { - SCC_ERROR(tok.loc, "%s", scc_cstring_as_cstr(&tok.lexeme)); - } - scc_lexer_tok_drop(&tok); - } - return; - case SCC_PP_TOK_WARNING: - scc_lexer_tok_drop(&tok); - while (1) { - ok = scc_lexer_next_non_blank(pp->cur_ring, &tok); - if (tok.type == SCC_TOK_ENDLINE || ok == false) { - return; - } - if (scc_get_tok_subtype(tok.type) == SCC_TOK_SUBTYPE_LITERAL) { - SCC_WARN(tok.loc, "%s", scc_cstring_as_cstr(&tok.lexeme)); - } - scc_lexer_tok_drop(&tok); - } - return; +#define __SCC_PPROC_LOG_PNT(func_name) \ + do { \ + scc_lexer_tok_drop(&tok); \ + while (1) { \ + ok = scc_lexer_next_non_blank(pp->cur_ring, &tok); \ + if (tok.type == SCC_TOK_ENDLINE || ok == false) { \ + return; \ + } \ + if (scc_get_tok_subtype(tok.type) == SCC_TOK_SUBTYPE_LITERAL) { \ + func_name(tok.loc, "%s", scc_cstring_as_cstr(&tok.lexeme)); \ + } \ + scc_lexer_tok_drop(&tok); \ + } \ + return; \ + } while (0) + case SCC_PP_TOK_ERROR: { + __SCC_PPROC_LOG_PNT(SCC_ERROR); + } + case SCC_PP_TOK_WARNING: { + __SCC_PPROC_LOG_PNT(SCC_WARN); + } case SCC_PP_TOK_PRAGMA: SCC_WARN(tok.loc, "pragma ignored"); scc_lexer_skip_until_newline(pp->cur_ring); diff --git a/libs/pproc/src/pproc_if.c b/libs/pproc/src/pproc_if.c index f408580..7cf19a4 100644 --- a/libs/pproc/src/pproc_if.c +++ b/libs/pproc/src/pproc_if.c @@ -1,6 +1,83 @@ #include #include +cbool scc_pproc_parse_if_need_skip(scc_pproc_t *pp, scc_tok_type_t type) { + if (pp->enable == true) { + return false; + } + + if (scc_vec_size(pp->if_stack) == 0) { + return false; + } + + scc_pproc_if_t *top = + &scc_vec_at(pp->if_stack, scc_vec_size(pp->if_stack) - 1); + pp->enable = top->active; + + if ((type == SCC_PP_TOK_IF || type == SCC_PP_TOK_IFDEF || + type == SCC_PP_TOK_IFNDEF || type == SCC_PP_TOK_ELIFDEF || + type == SCC_PP_TOK_ELIFNDEF || type == SCC_PP_TOK_ELSE || + type == SCC_PP_TOK_ELIF || type == SCC_PP_TOK_ENDIF)) { + return false; + } + return true; +} + +static void in_if(scc_pproc_t *pp, cbool enable) { + scc_pproc_if_t new_if; + + if (pp->enable) { + new_if.active = enable; + new_if.found_true = enable; + new_if.seen_else = false; + pp->enable = enable; + } else { + // to disable hole stack if we are in disabled state + new_if.active = false; + new_if.found_true = true; + new_if.seen_else = false; + } + scc_vec_push(pp->if_stack, new_if); +} + +static void in_elif(scc_pproc_t *pp, scc_pproc_if_t *top, cbool enable) { + if (top->found_true) { + top->active = false; + } else { + if (enable) { + top->found_true = true; + } + top->active = enable; + } + pp->enable = top->active; +} + +static void in_else(scc_pproc_t *pp, scc_pproc_if_t *top) { + if (top->found_true) { + top->active = false; + } else { + top->active = true; + top->found_true = true; + } + + top->seen_else = true; + pp->enable = top->active; +} + +static void in_endif(scc_pproc_t *pp) { + if (scc_vec_size(pp->if_stack) == 0) { + LOG_ERROR("#endif without #if"); + } else { + scc_vec_pop(pp->if_stack); + } + if (scc_vec_size(pp->if_stack) == 0) { + pp->enable = true; + } else { + pp->enable = + scc_vec_at(pp->if_stack, scc_vec_size(pp->if_stack) - 1).active; + } +} + cbool scc_pproc_parse_if_defined(scc_pproc_t *pp, scc_tok_type_t type, const scc_lexer_tok_t *tok) { int defined = 0; @@ -12,14 +89,7 @@ cbool scc_pproc_parse_if_defined(scc_pproc_t *pp, scc_tok_type_t type, case SCC_PP_TOK_IFDEF: case SCC_PP_TOK_IFNDEF: { cbool condition = (type == SCC_PP_TOK_IFDEF) ? defined : !defined; - - scc_pproc_if_t new_if; - new_if.found_true = condition; - new_if.seen_else = 0; - new_if.active = pp->enable ? condition : 0; - scc_vec_push(pp->if_stack, new_if); - - pp->enable = new_if.active; + in_if(pp, condition); break; } case SCC_PP_TOK_ELIFDEF: @@ -36,21 +106,7 @@ cbool scc_pproc_parse_if_defined(scc_pproc_t *pp, scc_tok_type_t type, } int condition = (type == SCC_PP_TOK_ELIFDEF) ? defined : !defined; - - if (top->found_true) { - // 前面已有真分支,本 elif 不激活 - top->active = 0; - } else { - if (condition) { - top->active = 1; - top->found_true = 1; - } else { - top->active = 0; - } - } - - // seen_else 仍为 0 - pp->enable = top->active; + in_elif(pp, top, condition); break; } case SCC_PP_TOK_ELSE: { @@ -64,31 +120,11 @@ cbool scc_pproc_parse_if_defined(scc_pproc_t *pp, scc_tok_type_t type, LOG_ERROR("multiple #else"); return false; } - - if (top->found_true) { - top->active = 0; - } else { - top->active = 1; - top->found_true = 1; - } - - top->seen_else = 1; - - pp->enable = top->active; + in_else(pp, top); break; } case SCC_PP_TOK_ENDIF: { - if (scc_vec_size(pp->if_stack) == 0) { - LOG_ERROR("#endif without #if"); - } else { - scc_vec_pop(pp->if_stack); - } - if (scc_vec_size(pp->if_stack) == 0) { - pp->enable = 1; - } else { - pp->enable = - scc_vec_at(pp->if_stack, scc_vec_size(pp->if_stack) - 1).active; - } + in_endif(pp); break; } default: { @@ -129,12 +165,7 @@ cbool scc_pproc_parse_if_condition(scc_pproc_t *pp, scc_tok_type_t type, // 根据指令类型更新条件编译栈 switch (type) { case SCC_PP_TOK_IF: { - scc_pproc_if_t new_if; - new_if.found_true = condition; - new_if.seen_else = 0; - new_if.active = pp->enable ? condition : 0; - scc_vec_push(pp->if_stack, new_if); - pp->enable = new_if.active; + in_if(pp, condition); break; } case SCC_PP_TOK_ELIF: { @@ -149,17 +180,7 @@ cbool scc_pproc_parse_if_condition(scc_pproc_t *pp, scc_tok_type_t type, LOG_ERROR("#elif after #else"); return false; } - if (top->found_true) { - top->active = 0; - } else { - if (condition) { - top->active = 1; - top->found_true = 1; - } else { - top->active = 0; - } - } - pp->enable = top->active; + in_elif(pp, top, condition); break; } default: diff --git a/libs/pproc/tests/test_unit.c b/libs/pproc/tests/test_unit.c index 9b65430..2ee9976 100644 --- a/libs/pproc/tests/test_unit.c +++ b/libs/pproc/tests/test_unit.c @@ -417,6 +417,50 @@ static void test_simple_number_conditional_if(void) { " foo\n bar\n"); } +static void test_conditional_nested_inactive(void) { + TEST_CASE("nested conditional when outer inactive"); + CHECK_PP_OUTPUT_EXACT("#ifdef NOT_DEFINED\n" + "#if 1\n" + "should not appear\n" + "#endif\n" + "#endif\n" + "after\n", + "after\n"); + CHECK_PP_OUTPUT_EXACT("#define A\n" + "#ifdef A\n" + " #ifdef B\n" + " B defined\n" + " #else\n" + " B not defined\n" + " #endif\n" + "#else\n" + " A not defined\n" + "#endif\n", + " B not defined\n"); + CHECK_PP_OUTPUT_EXACT("#undef A\n" + "#ifdef A\n" + " #ifdef B\n" + " B defined\n" + " #else\n" + " B not defined\n" + " #endif\n" + "#else\n" + " A not defined\n" + "#endif\n", + " A not defined\n"); + CHECK_PP_OUTPUT_EXACT("#if 0\n" + "#ifdef X\n" + "X defined\n" + "#elifdef Y\n" + "Y defined\n" + "#else\n" + "none\n" + "#endif\n" + "#endif\n" + "end\n", + "end\n"); +} + static void test_variadic_macros(void) { TEST_CASE("variadic macros with __VA_ARGS__"); @@ -560,6 +604,7 @@ TEST_LIST = { TEST_LIST_CASE(hard_test_define_func_macros), TEST_LIST_CASE(test_conditional_ifdef), TEST_LIST_CASE(test_simple_number_conditional_if), + TEST_LIST_CASE(test_conditional_nested_inactive), TEST_LIST_CASE(test_variadic_macros), TEST_LIST_CASE(test_gnu_comma_variadic_deletion),