#!/usr/bin/env python3 # Convert *.json to *.h # Usage: ./json2h.py msg_hash_fr.json import re import sys import json try: json_filename = sys.argv[1] h_filename = json_filename.replace('.json', '.h') except IndexError: print("Usage: ./template.py ") sys.exit(1) if json_filename == 'msg_hash_us.json' or json_filename == 'msg_hash_lbl.json': print("Skip") sys.exit(0) p = re.compile( 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*)*\)') def c89_cut(old_str): if old_str.endswith('[...]'): return old_str new_str = '' byte_count = 0 for c in old_str: byte_count += len(c.encode('utf-8')) if byte_count > 500: return new_str + '[...]' new_str += c return new_str def parse_message(message): # remove all comments before the value (= the string) a = message.find('/*') b = message.find('*/') c = message.find('"') new_msg = message while (a >= 0 and b >= 0) and (a < c < b or b < c): new_msg = new_msg[:a] + new_msg[b + 2:] c = new_msg.find('"', a) b = new_msg.find('*/', a) a = new_msg.find('/*', a) # get key word word = new_msg[new_msg.find('(') + 1:new_msg.find(',')].strip() # remove all comments after the value (= the string) a = new_msg.rfind('/*') b = new_msg.rfind('*/') d = new_msg.rfind('"') while (a >= 0 and b >= 0) and (a < d < b or a > d): new_msg = new_msg[:a] a = new_msg.rfind('/*') b = new_msg.rfind('*/') d = new_msg.rfind('"') # get value value = new_msg[c + 1:d] return word, value def parse_messages(text): result = p.findall(text) seen = set() msg_list = [] for msg in result: key, val = parse_message(msg) item = {'key': key, 'val': val, 'msg': msg} msg_list.append(item) if key not in seen: seen.add(key) else: print("Duplicate key: " + key) return msg_list def update(messages, template, source_messages): translation = template template_messages = parse_messages(template) for tp_msg in template_messages: old_msg = tp_msg['msg'] if tp_msg['key'] in messages and messages[tp_msg['key']] != source_messages[tp_msg['key']]: tp_msg_val = tp_msg['val'] tl_msg_val = messages[tp_msg['key']] # escape all \ tl_msg_val = tl_msg_val.replace('\\', r'\\') # remove "double-dipping" on escape sequences tl_msg_val = re.sub(r'\\\\(?=[nrt])', r'\\', tl_msg_val) # escape other symbols tl_msg_val = tl_msg_val.replace('"', '\\\"').replace('\n', '') if tp_msg['key'].find('_QT_') < 0: tl_msg_val = c89_cut(tl_msg_val) # Replace last match, in case the key contains the value string new_msg = old_msg[::-1].replace(tp_msg_val[::-1], tl_msg_val[::-1], 1)[::-1] translation = translation.replace(old_msg, new_msg) # Remove English duplicates and non-translatable strings else: translation = translation.replace(old_msg + '\n', '') return translation with open('msg_hash_us.h', 'r', encoding='utf-8') as template_file: template = template_file.read() with open('msg_hash_us.json', 'r+', encoding='utf-8') as source_json_file: source_messages = json.load(source_json_file) with open(json_filename, 'r+', encoding='utf-8') as json_file: messages = json.load(json_file) new_translation = update(messages, template, source_messages) with open(h_filename, 'w', encoding='utf-8') as h_file: h_file.seek(0) h_file.write(new_translation) h_file.truncate()