merge: task/cal-scale-doc 合入 v2-on-ui

任务 cal-scale(1 个提交)经 task-worktree 回收:
- feat(采集标定): 卡1 TPAFE 量程口径定死 + 卡3 cfg_file 补 CFG_VAL_INT
This commit is contained in:
2026-10-25 03:15:22 +08:00
5 changed files with 240 additions and 10 deletions
+120 -5
View File
@@ -7,7 +7,7 @@
* **内存虚拟文件系统**桩实现(cfg_store_* 系列强符号)。
*
* 为什么要主机侧单测(而不是只用板端套件):
* 1. 配置引擎的核心是"文本 <-> 结构"的纯变换(INI 段/键解析、四种值类型
* 1. 配置引擎的核心是"文本 <-> 结构"的纯变换(INI 段/键解析、五种值类型
* 编解码、外科手术式保存、超长守卫),与硬件无关;板端套件无法穷举
* 畸形输入,更无法在毫秒内构造"超长文件 / 写失败 / 堆分配失败"。
* 2. 主机侧可**精确注入**故障:文件缺失、读取失败、写失败、分配失败——
@@ -21,6 +21,12 @@
* TC-CONFIG-003 IP4 正常与非法(段数不足、>255、前导非数字、多余后缀)
* TC-CONFIG-004 MAC 三种分隔符 + 大小写 + 非法
* TC-CONFIG-005 STR 正常 / 超长拒绝 / 边界(恰好放下)
* TC-CONFIG-006 INT 合法解码:0 / -1 / INT32_MIN / INT32_MAX / 各宽度边界 /
* 前导 + / 前导 0(数据可信卡 3:负零点偏移可落盘)
* TC-CONFIG-007 INT 非法拒绝:空 / 非数字 / 带后缀 / 越界(含 strtol 饱和带,
* 即超 INT32 但钳位后恰落界内的文本)/ 坏 len
* TC-CONFIG-008 INT 编码带负号输出 + 注册校验(INT len=3 拒绝)+
* [sys] 段 load/save/load 全链往返一致(出厂模板带负号默认)
* —— INI 解析(s_split_line / s_match_section / s_key_value / s_parse)——
* TC-CONFIG-010 注释(; 与 #)与空行忽略
* TC-CONFIG-011 CRLF / LF 混排
@@ -229,16 +235,23 @@ static const cfg_key_def_t s_net_keys[] = {
{ "name", CFG_VAL_STR, offsetof(sec_net_t, name), 12u },
};
/* 段 B:[sys],无回调,用于验证多段与超长字段拒绝 */
/* 段 B:[sys],无回调,用于验证多段、超长字段拒绝与 INT 有符号往返(卡 3)。
* 字段按自然对齐排布:u32@0 / i8@4 / i16@6 / i32@8,offset 用 offsetof 取真值 */
typedef struct {
uint32_t baud; /* offset 0 len 4 UINT */
uint32_t baud; /* offset 0 len 4 UINT */
int8_t ofs8; /* offset 4 len 1 INT */
int16_t ofs16; /* offset 6 len 2 INT(负默认:模板须带负号写出) */
int32_t ofs32; /* offset 8 len 4 INT(默认 INT32_MIN:极值往返) */
} sec_sys_t;
static sec_sys_t s_sys_data;
static const sec_sys_t s_sys_def = { 115200u };
static const sec_sys_t s_sys_def = { 115200u, -5, -300, (-2147483647 - 1) };
static const cfg_key_def_t s_sys_keys[] = {
{ "baud", CFG_VAL_UINT, offsetof(sec_sys_t, baud), 4u },
{ "baud", CFG_VAL_UINT, offsetof(sec_sys_t, baud), 4u },
{ "ofs8", CFG_VAL_INT, offsetof(sec_sys_t, ofs8), 1u },
{ "ofs16", CFG_VAL_INT, offsetof(sec_sys_t, ofs16), 2u },
{ "ofs32", CFG_VAL_INT, offsetof(sec_sys_t, ofs32), 4u },
};
/* ===================== 辅助 ===================== */
@@ -417,6 +430,103 @@ static void tc_str(void) {
CHECK(s_decode_str(d, 8u, "") == 0 && d[0] == '\0', "empty string ok");
}
/* TC-CONFIG-006/007:INT 解码(数据可信卡 3——有符号零点偏移) */
static void tc_int_decode(void) {
uint8_t d[4];
printf("[TC-CONFIG-006] INT decode valid\n");
CHECK(s_decode_int(d, 4u, "0") == 0 && d[0] == 0u && d[3] == 0u, "int32 zero");
CHECK(s_decode_int(d, 4u, "-1") == 0 && d[0] == 0xFFu && d[1] == 0xFFu &&
d[2] == 0xFFu && d[3] == 0xFFu, "-1 = four FF bytes (two's complement)");
CHECK(s_decode_int(d, 4u, "-2147483648") == 0 && d[0] == 0x00u &&
d[1] == 0x00u && d[2] == 0x00u && d[3] == 0x80u, "INT32_MIN accepted");
CHECK(s_decode_int(d, 4u, "2147483647") == 0 && d[0] == 0xFFu &&
d[1] == 0xFFu && d[2] == 0xFFu && d[3] == 0x7Fu, "INT32_MAX accepted");
CHECK(s_decode_int(d, 1u, "-128") == 0 && d[0] == 0x80u, "int8 -128");
CHECK(s_decode_int(d, 1u, "127") == 0 && d[0] == 0x7Fu, "int8 +127");
CHECK(s_decode_int(d, 2u, "-32768") == 0 && d[0] == 0x00u && d[1] == 0x80u,
"int16 -32768");
CHECK(s_decode_int(d, 2u, "32767") == 0 && d[0] == 0xFFu && d[1] == 0x7Fu,
"int16 +32767");
CHECK(s_decode_int(d, 4u, "+42") == 0 && d[0] == 42u, "leading + accepted");
CHECK(s_decode_int(d, 4u, "-0") == 0 && d[0] == 0u && d[3] == 0u, "-0 decodes 0");
CHECK(s_decode_int(d, 4u, "00012") == 0 && d[0] == 12u && d[3] == 0u,
"leading zeros accepted");
printf("[TC-CONFIG-007] INT decode invalid rejected\n");
CHECK(s_decode_int(d, 4u, "") == -1, "empty rejected");
CHECK(s_decode_int(d, 4u, "abc") == -1, "non-numeric rejected");
CHECK(s_decode_int(d, 4u, "12x") == -1, "trailing garbage rejected");
CHECK(s_decode_int(d, 4u, "-") == -1, "bare sign rejected");
CHECK(s_decode_int(d, 4u, "1.5") == -1, "decimal point rejected");
CHECK(s_decode_int(d, 4u, "0x10") == -1, "hex text rejected");
CHECK(s_decode_int(d, 1u, "-129") == -1, "int8 -129 rejected");
CHECK(s_decode_int(d, 1u, "128") == -1, "int8 128 rejected");
CHECK(s_decode_int(d, 2u, "-32769") == -1, "int16 -32769 rejected");
CHECK(s_decode_int(d, 2u, "32768") == -1, "int16 32768 rejected");
CHECK(s_decode_int(d, 4u, "2147483648") == -1, "INT32_MAX + 1 rejected (ERANGE)");
CHECK(s_decode_int(d, 4u, "-2147483649") == -1, "INT32_MIN - 1 rejected (ERANGE)");
CHECK(s_decode_int(d, 4u, "99999999999") == -1, "huge magnitude rejected (ERANGE)");
CHECK(s_decode_int(d, 4u, "-99999999999") == -1, "huge negative rejected (ERANGE)");
CHECK(s_decode_int(d, 3u, "1") == -1, "invalid len 3 rejected");
}
/* TC-CONFIG-008:INT 编码带负号 + [sys] 段 load/save/load 全链往返 */
static void tc_int_encode(void) {
char buf[24];
uint8_t field[4];
static const cfg_key_def_t k32 = { "ofs32", CFG_VAL_INT, 0u, 4u };
static const cfg_key_def_t k8 = { "ofs8", CFG_VAL_INT, 0u, 1u };
printf("[TC-CONFIG-008] INT encode (sign in text)\n");
field[0] = 0xFFu; field[1] = 0xFFu; field[2] = 0xFFu; field[3] = 0xFFu;
CHECK(s_encode(&k32, field, buf, sizeof(buf)) > 0 && strcmp(buf, "-1") == 0,
"FFFFFFFF encodes -1");
field[0] = 0x00u; field[1] = 0x00u; field[2] = 0x00u; field[3] = 0x80u;
CHECK(s_encode(&k32, field, buf, sizeof(buf)) > 0 &&
strcmp(buf, "-2147483648") == 0, "INT32_MIN bytes encode with sign");
field[0] = 0xFFu; field[1] = 0xFFu; field[2] = 0xFFu; field[3] = 0x7Fu;
CHECK(s_encode(&k32, field, buf, sizeof(buf)) > 0 &&
strcmp(buf, "2147483647") == 0, "INT32_MAX bytes encode");
field[0] = 0x80u;
CHECK(s_encode(&k8, field, buf, sizeof(buf)) > 0 && strcmp(buf, "-128") == 0,
"int8 0x80 encodes -128");
field[0] = 0x7Fu;
CHECK(s_encode(&k8, field, buf, sizeof(buf)) > 0 && strcmp(buf, "127") == 0,
"int8 0x7F encodes 127");
printf("[TC-CONFIG-008] INT section roundtrip (load -> save -> load)\n");
vfs_reset();
register_std();
CHECK(cfg_file_load() == 0, "load creates template");
CHECK(strstr(vfs_get(), "ofs32=-2147483648") != NULL,
"template INT32_MIN default written with sign");
CHECK(strstr(vfs_get(), "ofs8=-5") != NULL, "template int8 default -5");
s_sys_data.ofs32 = -123456;
s_sys_data.ofs16 = -2;
s_sys_data.ofs8 = -128;
CHECK(cfg_file_save() == 0, "save with negatives");
CHECK(strstr(vfs_get(), "ofs32=-123456") != NULL, "negative saved with sign");
CHECK(strstr(vfs_get(), "ofs8=-128") != NULL, "int8 -128 saved");
s_sys_data.ofs32 = 1;
s_sys_data.ofs16 = 1;
s_sys_data.ofs8 = 1;
CHECK(cfg_file_load() == 0, "reload ok");
CHECK(s_sys_data.ofs32 == -123456 && s_sys_data.ofs16 == -2 &&
s_sys_data.ofs8 == -128, "INT values roundtrip identical");
/* 越界文本 = 该键拒绝、留工厂默认并留痕;同段其余键不受牵连 */
vfs_reset();
register_std();
vfs_put("[sys]\r\nbaud=9600\r\nofs32=2147483648\r\nofs8=-129\r\nofs16=-300\r\n");
CHECK(cfg_file_load() == 0, "load with out-of-range INT keys");
CHECK(s_sys_data.ofs32 == s_sys_def.ofs32, "out-of-range ofs32 keeps default");
CHECK(s_sys_data.ofs8 == s_sys_def.ofs8, "out-of-range ofs8 keeps default");
CHECK(s_sys_data.ofs16 == -300, "valid ofs16 in same section parsed");
CHECK(s_sys_data.baud == 9600u, "UINT key beside INT parsed");
}
/* TC-CONFIG-010~015:INI 解析 */
static void tc_parse(void) {
printf("[TC-CONFIG-010..015] INI parsing via load\n");
@@ -522,6 +632,7 @@ static void tc_register(void) {
{
cfg_section_reg_t r;
static const cfg_key_def_t bad_uint[] = { { "k", CFG_VAL_UINT, 0u, 3u } };
static const cfg_key_def_t bad_int[] = { { "k", CFG_VAL_INT, 0u, 3u } };
static const cfg_key_def_t bad_mac[] = { { "k", CFG_VAL_MAC, 0u, 4u } };
static const cfg_key_def_t bad_str[] = { { "k", CFG_VAL_STR, 0u, 80u } };
static const cfg_key_def_t zero_len[] = { { "k", CFG_VAL_UINT, 0u, 0u } };
@@ -536,6 +647,8 @@ static void tc_register(void) {
r.p_keys = bad_uint;
CHECK(cfg_file_register(&r) == -1, "UINT len=3 rejected");
r.p_keys = bad_int;
CHECK(cfg_file_register(&r) == -1, "INT len=3 rejected");
r.p_keys = bad_mac;
CHECK(cfg_file_register(&r) == -1, "MAC len=4 rejected");
r.p_keys = bad_str;
@@ -859,6 +972,8 @@ int main(void) {
printf("=== Config File Tests ===\n");
tc_uint();
tc_int_decode();
tc_int_encode();
tc_ip4();
tc_mac();
tc_str();