import sys, os sys.stdout.reconfigure(encoding='utf-8', errors='replace') rep = chr(0xfffd) base = 'D:\\Code\\DTU 程序\\STM32F4-Base\\' pair = { '\u51fd':'\u6570', '\u8bf4':'\u660e', '\u529f':'\u80fd', '\u53c2':'\u6570', '\u72b6':'\u6001', '\u521d':'\u59cb', '\u7f13':'\u51b2', '\u56de':'\u503c', '\u7b49':')', '\u8bbe':'\u7f6e', '\u5f00':'\u542f', '\u5173':'\u95ed', '\u83b7':'\u53d6', '\u53d1':'\u9001', '\u63a5':'\u6536', '\u8bfb':'\u53d6', '\u5199':'\u5165', '\u64e6':'\u9664', '\u5b57':'\u8282', '\u8282':'\u6570', '\u957f':'\u5ea6', '\u7aef':'\u53e3', '\u534f':'\u8bae', '\u7c7b':'\u578b', '\u6a21':'\u5f0f', '\u670d':'\u52a1', '\u5730':'\u5740', '\u7f51':'\u5173', '\u63a9':'\u7801', '\u4f7f':'\u80fd', '\u54cd':'\u5e94', '\u5bc4':'\u5b58', '\u5b58':'\u5668', '\u547d':'\u4ee4', '\u4e8b':'\u4ef6', '\u8c03':'\u7528', '\u58f0':'\u660e', '\u5b9e':'\u73b0', '\u8fd4':'\u56de', '\u6307':'\u9488', '\u6570':'\u636e', '\u8fde':'\u63a5', '\u9519':'\u8bef', '\u65f6':'\u95f4', '\u6b21':'\u6570', '\u603b':'\u5bb9', '\u5bb9':'\u91cf', '\u5757':'\u5927', '\u5927':'\u5c0f', '\u91cd':'\u4f20', '\u4f20':'\u6b21', '\u63a2':'\u6d4b', '\u9694':'\uff1a', '\u59cb':'\u5316', '\u8bdd':'\u65f6', '\u5316':'\uff1a', '\u52a1':'\u5668', '\u6237':'\u7aef', '\u76ee':'\u6807', '\u6807':'\u7aef', '\u672c':'\u5730', '\u542b':'\u957f', '\u5305':'\u542b', '\u5c5e':'\u6027', '\u6536':'\u6570', '\u53ca':'\u65f6', '\u7cfb':'\u7edf', '\u7edf':'\u521d', '\u5145':'\u7535', '\u95f9':'\u949f', '\u5199':'\u4fdd', '\u4fdd':'\u62a4', '\u8f6c':'\uff0c', '\u65f6':'\u5236', '\u6e05':'\u96f6', '\u5143':'\uff1a', '\u884c':'\uff1a', '\u6574':'\u4e00', } files = [ 'Drivers\\BSP\\CH395F\\ch395f.c', 'Drivers\\BSP\\CH395F\\ch395f_test.c', 'Drivers\\BSP\\NET\\net_select.c', 'Drivers\\BSP\\GD5F2GQ5UE\\gd5f2gq5ue.c', 'Drivers\\BSP\\SD2506\\sd2506.c', 'Drivers\\BSP\\TPAFE5160\\tpafe5160.c', ] # Manual patterns that don't follow the pair rule manual = [ # ch395f.c ('\u521d\u59cb\u5316' + rep + '?', '\u521d\u59cb\u5316\uff09'), ('\u4fee\u6539\u8bb0\u5f55' + rep + '?', '\u4fee\u6539\u8bb0\u5f55\uff1a'), ('\u738b\u5efa' + rep + '? \u6539', '\u738b\u5efa\u950b \u6539'), ('\u6d4b\u8bd5\u5b57' + rep + '?*/', '\u6d4b\u8bd5\u5b57\u8282 */'), ('\u79c1\u6709\u53d8\u91cf' + rep + '?', '\u79c1\u6709\u53d8\u91cf\u533a'), ('\u63a5\u6536\u7f13\u51b2' + rep + '?*/', '\u63a5\u6536\u7f13\u51b2\u533a */'), ('\u51fd\u6570\u58f0\u660e' + rep + '?', '\u51fd\u6570\u58f0\u660e\u533a'), ('\u51fd\u6570\u5b9e\u73b0' + rep + '?', '\u51fd\u6570\u5b9e\u73b0\u533a'), ('\u53d1\u9001\u7f13\u51b2' + rep + '?*/', '\u53d1\u9001\u7f13\u51b2\u533a */'), ('\u8bfb\u53d6\u6307\u5b9a' + rep + '?\u5b58' + rep + '?\u5185' + rep + '? */', '\u8bfb\u53d6\u6307\u5b9a\u5bc4\u5b58\u5668\u5185\u5bb9 */'), ('\u6210\u529f' + rep + '?\u5931' + rep + '?', '\u6210\u529f\u5931\u8d25'), ('\u53d1\u9001\u5b57\u8282' + rep + '?*/', '\u53d1\u9001\u5b57\u8282\u6570 */'), ('\u63a5\u6536\u5b57\u8282' + rep + '?*/', '\u63a5\u6536\u5b57\u8282\u6570 */'), ('\u5f00' + rep + '?SPI', '\u5f00\u542f SPI'), ('\u7ed3' + rep + '?SPI', '\u7ed3\u675f SPI'), ('\u53d1\u9001\u83b7\u53d6\u8fdc' + rep + '?IP', '\u53d1\u9001\u83b7\u53d6\u8fdc\u7aef IP'), # net_select.c ('\u53ef\u8bfb\u4e8b' + rep + '?*/', '\u53ef\u8bfb\u4e8b\u4ef6 */'), ('\u53ef\u5199\u4e8b' + rep + '?*/', '\u53ef\u5199\u4e8b\u4ef6 */'), ('\u5f02\u5e38\u4e8b' + rep + '?*/', '\u5f02\u5e38\u4e8b\u4ef6 */'), ('\u8d85\u65f6\u68c0' + rep + '?*/', '\u8d85\u65f6\u68c0\u67e5 */'), ('\u65b0\u8fde\u63a5\u65f6\u53ef' + rep + '?*/', '\u65b0\u8fde\u63a5\u65f6\u53ef\u8bfb */'), # tpafe5160.c ('16' + rep + '?\u901a\u9053', '16\u4f4d 8\u901a\u9053'), ('t10 (RD \u4f4e\u8109' + rep + '?)', 't10 (RD \u4f4e\u8109\u51b2)'), ('\u5e8f\u5173\u952e' + rep + '?(', '\u5e8f\u5173\u952e\u70b9('), ('\u51fd\u6570\u8bf4\u660e\uff1a\u4ea7' + rep + '?CONVST', '\u51fd\u6570\u8bf4\u660e\uff1a\u4ea7\u751f CONVST'), ('\u51fd\u6570\u8bf4\u660e\uff1a\u8f6e' + rep + '?BUSY', '\u51fd\u6570\u8bf4\u660e\uff1a\u8f6e\u8be2 BUSY'), ('\u51fd\u6570\u8bf4\u660e\uff1a\u6bcf' + rep + '?RD', '\u51fd\u6570\u8bf4\u660e\uff1a\u6bcf\u4e2a RD'), ('\u51fd\u6570\u8bf4\u660e\uff1a' + rep + 'V\u91cf\u7a0b', '\u51fd\u6570\u8bf4\u660e\uff1a5V\u91cf\u7a0b'), # sd2506.c ('\u5341\u8fdb\u5236' + rep + '?BCD ', '\u5341\u8fdb\u5236\u8f6c BCD '), ('\u6210\u529f' + rep + '?2 - I2C', '\u6210\u529f\uff0c-2 - I2C'), ('00H: ' + rep + '?*/', '00H: \u79d2 */'), ('01H: ' + rep + '?*/', '01H: \u5206 */'), ('02H: ' + rep + '?', '02H: \u65f6'), ('04H: ' + rep + '?*/', '04H: \u65e5 */'), ('05H: ' + rep + '?*/', '05H: \u6708 */'), ('06H: ' + rep + '?*/', '06H: \u5e74 */'), ('07H: \u79d2\u62a5' + rep + '?*/', '07H: \u79d2\u62a5\u8b66 */'), ('08H: \u5206\u62a5' + rep + '?*/', '08H: \u5206\u62a5\u8b66 */'), ('09H: \u65f6\u62a5' + rep + '?', '09H: \u65f6\u62a5\u8b66'), ('0BH: \u65e5\u62a5' + rep + '?*/', '0BH: \u65e5\u62a5\u8b66 */'), ('0CH: \u6708\u62a5' + rep + '?*/', '0CH: \u6708\u62a5\u8b66 */'), ('0DH: \u5e74\u62a5' + rep + '?*/', '0DH: \u5e74\u62a5\u8b66 */'), ('\u51fd\u6570\u8bf4\u660e' + rep + '?. \u5148\u5f00\u5199\u4fdd', '\u51fd\u6570\u8bf4\u660e\uff1a1. \u5148\u5f00\u5199\u4fdd\u62a4'), ('\u51fd\u6570\u8bf4\u660e' + rep + '?. \u5199\u4f7f', '\u51fd\u6570\u8bf4\u660e\uff1a2. \u5199\u4f7f\u80fd'), ('\u51fd\u6570\u8bf4\u660e' + rep + '?. \u542f\u52a8\u8f6c\u6362', '\u51fd\u6570\u8bf4\u660e\uff1a3. \u542f\u52a8\u8f6c\u6362'), # ch395f ('\u51fd\u6570\u529f\u80fd\uff1a\u590d\u4f4d\u82af' + rep + '?', '\u51fd\u6570\u529f\u80fd\uff1a\u590d\u4f4d\u82af\u7247'), ('\u51fd\u6570\u529f\u80fd\uff1a\u68c0' + rep + '?CH395', '\u51fd\u6570\u529f\u80fd\uff1a\u68c0\u67e5 CH395'), ('\u51fd\u6570\u529f\u80fd\uff1a\u83b7\u53d6\u8fdc' + rep + '?IP', '\u51fd\u6570\u529f\u80fd\uff1a\u83b7\u53d6\u8fdc\u7aef IP'), ('\u51fd\u6570\u529f\u80fd\uff1a\u8f6f\u4ef6\u590d' + rep + '?CH395', '\u51fd\u6570\u529f\u80fd\uff1a\u8f6f\u4ef6\u590d\u4f4d CH395'), ('\u51fd\u6570\u529f\u80fd\uff1a\u542f' + rep + '?TCP \u76d1\u542c', '\u51fd\u6570\u529f\u80fd\uff1a\u542f\u52a8 TCP \u76d1\u542c'), ('\u51fd\u6570\u529f\u80fd\uff1a\u542f' + rep + '?TCP \u8fde\u63a5', '\u51fd\u6570\u529f\u80fd\uff1a\u542f\u52a8 TCP \u8fde\u63a5'), ('\u51fd\u6570\u529f\u80fd\uff1a\u542f' + rep + '?\u7981\u7528 DHCP', '\u51fd\u6570\u529f\u80fd\uff1a\u542f\u7528\u7981\u7528 DHCP'), ('\u51fd\u6570\u529f\u80fd\uff1a\u542f' + rep + '?\u7981\u7528\u6307\u5b9a S', '\u51fd\u6570\u529f\u80fd\uff1a\u542f\u7528\u7981\u7528\u6307\u5b9a S'), ('\u51fd\u6570\u529f\u80fd\uff1a\u8bfb\u53d6\u5168' + rep + '?\u901a\u9053\u8f6c\u6362\u7ed3\u679c', '\u51fd\u6570\u529f\u80fd\uff1a\u8bfb\u53d6\u5168\u90e8\u901a\u9053\u8f6c\u6362\u7ed3\u679c'), ('\u51fd\u6570\u529f\u80fd\uff1a\u8bfb\u53d6\u82af' + rep + '?ID', '\u51fd\u6570\u529f\u80fd\uff1a\u8bfb\u53d6\u82af\u7247 ID'), # ch395f_test.c ('NET ' + rep + '?TCP Ec', 'NET \u7684 TCP Ec'), ('NET ' + rep + '?UDP Ec', 'NET \u7684 UDP Ec'), # gd5f2gq5ue.c ('\u7f16\u7a0b\u5b8c\u6210\u540e\u68c0' + rep + '?P_FAIL', '\u7f16\u7a0b\u5b8c\u6210\u540e\u68c0\u67e5 P_FAIL'), ('\u64e6\u9664\u5b8c\u6210\u540e\u68c0' + rep + '?E_FAIL', '\u64e6\u9664\u5b8c\u6210\u540e\u68c0\u67e5 E_FAIL'), # generic patterns ('\u9650\u5b9a\u6761\u4ef6\uff1a\u5e94' + rep + '?ch395f', '\u9650\u5b9a\u6761\u4ef6\uff1a\u5e94\u5148\u8c03\u7528 ch395f'), ('\u9650\u5b9a\u6761\u4ef6\uff1a\u9700' + rep + '?ch395f', '\u9650\u5b9a\u6761\u4ef6\uff1a\u9700\u5148\u8c03\u7528 ch395f'), ('\u9650\u5b9a\u6761\u4ef6\uff1a\u6307\u9488\u975e' + rep + '? */', '\u9650\u5b9a\u6761\u4ef6\uff1a\u6307\u9488\u975e\u7a7a */'), ('\u6570\u636e\u540c\u6b65\u5c4f\u969c\uff1a\u786e' + rep + '?memcpy', '\u6570\u636e\u540c\u6b65\u5c4f\u969c\uff1a\u786e\u4fdd memcpy'), ('\u68c0\u67e5\u8f93\u5165\u53c2\u6570\u5408\u6cd5' + rep + '?*/', '\u68c0\u67e5\u8f93\u5165\u53c2\u6570\u5408\u6cd5\u6027 */'), ('\u8bfb\u53d6\u5168\u5c40\u4e2d\u65ad\uff08\u5237' + rep + '?socket', '\u8bfb\u53d6\u5168\u5c40\u4e2d\u65ad\uff08\u5237\u65b0 socket'), ('Socket \u6709\u6570\u636e\u53ef' + rep + '?*/', 'Socket \u6709\u6570\u636e\u53ef\u8bfb */'), ('IP \u5730\u5740\uff08\u4f4e\u5b57\u8282\u5728\u524d' + rep + '?', 'IP \u5730\u5740\uff08\u4f4e\u5b57\u8282\u5728\u524d\uff09'), ('\u8fd4\u56de\u503c\uff1a\u547d\u4ee4\u7801\u56de\u663e' + rep + '? uint8', '\u8fd4\u56de\u503c\uff1a\u547d\u4ee4\u7801\u56de\u663e\u503c uint8'), ('\u8fd4\u56de\u503c\uff1a\u6570\u636e\u56de\u663e' + rep + '? uint8', '\u8fd4\u56de\u503c\uff1a\u6570\u636e\u56de\u663e\u503c uint8'), ('GET_IP_INF ' + rep + '?9 ', 'GET_IP_INF \u7b49 9 '), # tpafe ('RANGE ' + rep + '?GND', 'RANGE \u63a5 GND'), ('\u62f7\u8d1d\u7528\u6237\u6570\u636e' + rep + '?DMA', '\u62f7\u8d1d\u7528\u6237\u6570\u636e\u5230 DMA'), ('\u7ec4\u5408 9 ' + rep + '? bit8', '\u7ec4\u5408 9 \u548c bit8'), ('ttl - TTL ' + rep + '? uint8', 'ttl - TTL \u503c uint8'), ('(BAT8_VAL) ' + rep + '?1BH', '(BAT8_VAL) \u4e3a 1BH'), ('\u6b63\u6e29' + rep + '?*/', '\u6b63\u6e29\u5ea6 */'), ('\u8d1f\u6e29' + rep + '? \u53d6\u8865', '\u8d1f\u6e29\u5ea6 \u53d6\u8865\u7801'), # tpafe ('\u51fd\u6570\u8bf4\u660e\uff1a\u542f' + rep + '?DHCP', '\u51fd\u6570\u8bf4\u660e\uff1a\u542f\u52a8 DHCP'), ('\u51fd\u6570\u8bf4\u660e\uff1a' + rep + '?V\u91cf\u7a0b', '\u51fd\u6570\u8bf4\u660e\uff1a\u00b15V\u91cf\u7a0b'), # generic pair leftovers (rep + '?' + rep + '?\u503c\uff1a', '\u8fd4\u56de\u503c\uff1a'), ] # Apply pair mapping for fname in files: path = base + fname if not os.path.exists(path): print(f'*** {fname}: NOT FOUND') continue with open(path, 'rb') as f: raw = f.read() text = raw.decode('utf-8', errors='replace') before = text.count(rep) if before == 0: print(f'{fname}: clean') continue # Strategy 1: pair mapping [char][REP]? for first, second in pair.items(): pattern = first + rep + '?' replacement = first + second text = text.replace(pattern, replacement) # Strategy 2: manual patterns for old, new in manual: text = text.replace(old, new) # Strategy 3: common multi-char patterns text = text.replace(rep + '?' + rep + '?\u503c\uff1a', '\u8fd4\u56de\u503c\uff1a') text = text.replace(rep + '?' + rep + '?\u503c\uff1a', '\u8fd4\u56de\u503c\uff1a') # Strategy 4: for remaining [REP]?\u503c\uff1a -> '\u8fd4\u56de\u503c\uff1a' # These are cases where the full '\u8fd4' was also corrupted import re as regex text = regex.sub(rep + r'\?' + rep + r'\?\u503c\uff1a', '\u8fd4\u56de\u503c\uff1a', text) after = text.count(rep) fixed = before - after with open(path, 'wb') as f: f.write(text.encode('utf-8')) if after > 0: print(f'{fname}: fixed {fixed}/{before}, {after} remaining') # Show first remaining for i, line in enumerate(text.split(chr(10)), 1): if rep in line: idx = line.index(rep) ctx = line[max(0,idx-10):idx+6] printable = ctx.replace(rep, '[?]') print(f' eg L{i}: ...{printable}...') break else: print(f'{fname}: CLEAN ({fixed} fixed)') print('Done')