import sys, os sys.stdout.reconfigure(encoding='utf-8', errors='replace') rep = chr(0xfffd) base = 'D:\\Code\\DTU 程序\\STM32F4-Base\\' fixes = { 'Drivers\\BSP\\CH395F\\ch395f.c': [ # Author name ('王建' + rep + '? * 创建', '王建锋 * 创建'), # Closing parens and punctuation ('手册要' + rep + '?SPI', '手册要求 SPI'), ('rx_buf[' + rep + '? *', 'rx_buf] *'), ('SPI 驱动' + rep + '?DMA TX+RX', 'SPI 驱动) DMA TX+RX'), ('SPI 驱动' + rep + '?DMA 传输', 'SPI 驱动) DMA 传输'), ('begin() ' + rep + '?ch395f_spi_end', 'begin() 到 ch395f_spi_end'), ('begin() ' + rep + '?ch395f_spi_end', 'begin() 到 ch395f_spi_end'), ('begin() ' + rep + '?ch395f_spi_end', 'begin() 到 ch395f_spi_end'), ('0x57' + rep + '? *', '0x57) *'), ('exist() 检' + rep + '? */', 'exist() 检查) */'), ('在前,' + rep + '? */', '在前,) */'), ('默认' + rep + '?' + rep + '? *', '默认值) *'), ('SUCCESS ' + rep + '?CH395F_CMD_RET', 'SUCCESS 或 CH395F_CMD_RET'), ('4s' + rep + '? */', '4s) */'), ('EEPROM' + rep + '? * 入口参数', 'EEPROM) * 入口参数'), ('TE5' + rep + '? */', 'TE5) */'), ('手' + rep + '?5.37', '手册 5.37'), ('发送启' + rep + '?禁用', '发送启禁用'), ('时钟)' + rep + '? *', '时钟), *'), (rep + '?DMA 接收缓冲区偏移', '从 DMA 接收缓冲区偏移'), ('0~7' + rep + '? * 返回值', '0~7) * 返回值'), ('100ms' + rep + '?=默认', '100ms)=默认'), ('次' + rep + '?=默认', '次数=默认'), ('最' + rep + '?128', '最大 128'), ('+IP' + rep + '? * 限定条件', '+IP) * 限定条件'), ], 'Drivers\\BSP\\CH395F\\ch395f_test.c': [ ('默' + rep + '?192.168.1.2:8081' + rep + '?', '认 192.168.1.2:8081)'), ('默' + rep + '?192.168.1.2:8082' + rep + '?', '认 192.168.1.2:8082)'), ('version) ' + rep + '?read-clear', 'version) 即 read-clear'), ('创建' + rep + '?UDP', '创建 UDP'), ('DHCP ' + rep + '?轮询等待', 'DHCP 并轮询等待'), ('= 60000' + rep + '?*/', '= 60000)*/'), ], 'Drivers\\BSP\\GD5F2GQ5UE\\gd5f2gq5ue.c': [ ('再拉' + rep + '? */', '再拉高 */'), ('P_FAIL ' + rep + '? */', 'P_FAIL 位 */'), ('E_FAIL ' + rep + '? */', 'E_FAIL 位 */'), ('128KB' + rep + '? * 入口参数', '128KB) * 入口参数'), ], 'Drivers\\BSP\\NET\\net_select.c': [ ('不可' + rep + '? */', '不可写 */'), ('可' + rep + '?*/', '可写*/'), ], 'Drivers\\BSP\\SD2506\\sd2506.c': [ ('BCD ' + rep + '? * 入口参数', 'BCD 码 * 入口参数'), ('编码' + rep + '? * 限定条件', '编码) * 限定条件'), (rep + '?1AH=80H', '(1AH=80H'), ('毫' + rep + '?(raw', '毫秒 (raw'), ('SRAM ' + rep + '?2CH~71H', 'SRAM 区 2CH~71H'), ('始终' + rep + '?])', '始终为0])'), ('CTR2 ' + rep + '?INTAE=1', 'CTR2 的 INTAE=1'), ], 'Drivers\\BSP\\TPAFE5160\\tpafe5160.c': [ ('ZGT6,并' + rep + '?6位', 'ZGT6,并行 6位'), ('驱动' + rep + '?TPAFE5160' + rep + '?', '驱动适配 TPAFE5160'), # Fix multiple specific cases ('脉冲 ' + rep + '?22ns', '脉冲 约 22ns'), ('~6ns)' + rep + '? * 加上', '~6ns),* 加上'), ('已完' + rep + '?GPIO', '已完成 GPIO'), # 设置过采样 ('过采样' + rep + '? * 入口参数', '过采样率 * 入口参数'), ('返回值:' + rep + '? * 限定条件:GPIO', '返回值:无 * 限定条件:GPIO'), # 下一 - this is tricky, let me look at full context ('样本' + rep + '?BUSY', '样本 BUSY'), ('下一' + rep + '?BUSY', '下一次 BUSY'), # wait conversion ('转换完' + rep + '? * 入口参数', '转换完成 * 入口参数'), ('转换完' + rep + '? * 返回值', '转换完成 * 返回值'), # if this pattern exists ('转换完成' + rep + '?2 - 超时', '转换完成,2 - 超时'), ('下降' + rep + '? */', '下降沿 */'), ('空闲' + rep + '?*/', '空闲)*/'), ('转换' + rep + '?1 -', '转换中 1 -'), # 读取指定通道的转换结果 ('转换结' + rep + '? * 入口参数', '转换结果 * 入口参数'), ('转电压' + rep + '? * 入口参数', '转电压 * 入口参数'), ('量程' + rep + '?LSB', '量程,LSB'), ('量程' + rep + '?LSB', '量程,LSB'), ('引脚' + rep + '?GND', '引脚接 GND'), ('RANGE 接 GND ' + rep + '?±5V', 'RANGE 接 GND,±5V'), ('转换' + rep + '? * 入口参数', '转换)* 入口参数'), ('RD 为低' + rep + '?CS', 'RD 为低,CS'), ('通道' + rep + '? uint8_t', '通道数 uint8_t'), ('缓冲' + rep + '? int16_t', '缓冲区 int16_t'), ('返回值:' + rep + '? * 限定条件:转换', '返回值:无 * 限定条件:转换'), ('主频)' + rep + '? *', '主频),*'), ('数据' + rep + '?DB[15:0]', '数据到 DB[15:0]'), ('ISR ' + rep + '?s_buf_b', 'ISR 写 s_buf_b'), ('0 = ' + rep + '?B / ' + rep + '?A, 1 = ' + rep + '?A / ' + rep + '?B', '0 = 写 B / 读 A, 1 = 写 A / 读 B'), ('使能用' + rep + '? * 入口参数', '使能)* 入口参数'), ('返回值:' + rep + '? * 限定条件:CubeMX', '返回值:无 * 限定条件:CubeMX'), ('仅' + rep + '?irq_disable()', '仅当 irq_disable()'), ('返回值:' + rep + '? * 限定条件:已调用', '返回值:无 * 限定条件:已调用'), ('启动转换(中断模式' + rep + '? * 入口参数', '启动转换(中断模式)* 入口参数'), ('返回值:' + rep + '? * 限定条件:已调用 tpafe5', '返回值:无 * 限定条件:已调用 tpafe5'), ('完成后' + rep + '?EXTI 中断', '完成后触发 EXTI 中断'), ('数据就绪' + rep + '? - 无新数据', '数据就绪,0 - 无新数据'), ('返回值:' + rep + '? * 限定条件:中断', '返回值:无 * 限定条件:中断'), ('缓冲' + rep + '? */', '缓冲区 */'), ('下降' + rep + '?EXTI', '下降沿 EXTI'), ('返回值:' + rep + '? * 限定条件:BUSY', '返回值:无 * 限定条件:BUSY'), # Additional tpafe5160 patterns ('并' + rep + '?位数据', '并行 16位数据'), ('本驱动' + rep + '?AD7606', '本驱动适配 AD7606'), ], } total_fixed = 0 for fname, file_fixes in fixes.items(): path = base + fname with open(path, 'rb') as f: raw = f.read() text = raw.decode('utf-8', errors='replace') before = text.count(rep) for needle, replacement in file_fixes: while needle in text: text = text.replace(needle, replacement) after = text.count(rep) fixed = before - after total_fixed += fixed print('{}: fixed {} ({} -> {})'.format(fname, fixed, before, after)) with open(path, 'wb') as f: f.write(text.encode('utf-8')) print('\nTotal fixed this pass: {}'.format(total_fixed)) # Show remaining print('\n=== REMAINING ===') for fname in fixes: path = base + fname with open(path, 'rb') as f: text = f.read().decode('utf-8', errors='replace') remaining = text.count(rep) if remaining > 0: print('\n--- {} remaining in {} ---'.format(remaining, fname)) for i, line in enumerate(text.split(chr(10)), 1): if rep in line: idx = line.index(rep) left = line[max(0,idx-30):idx] right = line[idx+2:idx+20] print('L{}: ...{}[?]{}...'.format(i, left, right))