refactor(gate): bsp-err 四项检查改用自描述标签,废掉 R1~R4 这组撞车代号
纯改名,检查行为一个字没动:规则逻辑、阈值、豁免形状全部原样。 改名原因(用户一句「R4 到底是什么」问出来的):R1~R4 是我在 check_bsp_err.py 注释里 自造的序号,而这个裸形在本仓另有含义——R1~R8 已在 scripts/id_registry.json 登记为 "专项风险"的文档内编号(保护规划与看门狗的风险表都在用),带连字符的那一族又是审查 报告的可靠性 / 内存优化项编号(编号规范 §1 的"连字符承载语义"一行正是这么写的)。 **同一个裸形四种意思**。最刺人的一点:编号门禁**不会报**这种撞法,因为编号规范 §4.3 已把这些裸形声明为"同号不同义"、走 collides_with 白名单,校验 4 不计事故——同一天里 我起的另一组自造号被当场拦下、这组代号却一路绿灯,差别不在我做对了什么,而在白名单 挡的是"事故"、不是"可读性"。 新名同时是基线键的第二字段(格式 文件|标签|名字): · err-type 错误通道不外泄(对外接口不拿 HAL_StatusTypeDef / bool 当成败) · timeout-name 超时宏不取负值 · return-doc 公开函数必须写「返回值:」 · consume-result 返回值不得裸丢弃(须接住或显式 (void)) 老名对照:R1=err-type、R2=timeout-name、R3=return-doc、R4=consume-result。 同步面:脚本里的规则码与 38 条基线键的字段**一起换**(中途不跑 --prune,否则改名会被 读成"38 条全还清 + 38 条新账"),换完 --emit-baseline 复核仍是 38/38/0、RC=0。现状类 文本全部换新名:AGENTS.md、pre-commit使用说明.md §2.27(新增"检查项叫什么"一行含老新 对照与撞号说明)、bsp_err.h 边界纪律、报告 §0.4 / §9 / 附录 A,以及代码注释里的 5 处 (gd5f2gq5ue.c/.h、nand_ftl.h、ui_menu_tab.h)。已提交的变更记录行里的老名按"冻结历史 不回改"处理,以 §2.27 对照行为准。ui_menu_tab.h 带 BOM,Edit 又剥掉、已按原样补回。 写说明文字时又被编号门禁拦了一次:我为了举例"老名撞车",在那段话里写了两个编号字面, 被判"未紧邻文档名 / 未登记前缀"共 3 类新账——连批评自造编号的段落本身都在自造编号。 改法是不写号、只描述形态并指向权威条目。 验证:@build **0 错 0 警告**,Program Size 与上一笔**逐字段相同**(Code 213,676、RO 18,860、RW 1,188、ZI 131,500)→ 证明确为注释与文案,故不跑 @test(无指令变化); pre-commit run 全绿 **17 项 Passed**;check_doc_links --all --sections-strict 147 篇 0 问题(中途我自己写的 §4.3 没紧邻文档名,被判成本文自引用,已补全路径);9 个文件字节 卫生 0 异常(UI 头 BOM 仍在、无 CR、无 U+FFFD、均有尾换行)。
This commit is contained in:
+62
-53
@@ -6,19 +6,28 @@
|
||||
而"能不能重试"只写在个别注释里;叫 *_TIMEOUT 的东西里既有真毫秒(单位靠不统一的 _MS 后缀表达)、
|
||||
也有**返回码**。没有机械检查,新代码只会继续按各自旧习惯长。
|
||||
|
||||
三条规则(只看 Drivers/BSP 下的公开头文件 = 对外 API 面;lftpd 按第三方排除):
|
||||
R1 公开 API 不得返回 HAL_StatusTypeDef / bool
|
||||
四条检查(每项一个自描述标签 = 基线键的第二字段,格式是「文件|标签|名字」):
|
||||
err-type 公开 API 不得返回 HAL_StatusTypeDef / bool
|
||||
bool 把"为什么失败"整条丢掉;HAL 枚举把 HAL 焊进调用方的 include 链。
|
||||
R2 *_TIMEOUT 宏不得取负值
|
||||
timeout-name *_TIMEOUT 宏不得取负值
|
||||
名字叫 TIMEOUT 却是返回码,读代码的人会当成时长;超时应返回 BSP_ERR_TIMEOUT。
|
||||
R3 非 void 的公开 API 必须在紧邻注释块里写「返回值:」
|
||||
约定要能被读到,才算约定(也才谈得上审查)。
|
||||
R4 返回错误码的函数,调用点必须**接住返回值**或**显式 (void) 丢弃**
|
||||
return-doc 非 void 的公开 API 必须在紧邻注释块里写「返回值:」
|
||||
约定要能被读到,才算约定(也才谈得上审查)。匹配时忽略空格:规范 V1.0 允许列对齐写法
|
||||
「返 回 值:」,门禁不去规定排版。
|
||||
consume-result 返回错误码的函数,调用点必须**接住返回值**或**显式 (void) 丢弃**
|
||||
名单自动取,不手写:① 返回 bsp_err_t 的公开 API(契约规定它就是错误码);
|
||||
② 返回 int/int32_t 且文档块出现"错误码 / 失败 / BSP_ERR"的函数(覆盖 GD5F 私有码族);
|
||||
③ 已知返回 HAL_StatusTypeDef 的 HAL 传输/读写族。为什么单列:实测 ARMCC v5 不认
|
||||
warn_unused_result、cppcheck 也不报这类丢弃(都在本仓实跑验证过)——**丢弃底层传输
|
||||
的返回值,今天没有任何工具会响**。已知限度:只认单行整句的裸调用,跨行写的暂测不到。
|
||||
③ 已知返回 HAL_StatusTypeDef 的 HAL 传输/读写族;④ 上面 ①② 同一套启发式再扫一遍 .c
|
||||
里的 static 定义(只扫头文件等于只守跨编译单元的边界)。为什么单列:实测 ARMCC v5 不认
|
||||
warn_unused_result、cppcheck 也不报这类丢弃(都在本仓实跑验证过)——**丢弃底层传输的
|
||||
返回值,今天没有任何工具会响**。已知限度:只认单行整句的裸调用(行尾注释允许),跨行写的暂测不到。
|
||||
|
||||
术语迁移(2026-10-23):这四项原先叫 R1/R2/R3/R4,已整体改名。原因是 R1~R8 在本仓是"专项
|
||||
风险"的裸形编号(scripts/id_registry.json 已登记那一族,保护规划与看门狗的风险表都在用)、
|
||||
带连字符的那一族又是审查报告的可靠性 / 内存优化项编号——**同一个裸形四种意思**,而编号门禁
|
||||
因为 docs/编号规范.md §4.3 的同号不同义白名单不会报,
|
||||
等于机器放行、人看不懂。旧名到新名对照:R1=err-type、R2=timeout-name、R3=return-doc、
|
||||
R4=consume-result;已提交的文档与变更记录里出现的老名按"冻结历史不回改"处理,以本对照为准。
|
||||
|
||||
增量拦截(与 layer-deps / id-check 同构):BASELINE 钉住存量,只减不增,没有 --write。
|
||||
修完一条跑 --prune,它会点名"这条已消失,请从 BASELINE 删除"。
|
||||
@@ -38,44 +47,44 @@ EXCLUDE = ("lftpd/",)
|
||||
# 存量基线(2026-10-23 清点):"文件|规则|名字"。修掉一条删一行,不要往里加。
|
||||
BASELINE = frozenset(
|
||||
line.strip() for line in """
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Receive#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Receive#2
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Receive#3
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Transmit#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Transmit#10
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Transmit#11
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Transmit#2
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Transmit#3
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Transmit#4
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Transmit#5
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Transmit#6
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Transmit#7
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Transmit#8
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|HAL_SPI_Transmit#9
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_bbt_save#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_block_erase#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_page_read#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_program_exec#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_program_load#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_read_from_cache#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_read_status#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_read_status#2
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_read_status#3
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_wait_busy#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_write_enable#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_write_enable#2
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_write_enable#3
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|R4|gd5f_write_enable#4
|
||||
Drivers/BSP/GD5F2GQ5UE/nand_ftl.c|R4|gd5f_write_enable#1
|
||||
Drivers/BSP/RS485/rs485.c|R4|rs485_receive_start#1
|
||||
Drivers/BSP/RS485/rs485.c|R4|rs485_receive_start#2
|
||||
Drivers/BSP/UI/ui_content_page.h|R1|ui_content_page_open
|
||||
Drivers/BSP/UI/ui_net_sink.c|R4|net_close#1
|
||||
Drivers/BSP/UI/ui_net_sink.c|R4|net_close#2
|
||||
Drivers/BSP/UI/ui_net_sink.c|R4|net_close#3
|
||||
Drivers/BSP/UI/ui_net_sink.c|R4|net_close#4
|
||||
Drivers/BSP/UI/ui_net_sink.c|R4|net_close#5
|
||||
Drivers/BSP/UI/ui_net_sink.c|R4|net_close#6
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Receive#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Receive#2
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Receive#3
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Transmit#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Transmit#10
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Transmit#11
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Transmit#2
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Transmit#3
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Transmit#4
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Transmit#5
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Transmit#6
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Transmit#7
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Transmit#8
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|HAL_SPI_Transmit#9
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_bbt_save#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_block_erase#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_page_read#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_program_exec#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_program_load#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_read_from_cache#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_read_status#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_read_status#2
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_read_status#3
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_wait_busy#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_write_enable#1
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_write_enable#2
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_write_enable#3
|
||||
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c|consume-result|gd5f_write_enable#4
|
||||
Drivers/BSP/GD5F2GQ5UE/nand_ftl.c|consume-result|gd5f_write_enable#1
|
||||
Drivers/BSP/RS485/rs485.c|consume-result|rs485_receive_start#1
|
||||
Drivers/BSP/RS485/rs485.c|consume-result|rs485_receive_start#2
|
||||
Drivers/BSP/UI/ui_content_page.h|err-type|ui_content_page_open
|
||||
Drivers/BSP/UI/ui_net_sink.c|consume-result|net_close#1
|
||||
Drivers/BSP/UI/ui_net_sink.c|consume-result|net_close#2
|
||||
Drivers/BSP/UI/ui_net_sink.c|consume-result|net_close#3
|
||||
Drivers/BSP/UI/ui_net_sink.c|consume-result|net_close#4
|
||||
Drivers/BSP/UI/ui_net_sink.c|consume-result|net_close#5
|
||||
Drivers/BSP/UI/ui_net_sink.c|consume-result|net_close#6
|
||||
""".splitlines() if line.strip()
|
||||
)
|
||||
|
||||
@@ -127,7 +136,7 @@ HAL_STATUS_RE = re.compile(r"^HAL_(?:SPI|I2C|UART)_(?:Transmit|Receive|TransmitR
|
||||
r"(?:_DMA|_IT)?$|^HAL_I2C_Mem_(?:Read|Write)$")
|
||||
BARE_CALL_RE = re.compile(r"^\s*([A-Za-z_][A-Za-z_0-9]*)\s*\(.*\);"
|
||||
r"(?:\s*/\*.*?\*/)?\s*$") # 行尾注释不影响判定
|
||||
# 两类形状不算"丢弃错误码",也不许塞进基线——同 R1 谓词白名单的理由:**规则该按真实
|
||||
# 两类形状不算"丢弃错误码",也不许塞进基线——同 err-type 谓词白名单的理由:**规则该按真实
|
||||
# 反例收窄,而不是拿基线去洗假阳性**:
|
||||
# · 谓词:返回值是"提问"而不是"办成没有"(is_/has_/can_/should_/need_/valid_);
|
||||
# · setter:形如 xxx_set_yyy(...) 的写入口,它返回的 int 是状态回声而不是调用成败
|
||||
@@ -220,7 +229,7 @@ def static_int_defs(text):
|
||||
return hits
|
||||
|
||||
def scan_r4(must_use):
|
||||
"""R4:Drivers/BSP 下的 .c 里,对 must-use 函数的"裸调用"(不接、也不显式 (void))。"""
|
||||
"""consume-result:Drivers/BSP 下的 .c 里,对 must-use 函数的"裸调用"(不接、也不显式 (void))。"""
|
||||
files = tracked_sources()
|
||||
|
||||
hits = []
|
||||
@@ -246,7 +255,7 @@ def scan_r4(must_use):
|
||||
if ALLOW_BARE_RE.search(name):
|
||||
continue
|
||||
seen[name] = seen.get(name, 0) + 1
|
||||
hits.append((rel, "R4", "%s#%d" % (name, seen[name])))
|
||||
hits.append((rel, "consume-result", "%s#%d" % (name, seen[name])))
|
||||
return hits
|
||||
|
||||
|
||||
@@ -260,7 +269,7 @@ def scan():
|
||||
raise SystemExit(2)
|
||||
lines = text.splitlines()
|
||||
for m in DEFINE_RE.finditer(text):
|
||||
hits.append((rel, "R2", m.group(1)))
|
||||
hits.append((rel, "timeout-name", m.group(1)))
|
||||
for m in DECL_RE.finditer(text):
|
||||
ret = m.group(1).replace("const", "").strip()
|
||||
name = m.group(2)
|
||||
@@ -269,7 +278,7 @@ def scan():
|
||||
continue
|
||||
is_bool = flat.endswith("bool") or flat.endswith("_Bool")
|
||||
if flat.endswith("HAL_StatusTypeDef") or (is_bool and not PREDICATE_RE.search(name)):
|
||||
hits.append((rel, "R1", name))
|
||||
hits.append((rel, "err-type", name))
|
||||
if flat == "void":
|
||||
continue
|
||||
idx = text[:m.start()].count("\n")
|
||||
@@ -277,7 +286,7 @@ def scan():
|
||||
# 要求"必须写成不空格的形式"等于让门禁去规定排版,会把合规注释判成违规。
|
||||
marker = doc_block_before(lines, idx).replace(" ", "").replace("\u3000", "")
|
||||
if "返回值" not in marker:
|
||||
hits.append((rel, "R3", name))
|
||||
hits.append((rel, "return-doc", name))
|
||||
hits.extend(scan_r4(must_use_names()))
|
||||
return hits
|
||||
|
||||
|
||||
Reference in New Issue
Block a user