1#!/usr/bin/env python3 2 3# Convert *.json to *.h 4# Usage: ./json2h.py msg_hash_fr.json 5 6import re 7import sys 8import json 9 10try: 11 json_filename = sys.argv[1] 12 h_filename = json_filename.replace('.json', '.h') 13except IndexError: 14 print("Usage: ./template.py <language_postfix>") 15 sys.exit(1) 16 17if json_filename == 'msg_hash_us.json' or json_filename == 'msg_hash_lbl.json': 18 print("Skip") 19 sys.exit(0) 20 21p = re.compile( 22 r'MSG_HASH\s*(?:\/\*(?:.|[\r\n])*?\*\/\s*)*\(\s*(?:\/\*(?:.|[\r\n])*?\*\/\s*)*[a-zA-Z0-9_]+\s*(?:\/\*(?:.|[\r\n])*?\*\/\s*)*,\s*(?:\/\*(?:.|[\r\n])*?\*\/\s*)*\".*\"\s*(?:\/\*(?:.|[\r\n])*?\*\/\s*)*\)') 23 24 25def c89_cut(old_str): 26 new_str = '' 27 byte_count = 0 28 for c in old_str: 29 byte_count += len(c.encode('utf-8')) 30 if byte_count > 500: 31 return new_str + '[...]' 32 new_str += c 33 return new_str 34 35 36def parse_message(message): 37 # remove all comments before the value (= the string) 38 a = message.find('/*') 39 b = message.find('*/') 40 c = message.find('"') 41 new_msg = message 42 while (a >= 0 and b >= 0) and (a < c < b or b < c): 43 new_msg = new_msg[:a] + new_msg[b + 2:] 44 c = new_msg.find('"', a) 45 b = new_msg.find('*/', a) 46 a = new_msg.find('/*', a) 47 # get key word 48 word = new_msg[new_msg.find('(') + 1:new_msg.find(',')].strip() 49 50 # remove all comments after the value (= the string) 51 a = new_msg.rfind('/*') 52 b = new_msg.rfind('*/') 53 d = new_msg.rfind('"') 54 while (a >= 0 and b >= 0) and (a < d < b or a > d): 55 new_msg = new_msg[:a] 56 a = new_msg.rfind('/*') 57 b = new_msg.rfind('*/') 58 d = new_msg.rfind('"') 59 # get value 60 value = new_msg[c + 1:d] 61 62 return word, value 63 64 65def parse_messages(text): 66 result = p.findall(text) 67 seen = set() 68 msg_list = [] 69 for msg in result: 70 key, val = parse_message(msg) 71 item = {'key': key, 'val': val, 'msg': msg} 72 msg_list.append(item) 73 if key not in seen: 74 seen.add(key) 75 else: 76 print("Duplicate key: " + key) 77 78 return msg_list 79 80 81def update(messages, template, source_messages): 82 translation = template 83 template_messages = parse_messages(template) 84 for tp_msg in template_messages: 85 old_msg = tp_msg['msg'] 86 if tp_msg['key'] in messages and messages[tp_msg['key']] != source_messages[tp_msg['key']]: 87 tp_msg_val = tp_msg['val'] 88 tl_msg_val = messages[tp_msg['key']] 89 tl_msg_val = tl_msg_val.replace('"', '\\\"').replace('\n', '') # escape 90 if tp_msg['key'].find('_QT_') < 0: 91 tl_msg_val = c89_cut(tl_msg_val) 92 # Replace last match, in case the key contains the value string 93 new_msg = old_msg[::-1].replace(tp_msg_val[::-1], tl_msg_val[::-1], 1)[::-1] 94 translation = translation.replace(old_msg, new_msg) 95 # Remove English duplicates and non-translatable strings 96 else: 97 translation = translation.replace(old_msg + '\n', '') 98 return translation 99 100 101with open('msg_hash_us.h', 'r', encoding='utf-8') as template_file: 102 template = template_file.read() 103 with open('msg_hash_us.json', 'r+', encoding='utf-8') as source_json_file: 104 source_messages = json.load(source_json_file) 105 with open(json_filename, 'r+', encoding='utf-8') as json_file: 106 messages = json.load(json_file) 107 new_translation = update(messages, template, source_messages) 108 with open(h_filename, 'w', encoding='utf-8') as h_file: 109 h_file.seek(0) 110 h_file.write(new_translation) 111 h_file.truncate() 112