with one click
repository-encoding-normalizer
// 仅当用户明确要求规范化源码仓库文件编码、保留历史 GBK 中文运行期字节语义、处理 armcc/armclang 嵌入式 C/C++ 项目中 UTF-8 与 GBK 混合源码时使用;若用户没有明确要求,禁止使用。
// 仅当用户明确要求规范化源码仓库文件编码、保留历史 GBK 中文运行期字节语义、处理 armcc/armclang 嵌入式 C/C++ 项目中 UTF-8 与 GBK 混合源码时使用;若用户没有明确要求,禁止使用。
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | repository-encoding-normalizer |
| description | 仅当用户明确要求规范化源码仓库文件编码、保留历史 GBK 中文运行期字节语义、处理 armcc/armclang 嵌入式 C/C++ 项目中 UTF-8 与 GBK 混合源码时使用;若用户没有明确要求,禁止使用。 |
先记录原始编码,再做转换;先确认运行期字节语义,再改源码文本形态。不要根据“转换后的编码”判断中文能否原地保留,必须根据文件转换前的原始编码判断。
对于原本不是 UTF-8 的中文源码,关键语义通常是 GBK 运行期文本字节,不是 Unicode 文本。迁移时不能把运行期 GBK 字符串误变成 UTF-8 字符串。
用于含混合编码的源码仓库。常见目标包括 C/C++/H/ASM/Make/SCons/CMake/脚本/配置/文本资源,但必须按具体仓库确认文件类型。
不要写死设备、板卡、芯片、产品或绝对路径。用户给出的路径示例默认只表示“形态参考”,除非用户明确指定它就是目标路径。 仅在用户明确要求执行编码规范化时使用;如果用户没有明确要求,禁止调用本 skill。
先根据工具链选择转换格式,再用最小构建验证。
| 工具链/场景 | 推荐宏头文件存储方式 | 原因 |
|---|---|---|
armcc / ARM Compiler 5 | 转换为 UTF-8 with BOM | 保持 BOM 以适配旧工具链对文本头文件的稳定读取。 |
armclang / ARM Compiler 6 | 转换为 UTF-8 | 避免不必要的 BOM 影响,按 UTF-8 统一保存。 |
| 非 ARM 或未知编译器 | 默认 UTF-8 with BOM | 跨文件编码最稳妥。 |
默认先识别工具链,再决定目标编码:armclang 输出 UTF-8,armcc 输出 UTF-8 with BOM,其他场景默认 UTF-8 with BOM。
确认:
优先遵循仓库既有约定。没有约定时,把宏头文件放在拥有这些字符串的模块附近,例如:
<module>/misc/<module>_text.h
<module>/inc/<module>_text.h
<module>/<feature>_text.h
用户示例 .../misc/prt_gbk_text.h 只表示“模块内集中维护历史 GBK 运行期文本”的一种形态,不代表固定绝对路径。
对每个目标文本文件记录:
优先使用确定性工具。对 GBK/GB2312/Big5 等历史编码要使用多种信号交叉确认。编码识别不确定时,停止并询问用户,不要猜测转换。
工具脚本: 本 skill 附带 scan_encoding.py,可自动扫描仓库并生成编码审计报告:
python scan_encoding.py --root . --out encoding_audit.md
该脚本会输出每个含中文文件的路径、原始编码、中文出现在注释/字符串/代码区的统计,以及详细行级清单。将审计报告作为后续决策依据。
只迁移代码会使用的中文,例如:
不要因为文件原始编码不是 UTF-8 就迁移中文注释。中文注释可以随文件一起转换为 UTF-8 with BOM 后原地保留,除非仓库策略另有要求。
根据字符串归属创建一个或多个头文件。除非仓库已有统一大文本表风格,否则不要创建全仓库级“垃圾桶”式头文件。
最大兼容方案:宏头文件使用 UTF-8 with BOM 保存,迁移出来的 GBK 运行期字符串用字节转义表达,并在宏后保留中文注释方便维护。
头文件模板:
#ifndef MODULE_TEXT_H
#define MODULE_TEXT_H
/*
* 中文文本集中定义
* 来源:由历史非 UTF-8/GBK 编码源码中的运行期中文字符串迁移而来。
* 说明:本文件使用 UTF-8 with BOM 保存;宏值使用 GBK 字节转义,保持运行期字节不变。
*/
/* ===== 打印状态文本 ===== */
#define MODULE_TEXT_PRINT_READY "\xB4\xF2\xD3\xA1\xBB\xFA\xBE\xCD\xD0\xF7" /* 打印机就绪 */
#define MODULE_TEXT_PRINT_ERROR "\xB4\xF2\xD3\xA1\xBB\xFA\xB4\xED\xCE\xF3" /* 打印机错误 */
/* ===== 菜单显示文本 ===== */
#define MODULE_TEXT_MENU_SETTING "\xC9\xE8\xD6\xC3" /* 设置 */
#endif /* MODULE_TEXT_H */
默认不要使用 GBK 编码、明文中文宏值的头文件。只有在仓库明确要求,并且编译器专项验证能证明无 warning/error 时,才允许这种例外。
命名规则:
对每个被迁移的中文运行期文本:
示例:
/* before:原始文件是 GBK,运行期需要 GBK 字节 */
show_msg("打印机错误");
/* after */
#include "module_text.h"
show_msg(MODULE_TEXT_PRINT_ERROR);
完成字面量迁移决策后:
armclang 转换为 UTF-8,armcc 转换为 UTF-8 with BOM;工具脚本: 本 skill 附带 normalize_encoding.py,可根据审计结果批量执行编码转换和宏迁移:
# 示例:armcc 项目,转换指定文件为 UTF-8 with BOM,同时创建宏头文件并替换字面量
python normalize_encoding.py \
--root . \
--compiler armcc \
--files "src/tp.c,src/esc_p.c,src/includes.h" \
--no-bom-files "src/inc_config.mk" \
--macro-header "src/tp_text.h" \
--macro-name "TP_TEXT_TEST_SAMPLE" \
--macro-value "PT562\\xB2\\xE2\\xCA\\xD4\\xD1\\xF9\\xD5\\xC5\\n" \
--macro-comment "PT562测试样张" \
--source-file "src/tp.c" \
--old-string '"PT562测试样张\\n"' \
--include-marker '#include "includes.h"'
注意: normalize_encoding.py 为模板脚本,执行前必须根据 scan_encoding.py 的审计结果调整 --files、--macro-* 和 --source-file 参数。Makefile 类文件务必放入 --no-bom-files,避免 Make 工具解析失败。
必须验证:
建议报告格式:
编码规范化报告
- 处理范围:
- 转换为 UTF-8 with BOM 的文件:
- 原始 UTF-8 且保留原地中文的文件:
- 已迁移 GBK 运行期文本的原始非 UTF-8 文件:
- 新建/更新的宏头文件:
- 宏头文件存储策略:UTF-8 with BOM + GBK 字节转义 / 已验证的 GBK 明文头文件例外
- 跳过文件与原因:
- 验证命令与结果:
- 风险/未覆盖项:
遇到以下情况必须暂停并询问用户:
| 错误 | 正确做法 |
|---|---|
| 根据转换后的编码判断中文能否保留 | 根据原始编码审计判断 |
| 迁移所有中文 | 只迁移原始非 UTF-8 文件中的运行期中文文本;注释可保留 |
| 创建全仓库一个巨大文本头文件 | 优先创建模块归属明确的头文件 |
| 在 armcc/armclang 项目中不区分工具链就统一套用同一种输出编码 | 先判断工具链,armclang 输出 UTF-8,armcc 输出 UTF-8 with BOM |
| 把 GBK 运行期字符串转成 UTF-8 运行期字符串 | 宏值必须保持原 GBK 字节 |
| 不先识别编译器就开始转换 | 先确认编译器类型,再选择对应编码格式 |
| 修改生成物/供应商/构建输出 | 默认排除,除非用户明确要求 |
| 使用 Windows 绝对路径写死规则 | 文档和配置使用仓库相对路径与 / 分隔符 |
完成一次编码规范化时,必须提供:
本 skill 目录下附带两个 Python 辅助脚本,用于自动化扫描和执行编码规范化。
作用: 扫描仓库所有目标文本文件,检测原始编码,识别中文字符位置(注释 vs 字符串字面量 vs 代码区),生成 encoding_audit.md 审计报告。
位置: agents/skills/repository-encoding-normalizer/scan_encoding.py
参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
--root | . | 仓库根目录 |
--out | encoding_audit.md | 审计报告输出路径 |
--exts | .c,.h,.s,.S,.mk,.txt,.bat,.cmd | 扫描的文件扩展名(逗号分隔) |
--exclude | stm32lib,stm32usb,ucos2,Libraries,... | 排除的目录名(逗号分隔) |
用法示例:
python scan_encoding.py --root . --out encoding_audit.md
输出示例:
审计报告包含两部分:
作用: 根据审计结果批量执行编码转换(GBK -> UTF-8 with/without BOM),创建宏定义头文件,并替换源文件中的中文字符串字面量为宏。
位置: agents/skills/repository-encoding-normalizer/normalize_encoding.py
参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
--root | . | 仓库根目录 |
--compiler | armcc | 编译器类型(armcc 或 armclang),决定目标编码是否带 BOM |
--files | "" | 需要转换的文件列表(逗号分隔,相对 root) |
--no-bom-files | "" | 转为 UTF-8 无 BOM 的文件列表(如 Makefile) |
--macro-header | "" | 新建的宏头文件路径(相对 root) |
--macro-name | "" | 宏名称 |
--macro-value | "" | 宏值(GBK 字节转义,如 PT562\xB2\xE2...) |
--macro-comment | "" | 宏后中文注释 |
--source-file | "" | 包含旧字符串的源文件路径(相对 root) |
--old-string | "" | 需要替换的旧字符串字面量 |
--include-marker | #include "includes.h" | 插入 include 的标记行 |
用法示例:
# 1. 仅批量转换文件编码
python normalize_encoding.py \
--root . \
--compiler armcc \
--files "src/tp.c,src/esc_p.c,src/includes.h" \
--no-bom-files "src/inc_config.mk"
# 2. 同时创建宏头文件并替换字面量
python normalize_encoding.py \
--root . \
--compiler armcc \
--files "src/tp.c,src/esc_p.c" \
--no-bom-files "src/inc_config.mk" \
--macro-header "src/tp_text.h" \
--macro-name "TP_TEXT_TEST_SAMPLE" \
--macro-value "PT562\\xB2\\xE2\\xCA\\xD4\\xD1\\xF9\\xD5\\xC5\\n" \
--macro-comment "PT562测试样张" \
--source-file "src/tp.c" \
--old-string '"PT562测试样张\\n"' \
--include-marker '#include "includes.h"'
注意事项:
--no-bom-files,否则 Make 工具会因 BOM 而报 missing separator 错误。--macro-value 中的 GBK 字节必须通过 python -c "print(' '.join('0x%02X' % b for b in '中文'.encode('gbk')))" 提前确认。--old-string 必须与实际源码中的字符串字面量完全匹配(包括引号和转义)。scan_encoding.py 的审计结果调整参数,不可盲目套用。--files 转换少量文件,编译通过后再批量处理剩余文件。