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:
@@ -90,7 +90,7 @@
|
||||
|
||||
## 提交门禁(pre-commit)
|
||||
|
||||
- 任一失败即拦截,共 **39 个钩子**(逐个详解 → `docs/代码规范/pre-commit使用说明.md`):通用 5 + `gitlint` + `cppcheck` / `test-cppcheck` + `no-mojibake` + `coding-standard` + 文档三件套 `doc-links` / `task-table` / `mem-numbers` + `id-check`(**编号门禁**,`docs/编号规范.md` §8 八项校验;**已关闸为【增量拦截】**:只拦 `scripts/id_known_backlog.json` 台账之外的新错误级问题,存量按指纹豁免、台账只减不增;另有一根恒生效的线——可判定比例跌破 `id_registry.json` 基线即失败)+ `lv-conf-sync`(两份 `lv_conf.h` 特性子集一致)+ `cubemx-survival` + 主机侧单测 16 个(`-unit-test` 后缀)+ `test-suite-switch` + `registration-check`(双端注册反向校验 + UI 页面描述符表接线,N-23/U4)+ `mem-budget`(RAM 92% 预算门禁,N-27)+ `font-charset`(UI 字符集差集检查,防缺字白框,U4)+ `ui-golden`(UI 像素回归,菜单 8 状态 + 内容页 11 页黄金参考,U4)+ `layer-deps`(**分层方向**:`Drivers/BSP/**` 不得 include `App/**` 的头;存量 6 条基线只减不增,报告 S-1)+ `bsp-err`(**BSP 错误码与超时命名约定**:公开 API 不得拿 `HAL_StatusTypeDef`/`bool` 当错误通道、`*_TIMEOUT` 宏不得取负值、非 void 须写「返回值:」、**返回错误码的函数不得裸丢弃返回值**(须接住或显式 `(void)`;实测编译器与 cppcheck 都不报这类,只有这条会响);约定正文 `Drivers/BSP/bsp_err.h`,存量基线只减不增(2026-10-23 首清点 19 条 → 已还 18;R4 上线又暴露 37 条存量丢弃 → **现 38 条**),报告 S-5)
|
||||
- 任一失败即拦截,共 **39 个钩子**(逐个详解 → `docs/代码规范/pre-commit使用说明.md`):通用 5 + `gitlint` + `cppcheck` / `test-cppcheck` + `no-mojibake` + `coding-standard` + 文档三件套 `doc-links` / `task-table` / `mem-numbers` + `id-check`(**编号门禁**,`docs/编号规范.md` §8 八项校验;**已关闸为【增量拦截】**:只拦 `scripts/id_known_backlog.json` 台账之外的新错误级问题,存量按指纹豁免、台账只减不增;另有一根恒生效的线——可判定比例跌破 `id_registry.json` 基线即失败)+ `lv-conf-sync`(两份 `lv_conf.h` 特性子集一致)+ `cubemx-survival` + 主机侧单测 16 个(`-unit-test` 后缀)+ `test-suite-switch` + `registration-check`(双端注册反向校验 + UI 页面描述符表接线,N-23/U4)+ `mem-budget`(RAM 92% 预算门禁,N-27)+ `font-charset`(UI 字符集差集检查,防缺字白框,U4)+ `ui-golden`(UI 像素回归,菜单 8 状态 + 内容页 11 页黄金参考,U4)+ `layer-deps`(**分层方向**:`Drivers/BSP/**` 不得 include `App/**` 的头;存量 6 条基线只减不增,报告 S-1)+ `bsp-err`(**BSP 错误码与超时命名约定**:公开 API 不得拿 `HAL_StatusTypeDef`/`bool` 当错误通道、`*_TIMEOUT` 宏不得取负值、非 void 须写「返回值:」、**返回错误码的函数不得裸丢弃返回值**(须接住或显式 `(void)`;实测编译器与 cppcheck 都不报这类,只有这条会响);约定正文 `Drivers/BSP/bsp_err.h`,存量基线只减不增(2026-10-23 首清点 19 条 → 已还 18;`consume-result` 上线又暴露 37 条存量丢弃 → **现 38 条**),报告 S-5)
|
||||
- **范围 = 项目代码**:第三方(`Lib/`、`Middlewares/`、CMSIS、HAL、`lftpd`、`dhara`、`MDK-ARM`)排除;`cppcheck`/`coding-standard` 另排除 `test/`,规范检查再排除 CubeMX 生成的 `Src/`/`Inc/`。**`simulator/` 已纳入全部钩子**(2026-10-11)——生成物只靠 `.gitignore` 挡,**不在 `exclude` 里写目录名**(教训见 `docs/代码规范/pre-commit使用说明.md` §5.5)
|
||||
- ⚠ **pre-commit 4.x 已移除 `always: true`**(实测对 `local` 钩子只告警 `Unexpected key(s)` 并跳过)→ 想"总是跑"的钩子**必须让 `files:` 覆盖到所有会触发它的文件**,没有兜底开关
|
||||
- **改写型钩子(`trailing-whitespace` + `end-of-file-fixer`)豁免 CubeMX/Keil 生成文件**(配置里 YAML 锚点 `&cubemx-generated`);⚠ **只读检查不受影响**:`cppcheck` / 乱码 / `cubemx-survival` / `task-table` / `mem-numbers` 仍覆盖 `Src/`、`Inc/`
|
||||
|
||||
@@ -670,7 +670,7 @@ int32_t gd5f2gq5ue_bbt_rebuild(void) {
|
||||
DBG_INFO("Rebuilding BBT from factory scan...");
|
||||
|
||||
/* 1. 关闭 ECC 以读取原始出厂坏块标记(与 gd5f2gq5ue_init 的扫描前提一致)。
|
||||
* 2026-10-23(S-5 R4 上线当天照出来的一处真窟窿):这两行原是**裸调用**——关 ECC 失败就是没关掉,扫描会在
|
||||
* 2026-10-23(bsp-err 的 consume-result 检查上线当天照出来的一处真窟窿):这两行原是**裸调用**——关 ECC 失败就是没关掉,扫描会在
|
||||
* ECC 语义下读 spare,把厂标好块误判成坏块,"重建 BBT"反而制造坏块。 */
|
||||
ret = gd5f_set_feature(0xB0, 0x00);
|
||||
if (ret != GD5F_OK) {
|
||||
@@ -687,7 +687,7 @@ int32_t gd5f2gq5ue_bbt_rebuild(void) {
|
||||
ret = gd5f_bbt_scan();
|
||||
|
||||
/* 3. 重新使能 ECC:无论扫描成败都必须恢复,而且要**验证真的生效**
|
||||
* (2026-10-23,S-5 R4)。原先这两行返回值全丢:SPI 一抖 ECC 就保持关闭,而
|
||||
* (2026-10-23,由 bsp-err 的 consume-result 检查照出)。原先这两行返回值全丢:SPI 一抖 ECC 就保持关闭,而
|
||||
* gd5f_check_ecc() 在 ECC 关闭时恒读"无 ECC 错"——整条链再没有任何信号,设备
|
||||
* 从此在无位翻转保护下读写却"一切正常"。init 路径有 E-10 的"写完回读 B0h 校验
|
||||
* ECC_EN 位",这里补同一套;ECC 没恢复比扫描失败更严重,所以优先返回它。 */
|
||||
|
||||
@@ -116,7 +116,7 @@ typedef char gd5f_dma_threshold_contract_check_t[
|
||||
/* 返回值定义 */
|
||||
#define GD5F_OK 0
|
||||
#define GD5F_ERROR -1
|
||||
#define GD5F_WAIT_EXPIRED -2 /* 旧名 GD5F_BUSY_TIMEOUT;S-5 R2:**返回码不许叫 *_TIMEOUT** */
|
||||
#define GD5F_WAIT_EXPIRED -2 /* 旧名 GD5F_BUSY_TIMEOUT;S-5 的 timeout-name 检查:**返回码不许叫 *_TIMEOUT** */
|
||||
#define GD5F_ECC_ERROR -3
|
||||
#define GD5F_PROGRAM_FAIL -4
|
||||
#define GD5F_ERASE_FAIL -5
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-09
|
||||
* 修改记录:
|
||||
* 2026-10-23 王建锋 补模块头与函数注释(S-5 R3);返回值语义写明"失败类目前
|
||||
* 2026-10-23 王建锋 补模块头与函数注释(S-5 的 return-doc 检查);返回值语义写明"失败类目前
|
||||
* 只进日志、不外传",避免调用方以为能拿到 ECC / 预算耗尽的区别
|
||||
*/
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ uint8_t ui_menu_tab_children(uint8_t node, uint8_t out[], uint8_t max);
|
||||
* 入口参数:node - 节点下标 uint8_t 0 - 表长-1
|
||||
* 返回值:true - 有子项(显示为菜单,带 ▶);false - 无子项(叶子,可进内容页)
|
||||
* 限定条件:纯查询,无副作用;node 越界返回 false
|
||||
* 函数说明:这是**谓词**(bool 合法),不是成败码——S-5 R1 的白名单形态。
|
||||
* 函数说明:这是**谓词**(bool 合法),不是成败码——S-5 的 err-type 检查里白名单放行的形态。
|
||||
*/
|
||||
bool ui_menu_tab_has_children(uint8_t node);
|
||||
|
||||
|
||||
@@ -123,13 +123,13 @@ typedef int bsp_err_t;
|
||||
* (用户确认 2026-10-23):它的调用方要的就是那个形状,模拟器的 Winsock 后端也照同一
|
||||
* 形状实现;归一只到芯片层 ch395f_*。要收口的是"芯片码到 bsp_err_t"这一层,不是把
|
||||
* BSD 形状改成另一套——那只会让 net_* 的调用方在每个判据上多绕一道。
|
||||
* 4. **丢弃返回值必须写 (void),或由调用点接住**——本条已由 bsp-err 的 **R4** 机械化(2026-10-23)。
|
||||
* 4. **丢弃返回值必须写 (void),或由调用点接住**——本条已由 bsp-err 的 **consume-result** 检查机械化(2026-10-23)。
|
||||
* 为什么不能指望工具,两条实测负结果:① ARMCC v5 对 __attribute__((warn_unused_result))
|
||||
* **完全不生效**——凌晨在 rs485_transmit 上做过实验,属性在位、调用点裸调不接返回值,构建
|
||||
* 仍 0 错 0 警告;② **cppcheck 也照不出来**——按本仓自己的 --enable 跑 gd5f2gq5ue.c,对 14 处
|
||||
* 丢弃 HAL_SPI_Transmit/Receive 返回值、以及"未初始化局部量直接进 P_FAIL 判定"**一条不报**
|
||||
* (它假定被调函数会写出参,而失败路径根本不写)。所以"丢弃底层传输的返回值"今天没有任何
|
||||
* 工具会响,只能靠脚本 + 书写约定;R4 上线当天就照出 37 处存量丢弃,其中一处是真窟窿:
|
||||
* 工具会响,只能靠脚本 + 书写约定;consume-result 上线当天就照出 37 处存量丢弃,其中一处是真窟窿:
|
||||
* bbt_rebuild 的 ECC 重开被丢弃(详见 ../测试说明/存储维护与容量恢复.md §4.3)。
|
||||
* 5. 重试由调用方决定:必须有上限、必须喂看门狗、不得跨越就绪屏障盲目等。本头文件
|
||||
* 不提供 retry helper——一个通用 while 重试包装太容易被拿去包住无限等待;每个日志
|
||||
|
||||
@@ -487,33 +487,33 @@ cppcheck 是开源 C/C++ 静态分析工具,**不运行代码**,通过语法
|
||||
| **约定正文在哪** | `Drivers/BSP/bsp_err.h`(**header-only,无 `.c`** → 不占体积、不需双端注册)。
|
||||
`0 = BSP_OK`、负值失败、`BSP_ERR_CAN_RETRY(e)` 把"能不能重试"变成跨模块可判定(这是本契约
|
||||
真正值钱的一条:以前"可重试"只写在个别注释里) |
|
||||
| **四条规则** | **R1** 公开 API 不得用 `HAL_StatusTypeDef` / `bool` 当错误通道(`is_/has_/can_/valid`
|
||||
| **四条检查** | **`err-type`**(错误通道不外泄)公开 API 不得用 `HAL_StatusTypeDef` / `bool` 当错误通道(`is_/has_/can_/valid`
|
||||
这类**谓词**白名单放行——第一版误判了 7 个正当谓词,我们把规则改窄,**不拿基线去洗规则**);
|
||||
**R2** `*_TIMEOUT` 宏不得取负值(名字叫 TIMEOUT 却是返回码 → 一律改 `BSP_ERR_TIMEOUT`);
|
||||
**R3** 非 void 的公开 API 必须有「返回值:」注释(约定要能被读到才谈得上审查;匹配时**忽略空格**,
|
||||
**`timeout-name`**(超时宏不取负值)`*_TIMEOUT` 宏不得取负值(名字叫 TIMEOUT 却是返回码 → 一律改 `BSP_ERR_TIMEOUT`);
|
||||
**`return-doc`**(公开函数必须写返回值)非 void 的公开 API 必须有「返回值:」注释(约定要能被读到才谈得上审查;匹配时**忽略空格**,
|
||||
因为规范 V1.0 允许列对齐写法「返 回 值:」——门禁去规定排版会把合规注释判成违规,实测就有两条因为
|
||||
**函数说明**里顺口出现"返回值"三个字而误判通过);
|
||||
**R4** 返回错误码的函数,调用点必须**接住返回值**或**显式 `(void)` 丢弃**(裸调用即违规)。must-use
|
||||
**`consume-result`**(返回值不得裸丢弃)返回错误码的函数,调用点必须**接住返回值**或**显式 `(void)` 丢弃**(裸调用即违规)。must-use
|
||||
名单**自动取**、不手写:① 返回 `bsp_err_t` 的公开 API;② 返回 `int`/`int32_t` 且文档块出现"错误码 /
|
||||
失败 / BSP_ERR / `_FAIL`"的函数;③ 已知返回 `HAL_StatusTypeDef` 的 HAL 传输/读写族。**名单必须同时
|
||||
覆盖 `.c` 里的 static 定义**——只扫头文件时 `gd5f_set_feature` 这类 static 原语在名单之外,等于只守
|
||||
跨编译单元的边界、看不见编译单元内部的丢弃(实测漏掉后靠人工才发现一处 ECC 丢弃)。豁免两类形状:
|
||||
**谓词**(`is_/has_/can_/should_/need_/valid_`)与 **setter**(`xxx_set_yyy`,实跑误判出 `net_set_errno`
|
||||
八处)——同 R1 的原则:**规则按真实反例收窄,不拿基线洗假阳性**。已知限度:只认**单行整句**的裸调用
|
||||
八处)——同 `err-type` 的原则:**规则按真实反例收窄,不拿基线洗假阳性**。已知限度:只认**单行整句**的裸调用
|
||||
(`foo(...);` 一行写完,行尾注释允许),跨行写的调用暂测不到 |
|
||||
| **范围** | 只扫 `git ls-files` 里 `Drivers/BSP/**/*.h`(对外 API 面);**lftpd 按第三方排除**——
|
||||
它的 `226/425/450/550` 是 FTP 协议码不是内部错误码;**`net_*` BSD 兼容层不纳入**(用户裁定
|
||||
2026-10-23):调用方要的就是"返回字节数 + 每任务 errno 槽"那个形状,模拟器的 Winsock
|
||||
后端也照同一形状实现 |
|
||||
| **增量拦截** | 存量 **38 条**钉 `BASELINE`(首清点 19,已还 18(首清点 19 条:2 个 `*_BUSY_TIMEOUT = -2` + 16 个缺「返回值:」+ 1 个 bool;**现仅剩
|
||||
`bool ui_content_page_open()` 一条**——它需要改签名并处理 3 个调用点,与"还注释"不是一档事)。**R4 是同日新加的一条,上线即暴露 37 条存量丢弃**(`gd5f2gq5ue.c` 29 处:14 处
|
||||
`bool ui_content_page_open()` 一条**——它需要改签名并处理 3 个调用点,与"还注释"不是一档事)。**`consume-result` 是同日新加的一条,上线即暴露 37 条存量丢弃**(`gd5f2gq5ue.c` 29 处:14 处
|
||||
丢弃 `HAL_SPI_*` 状态 + 15 处丢弃自家原语;`NET/net_socket.c` 8、`UI/ui_net_sink.c` 4 处 `net_close`、
|
||||
`RS485/rs485.c` 2、`nand_ftl.c` 1)——这些是**覆盖面扩大而新暴露的历史债**,按增量拦截的老规矩入基线
|
||||
(不算"新增违规"),修一条删一行。**只减不增**、脚本没有 `--write`;修完跑 `--prune` 会点名"这条已消失,
|
||||
请从基线删除" |
|
||||
| **配置** | `files: ^Drivers/BSP/\|^scripts/check_bsp_err\.py$\|^\.pre-commit-config\.yaml$`、
|
||||
`pass_filenames: false`(恒扫全库,要按 git 清单建公开头索引) |
|
||||
| **为什么 R4 只能自己做**(两条实测负结果) | ① `__attribute__((warn_unused_result))` **在 ARMCC v5 上
|
||||
| **为什么 `consume-result` 只能自己做**(两条实测负结果) | ① `__attribute__((warn_unused_result))` **在 ARMCC v5 上
|
||||
不生效**:属性挂上、调用点裸调不接返回值,构建仍 0 错 0 警告。② **cppcheck 也照不出来**:按本仓自己的
|
||||
`--enable=warning,style,performance,portability` 跑 `gd5f2gq5ue.c`,对 14 处丢弃 `HAL_SPI_*` 返回值、以及
|
||||
"未初始化局部量直接进 `P_FAIL` 判定"都**一条不报**(它假定 `gd5f_read_status(&status)` 会写出参,而失败
|
||||
@@ -521,6 +521,14 @@ cppcheck 是开源 C/C++ 静态分析工具,**不运行代码**,通过语法
|
||||
必须写 `(void)`";评审时看到既没 `(void)` 也没接住的调用就是漏判嫌疑 |
|
||||
| **踩坑提醒** | pre-commit 会 **stash 未暂存改动**再跑钩子。所以"改代码 + 同时更新基线"要在
|
||||
一次提交里**把改动 `git add` 了再跑**,否则钩子看到的是没有你改动的树,会假报警 |
|
||||
| **检查项叫什么** | 四项用自描述标签(就是基线键的第二字段,格式 `文件|标签|名字`):
|
||||
`err-type` 错误通道不外泄、`timeout-name` 超时宏不取负值、`return-doc` 公开函数必须写返回值、
|
||||
`consume-result` 返回值不得裸丢弃。**2026-10-23 之前这四项叫 R1/R2/R3/R4,已整体改名**——
|
||||
`R1~R8` 在本仓是"专项风险"的裸形编号(`scripts/id_registry.json` 已登记该族,保护规划与看门狗
|
||||
的风险表都在用)、**带连字符的那一族是审查报告的可靠性 / 内存优化项编号**(见同一裸形四种意思;而编号门禁因为 `docs/编号规范.md` §4.3 已把这些裸形声明为
|
||||
"同号不同义"、走 `collides_with` 白名单,**所以这种撞法不会报**(§1 的"连字符承载语义"
|
||||
一行正是这么写的),等于机器放行、人看不懂(对照:`R1`=err-type、`R2`=timeout-name、
|
||||
| `R3`=return-doc、`R4`=consume-result;已提交的变更记录里出现的老名按冻结历史不回改)。 |
|
||||
| **运行器** | `scripts/check_bsp_err.py`(纯标准库;`--verbose` 列全部命中归类、`--prune` 只报
|
||||
可删基线、`--emit-baseline` 建基线用;退出码 0/1/2) |
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
`net_msg_queue_adopt()` 绑定(创建点不能外移——`osKernelInitialize()` 之前的创建类 API 会杀死启动;**故意不新建第二个队列**:那会白占 CCM 里 8×`net_msg_t`
|
||||
的堆空间,而 CCM 正是当前红线)。**两类从来不算债**:`stm32f4xx_it.c:241-256` 是 CubeMX「External variables」生成块;`:183/195/207/220` 是 `__asm` Handler
|
||||
里的汇编标签引用(ARMCC `__asm` 取不到 C 数据符号)。 | 无(后续由 `layer-deps` 与 `cubemx-survival` 两条门禁守着不回退:新增 `net-msgq-adopt` 存活项) |
|
||||
| 驱动规范 | **S-5 🟡 主体已落地**(2026-10-23:契约 + 门禁 + RS485/SD2506/TPAFE 收编 + GD5F 改名 + dhara 三类码) | 我原先写的"无统一错误码"**不准**,实测是 **六套并存**:0/−1(SD2506、NETCFG、nand_ftl)、自研枚举 `CH395F_STATUS_*`、**芯片寄存器原生码** `CH395F_ERR_*`(与前一套同模块并存)、`HAL_StatusTypeDef`(`rs485.h` 曾直接暴露)、`bool`,外加第三方 dhara 出参 `dhara_error_t` 与 FatFs `FRESULT`。超时侧是**同形两义**:`SD2506_I2C_TIMEOUT_MS` 带单位后缀而 `GD5F_SPI_TIMEOUT 100` 不带(**逐行核过:它也是毫秒**,我先前记成"自旋圈数"是错的)、`GD5F/TPAFE5160_BUSY_TIMEOUT = -2` 其实是**返回码**;`osWaitForever` 与 `HAL_MAX_DELAY` **同为 0xFFFFFFFFU**(值同域不同,跨层转手不报错也不变慢)。真正值钱的不是码名,是"**能不能重试**"以前只写在个别注释里 | `Drivers/BSP/bsp_err.h`(header-only,含 `BSP_ERR_CAN_RETRY`)+ `bsp-err` 钩子(**四条规则**,基线 19 → 1 → **38**:R4 上线又暴露 37 条存量丢弃);已收编 **RS485(HAL 枚举不再外泄)/ SD2506(11 个公共 API,I2C 超时终于归成可重试)/ TPAFE5160(含 E-44 的 FRSTDATA → `BSP_ERR_NO_DEVICE`)**,GD5F 的 `GD5F_BUSY_TIMEOUT` 改名 `GD5F_WAIT_EXPIRED` 消掉同形两义,FTL 坍缩点按 **ECC / 预算耗尽 / 完整性** 三类就地分类并打可读日志(§10.4)。`net_*` BSD 层与 `tpafe5160_snapshot()` 三态按裁定**不纳入**。**已修第一处静默降级**(2026-10-23):`gd5f2gq5ue_bbt_rebuild()` 的 ECC 关闭/恢复不再裸丢弃,并补 E-10 同款**回读
|
||||
| 驱动规范 | **S-5 🟡 主体已落地**(2026-10-23:契约 + 门禁 + RS485/SD2506/TPAFE 收编 + GD5F 改名 + dhara 三类码) | 我原先写的"无统一错误码"**不准**,实测是 **六套并存**:0/−1(SD2506、NETCFG、nand_ftl)、自研枚举 `CH395F_STATUS_*`、**芯片寄存器原生码** `CH395F_ERR_*`(与前一套同模块并存)、`HAL_StatusTypeDef`(`rs485.h` 曾直接暴露)、`bool`,外加第三方 dhara 出参 `dhara_error_t` 与 FatFs `FRESULT`。超时侧是**同形两义**:`SD2506_I2C_TIMEOUT_MS` 带单位后缀而 `GD5F_SPI_TIMEOUT 100` 不带(**逐行核过:它也是毫秒**,我先前记成"自旋圈数"是错的)、`GD5F/TPAFE5160_BUSY_TIMEOUT = -2` 其实是**返回码**;`osWaitForever` 与 `HAL_MAX_DELAY` **同为 0xFFFFFFFFU**(值同域不同,跨层转手不报错也不变慢)。真正值钱的不是码名,是"**能不能重试**"以前只写在个别注释里 | `Drivers/BSP/bsp_err.h`(header-only,含 `BSP_ERR_CAN_RETRY`)+ `bsp-err` 钩子(**四条检查**:`err-type` / `timeout-name` / `return-doc` / `consume-result`;基线 19 → 1 → **38**,其中 `consume-result` 上线又暴露 37 条存量丢弃);已收编 **RS485(HAL 枚举不再外泄)/ SD2506(11 个公共 API,I2C 超时终于归成可重试)/ TPAFE5160(含 E-44 的 FRSTDATA → `BSP_ERR_NO_DEVICE`)**,GD5F 的 `GD5F_BUSY_TIMEOUT` 改名 `GD5F_WAIT_EXPIRED` 消掉同形两义,FTL 坍缩点按 **ECC / 预算耗尽 / 完整性** 三类就地分类并打可读日志(§10.4)。`net_*` BSD 层与 `tpafe5160_snapshot()` 三态按裁定**不纳入**。**已修第一处静默降级**(2026-10-23):`gd5f2gq5ue_bbt_rebuild()` 的 ECC 关闭/恢复不再裸丢弃,并补 E-10 同款**回读
|
||||
B0h 验 `ECC_EN`**——原先那两行的注释自己写着"否则后续 I/O 在无 ECC 下运行",风险却正落在它下面那行。
|
||||
**待还**:GD5F 私有码集整体收编(169 处、含板级套件 48 处,需真机 + 套件回归)、C4 失败类快照(让卷
|
||||
健康探针按类分支)、`bool ui_content_page_open()` 一条(需改签名 + 处理 3 个调用点,与还注释不是一档事)、
|
||||
@@ -330,7 +330,7 @@ W6 簇按 U4 → U1 → U3 → U2 的顺序执行完毕(U2 停在"够用即止
|
||||
| 波次 | 本报告条目(今天状态) | 备注 |
|
||||
|---|---|---|
|
||||
| ~~W3 预算与内存~~ ⏸ | R-9 ✅ / R-2 后半、R-3、R-4、R-6 暂缓 | 暂缓期间无验收动作,观测照常 |
|
||||
| W4 结构债 | N-14 ⏸、F-5 🟡、S-1/S-2/S-4/S-5、N-25 | `--strict` 已默认;S-5 契约/门禁已落地并收编三模块,R4 已把"丢弃返回值"纳入机械检查(基线 19→1→38;剩 GD5F 码集收编、C4 快照、37 条丢弃点、标坏策略) |
|
||||
| W4 结构债 | N-14 ⏸、F-5 🟡、S-1/S-2/S-4/S-5、N-25 | `--strict` 已默认;S-5 契约/门禁已落地并收编三模块,`consume-result` 已把"丢弃返回值"纳入机械检查(基线 19→1→38;剩 GD5F 码集收编、C4 快照、37 条丢弃点、标坏策略) |
|
||||
| W5 验证常态 | 覆盖率、`malloc` 正则、TC 差异 13 处升门禁 | 逢窗口顺手做 |
|
||||
| W6 UI 扩展 | U2 残余、U5 页量 | 随产品需求,不再单列专项 |
|
||||
| W7 仓库决策 | D-1(N-29) | 已决策暂不处理;对外交付前重评 |
|
||||
@@ -389,7 +389,7 @@ W6 簇按 U4 → U1 → U3 → U2 的顺序执行完毕(U2 停在"够用即止
|
||||
| **S-2** | 跨模块裸 `extern` | ✅ **已闭环 2026-10-22**(24 处手写全消;两类本就不算债见 §0.4) | 本文变更记录 2026-10-22 三行;契约见 `App/task/task_handles.h`、`gd5f_spi1_notify_*`、`net_msg_queue_adopt` |
|
||||
| **S-4** | `app_cfg.h` 未接线占位开关 | ✅ **已闭环 2026-10-22**(4 个零消费点宏删除) | `App/app/app_cfg.h` 修改记录 v1.2;口径同步见 `../环境与部署/项目部署环境要求.md` §3.2/§3.5、`../产品需求/产品需求设计文档.md`、`../任务规划/排期详述.md` C5 |
|
||||
| **S-3** | `.ioc` 侧 USART1 配置 | ❌ 在策 | 登记簿 S-3 |
|
||||
| **S-5** | 统一 `bsp_err_t` 错误码与超时命名约定 + **返回值不得裸丢弃** | 🟡 主体已落地(2026-10-23:契约 + `bsp-err` 四规则 + RS485/SD2506/TPAFE 收编 + GD5F 改名 + dhara 三类码 + R4 照出 37 条丢弃 + ECC 回读校验;基线 19 → 1 → 38) | 本文 §0.4、`pre-commit使用说明.md` §2.27、`STM32F4-Base存储架构说明.md` §10.4、`Drivers/BSP/bsp_err.h` |
|
||||
| **S-5** | 统一 `bsp_err_t` 错误码与超时命名约定 + **返回值不得裸丢弃** | 🟡 主体已落地(2026-10-23:契约 + `bsp-err` 四规则 + RS485/SD2506/TPAFE 收编 + GD5F 改名 + dhara 三类码 + `consume-result` 照出 37 条丢弃 + ECC 回读校验;基线 19 → 1 → 38) | 本文 §0.4、`pre-commit使用说明.md` §2.27、`STM32F4-Base存储架构说明.md` §10.4、`Drivers/BSP/bsp_err.h` |
|
||||
| R-1 ~ R-9 | 内存优化项(R-9 已落地、R-5 判定不可行、其余随簇暂缓) | 见 §5.3 | 本文 §5.3、`../内存管理/RAM预算台账.md` |
|
||||
| F-1 / F-2 / F-3 | LVGL 死代码裁剪,省 64,576 B | ✅ 已落地 2026-10-11 | `../内存管理/RAM使用分析与优化方案.md` §2.6.4 |
|
||||
| **F-4 / F-5 / F-6** | Flash 双精度与死代码簇 | ✅/🟡/❌ 见 §5.4 | 本文 §5.4、`App/algo/prot_set.h` 注释 |
|
||||
@@ -448,6 +448,20 @@ admin/admin(SHA-256 `pwd_hash`)→ 该脚本**必然登录失败**;它是
|
||||
| | 数字联动照做:两份 `data/` 快照重跑、`ram_baseline --update/--write`、`check_mem_numbers --write`、FLASH 与
|
||||
任务栈两张配图重算重生成(逐文本复查越界 = 0)、本文 §1.3/§5.1/§5.4 与部署文档 §3.3 同步;§0.4 的 S-2 行按
|
||||
「完成即销项」改写、§9 拆出 S-2 行标 ✅。 |
|
||||
| **2026-10-23** | **术语迁移**:`bsp-err` 的四项检查从 `R1/R2/R3/R4` 改成语义标签 | 用户一句「R4
|
||||
| | 到底是什么」问出来的。这四个号**是我自己造的**,而 `R1~R8` 在本仓是"专项风险"的裸形编号
|
||||
| | (`id_registry.json` 已登记那一族,保护规划 `R1~R8`、看门狗 `R1~R7` 的风险表都在用),`R-2`
|
||||
| | 还是内存优化项——**同一裸形四种意思**。最刺人的是:**编号门禁不会报这种撞法**,因为
|
||||
| | `docs/编号规范.md` §4.3 已把这些裸形声明为"同号不同义"、走 `collides_with` 白名单,于是机器一路
|
||||
| | 放行、人完全看不懂。
|
||||
| | 同一天里我给这批缺陷起的"字母加数字"自造号被门禁当场拦下,而这套代号却一路绿灯——说明白名单
|
||||
| | 挡的是"事故"、不是"可读性"。
|
||||
| | 新名(同时是基线键的第二字段):`err-type` 错误通道不外泄 / `timeout-name` 超时宏不取负值 /
|
||||
| | `return-doc` 公开函数必须写返回值 / `consume-result` 返回值不得裸丢弃。改名**不动任何检查行为**:
|
||||
| | 脚本里规则码与基线键一起换(38 条键的字段同步替换,换完 `--emit-baseline` 复核仍是 38/38/0,
|
||||
| | 中途不跑 `--prune`,否则会把改名误读成"全部还清 + 全部新账");现状类文档(AGENTS、§2.27、
|
||||
| | `bsp_err.h`、本报告 §0.4/§9/附录 A)全部改用新名,**已提交的变更记录行里的老名按冻结历史不回改**,
|
||||
| | 以 `docs/代码规范/pre-commit使用说明.md` §2.27 的对照行为准。 |
|
||||
| **2026-10-23** | **S-5 第三波**:给 `bsp-err` 加 **R4(返回值不得裸丢弃)**,并修掉它照出来的第一处
|
||||
| | ECC 静默降级 | 用户裁定"B 按你说的进行"(先上 R4,再修最小最值的那处)。R4 之所以必须自己做,是两条实测
|
||||
| | 负结果:`warn_unused_result` 在 ARMCC v5 不生效;cppcheck 按本仓 `--enable` 跑同一文件,对 14 处丢弃
|
||||
|
||||
+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