From e6232226383e6c2fa218b935292a418bb50712f7 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Sun, 5 Jul 2026 12:40:59 +0800 Subject: [PATCH] fix: result of #if macro expr is wrong when has recursive trinary '?:' --- lex/scf_macro_expr.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/lex/scf_macro_expr.c b/lex/scf_macro_expr.c index a1a3aa1..e5ae60d 100644 --- a/lex/scf_macro_expr.c +++ b/lex/scf_macro_expr.c @@ -6,6 +6,9 @@ typedef struct { scf_lex_word_t** pp; scf_lex_word_t* error; + int n_q_masks; + int n_colons; + int n_lps; int n_rps; } scf_macro_ctx_t; @@ -144,7 +147,7 @@ static int __macro_binary_##name(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_w } \ \ w0->data.i64 = w0->data.i64 op w1->data.i64; \ - scf_logi("op: %s, result: %ld, line: %d, pos: %d\n", w_op->text->data, w0->data.i64, w_op->line, w_op->pos); \ + scf_logi("op: %s, result: %ld, line: %d, pos: %d\n\n", w_op->text->data, w0->data.i64, w_op->line, w_op->pos); \ \ *operand = w0; \ return 0; \ @@ -274,6 +277,8 @@ static int __macro_operator_cond(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_w return -EINVAL; } + ctx->n_q_masks++; + scf_lex_word_t* cond = *operand; scf_lex_word_t* _true = NULL; scf_lex_word_t* _false = NULL; @@ -316,6 +321,7 @@ static int __macro_operator_cond(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_w break; case SCF_LEX_WORD_COLON: + ctx->n_colons++; break; default: scf_loge("'%s' is NOT ':' after '?', file: %s, line: %d, pos: %d\n", @@ -324,17 +330,31 @@ static int __macro_operator_cond(scf_lex_t* lex, scf_macro_ctx_t* ctx, scf_lex_w break; }; - ret = __macro_unary_operand(lex, ctx, &_false); - if (ret < 0) - return ret; + while (1) { + _false = NULL; + + ret = __macro_unary_operand(lex, ctx, &_false); + if (ret < 0) + return ret; + + if (SCF_LEX_WORD_COLON != _false->type) + break; + + if (++ctx->n_colons > ctx->n_q_masks) { + + scf_loge("too many '%s' after '?', file: %s, line: %d, pos: %d\n", + _false->text->data, _false->file->data, _false->line, _false->pos); + return -EINVAL; + } + } if (cond->data.u64) *operand = _true; else *operand = _false; - scf_logi("op: %s, flag: %d, result: %ld, line: %d, pos: %d\n", - w_op->text->data, !!cond->data.u64, (*operand)->data.i64, w_op->line, w_op->pos); + scf_logi("op: %s, flag: %d, result: %ld, true: %ld, false: %ld, line: %d, pos: %d\n\n", + w_op->text->data, !!cond->data.u64, (*operand)->data.i64, _true->data.i64, _false->data.i64, w_op->line, w_op->pos); return 0; } @@ -512,7 +532,7 @@ int __macro_if_expr(scf_lex_t* lex) scf_lex_word_t* operand = NULL; scf_lex_word_t* w = NULL; scf_lex_word_t* h = NULL; - scf_macro_ctx_t ctx = {&h, 0, 0}; + scf_macro_ctx_t ctx = {&h, 0, 0, 0, 0}; int ret = 0; -- 2.25.1