搜索/修改支持多种平台的老牌 C 项目,同时不破坏兼容性

修改支持多种平台的老牌 C 项目,同时不破坏兼容性

当 AI 要修改一个必须继续支持旧编译器、多种平台和可选功能的成熟 C 代码库时使用。它会构建并测试受影响的配置,遵守代码风格、内存、提交、文档和发布规则,并让每个补丁都小而能单独通过。

要使用这个AI规则
## 修改前,确认必须继续运行的平台和功能组合 - 将可移植性、稳定性、健壮性和向后兼容性视为首要设计约束。 - 覆盖从符合标准的最小配置,到带有可选脚本接口的完整图形配置等各种构建方式。 - 在更改架构或面向用户的行为之前,阅读仓库的高层设计策略。 - 区分核心源码、运行时资源、翻译、测试、文档、子项目,以及以供应商副本形式引入的上游代码。 - 不要假定可使用最新的编译器、操作系统、功能集或图形环境。 - 除非变更明确受功能门控,否则应使各个受支持变体的行为保持一致。 ## 构建并测试受影响的配置,不产生新警告 - 使用为当前平台和工具链记录的构建路径。 - 通过相应生成器重新生成函数声明或其他派生接口,不要手工编辑生成后的输出。 - 迭代期间运行目标明确的测试文件,并同时检查消息输出和详细测试日志。 - 提交前必须确保构建没有新增警告、相关测试通过,并且源码风格与所编辑文件一致。 - 不同平台的构建流程不同时,应查阅该平台的安装指南,不要凭猜测改写命令。 - 当共享代码、功能组合或运行时文件受到影响时,扩展到更广的测试范围。 ## 生成文件只通过生成器重新生成,并遵守文件负责人的流程 - 识别哪些目录是生成的、从上游引入的、与相关项目共享的,或由指定维护者管理的。 - 只有当生成文件的源发生变化时才更改该生成文件,并将无关的重新生成排除在功能补丁之外。 - 按记录的维护者工作流处理受维护的运行时变更,不要绕过归属权。 - 编辑随产品交付的运行时文件和帮助文件时,更新必需的变更日期或说明。 - 除非存在明确的目录例外,否则为核心源码变更添加仓库要求的补丁跟踪条目。 - 绝不要把供应商更新、生成噪声、翻译和无关源码整理混入同一个补丁。 ## 在提交标题中写问题,而不是修复方法 - 严格遵循仓库规定的补丁主题和正文结构。 - 在主题中陈述问题,而不是解决方案的实现方式。 - 编写完整的问题句和简洁的解决方案句,并包含要求的署名和标点。 - 当格式有此要求时,将可选说明放在必需的问题和解决方案标题之后,并使用连续文字而非项目符号。 - 根据修复、关闭和相关引用各自不同的含义为其加上标签。 - 包含要求的开发者认证,并且只通过获准的共同作者机制披露 AI 协助。 ## 沿用现有 C 风格,不使用旧编译器不支持的语法 - 保持4个空格的逻辑缩进,同时遵守文件特定的制表符规则或纯空格规则。 - 对于函数和控制流,让左花括号独占一行。 - 按仓库既有布局安排函数定义的返回类型和函数名。 - 匹配周围文件中的声明位置,不要借机将其现代化。 - 只使用已记录的基准 C 语言及获准的新特性;不要引入老旧编译器不支持的结构。 - 编辑后运行所有文件特定的格式化工具,并检查其差异。 ## 使用项目自己的类型,并把已知的字符串长度传给辅助函数 - 使用仓库的自定义类型后缀,避开系统标准保留的后缀。 - 保持正在进行的布尔类型迁移:在同一个补丁内一致使用当地既有的布尔形式,避免批量转换。 - 当读者无法轻易看出首次赋值时初始化局部变量,但不要添加会掩盖未初始化读取缺陷的冗余初始化。 - 对字符串字面量使用字面量长度辅助函数;需要已写入大小时,使用会返回长度的格式化函数。 - 已知字符串长度时,将其传给长度感知操作,不要再次扫描。 - 让每个字节缓冲区指针紧邻其 `size_t` 长度;只有老旧接口要求时才使用更窄的整数类型。 ## 用项目封装管理内存,出错时也一定释放 - 相比直接使用标准库的分配、释放、复制、移动、字符和空白操作,优先使用仓库封装。 - 根据封装已记录的空指针处理、内存耗尽行为、重叠区域安全性、编码行为和跨平台一致性来选择封装。 - 每次除法前都显式检查除数是否为零,即使较早的复合条件看起来已能推导出非零。 - 对每次新增分配,验证成功、提前返回和每个错误分支中的清理路径。 - 以字节为单位保存缓冲区大小,并明确截断、终止和已写入长度的行为。 - 不要仅仅因为熟悉通用库调用,就用它替换更安全的项目封装。 ## 遵守命名和宏的规则,让构建文件保持可移植 - 遵守保留名称限制、禁用标识符、函数名长度限制、空白规则和每行一条语句规则。 - 使用既有的功能前缀和大写宏约定。 - 使用仓库支持的条件模式测试功能宏。 - 将主要构建文件限制在已记录的可移植 make 方言内;避免实现特定的赋值、模式、外壳和条件扩展。 - 复用项目的字符串类型、字节类型及其对应的宏。 - 引入新标识符、宏或构建规则之前,阅读权威的风格参考。 ## 编写在相关运行时和派生实现中也能运行的运行时脚本 - 新文件使用当前脚本风格,同时考虑与相关运行时和派生实现的兼容性。 - 兼容性不确定时,在采用较新的语言结构之前先询问。 - 在脚本测试中遵循局部变量命名约定。 - 文件已在顶层门控某项功能时,不要在单个测试内重复该功能门控。 - 文件没有顶层门控时,只为需要可选功能的测试添加范围明确的门控。 - 将运行时脚本变更与无关的核心语言现代化分开。 ## 编写能重现所报告缺陷的回归测试 - 优先使用确定性断言,而不是只验证程序不会崩溃的测试。 - 对渲染缺陷添加屏幕捕获比较;对错误数据断言其精确输出。 - 为新行为添加全面覆盖,最好放入现有的相关测试文件。 - 修复已报告缺陷时,应复现原始场景,而不只是简化的合成案例。 - 对终端会话、屏幕转储、脚本加载成功和预期的脚本加载失败使用标准辅助函数。 - 将语法和缩进的运行时测试放入各自专用的测试套件。 ## 在同一补丁中更新帮助文档,并保持其格式 - 任何选项或功能变更,都应在同一个补丁中更新面向用户的文档。 - 编辑现有文档时,刷新帮助文件的变更标题。 - 对文件标题、模式行、宽度、制表符对齐、唯一标签、交叉引用、标题、代码示例和高亮记号,保留权威帮助格式。 - 使用安全的重新制表操作并检查其差异;不要强制进行大范围空白重写。 - 保证链接标签在全局唯一,并在需要时为扩展特定标签添加前缀。 - 新增或修改文字时优先使用性别中立措辞,但不要仅为此目的改写未受影响的文本。 ## 先确认发布阶段,并让已弃用的行为仍可使用 - 提议变更范围前,先确定项目处于开发周期还是稳定期。 - 稳定期内,将可接受变更限制为明确的缺陷修复、安全修复、文档、翻译和运行时维护。 - 稳定期内不要引入新功能或破坏向后兼容性的核心变更。 - 在各个次要版本之间保持已发布核心行为不变。 - 让弃用行为继续可通过配置访问,将其记录为已弃用,在受支持时允许编译时禁用,并且仅可在后续获准周期中移除。 - 按运行时资源已记录的维护灵活性处理它们,但不得削弱核心保证。 ## 提交补丁时,让每个提交都能单独构建并通过测试 - 报告疑似安全问题或更改安全敏感代码之前,先阅读安全策略。 - 确保提交格式、无新增警告的构建、相关测试、回归覆盖、文档和认证全部完成。 - 将差异限制在所述问题内:不得包含零散空白变更、无关重构或无关生成输出。 - 对多补丁系列,要求每个提交都能独立编译并通过自身测试。 - 不要留下由后续提交修复的故意损坏中间提交;应将它们合并。 - 确认文档描述的行为与代码强制执行的行为仍然一致,并在问题和解决方案记录中说明有意变更。 ## 只做最小的修改,在工作树之外操作前先询问 - 做出达成目标所需的最小变更,并匹配周围代码,不要强行实施大范围改进。 - 将解决多个独立问题的补丁拆分开。 - 如果补丁只处理症状,应说明更深层问题和所选范围限制。 - 声称缺陷存在前先复现它;声称代码会执行某项行为前先阅读实现。 - 当前源码可用时,不要依赖记忆中的文件内容。 - 安装软件包、更改工作树外的文件、推送分支或使用网络操作之前,先征得用户确认。