From 933add6cd833bb6ba6682ad2b6eb478871415ff5 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Tue, 31 Jul 2018 16:53:54 -0700 Subject: Support internationalisation. --- py/makeqstrdata.py | 64 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 7 deletions(-) (limited to 'py/makeqstrdata.py') diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index 3c0a60909..719bc62fa 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -9,6 +9,9 @@ from __future__ import print_function import re import sys +import collections +import gettext + # Python 2/3 compatibility: # - iterating through bytes is different # - codepoint2name lives in a different module @@ -59,6 +62,12 @@ def compute_hash(qstr, bytes_hash): # Make sure that valid hash is never zero, zero means "hash not computed" return (hash & ((1 << (8 * bytes_hash)) - 1)) or 1 +def translate(translation_file, i18ns): + with open(translation_file, "rb") as f: + table = gettext.GNUTranslations(f) + + return [(x, table.gettext(x)) for x in i18ns] + def qstr_escape(qst): def esc_char(m): c = ord(m.group(0)) @@ -73,6 +82,7 @@ def parse_input_headers(infiles): # read the qstrs in from the input files qcfgs = {} qstrs = {} + i18ns = set() for infile in infiles: with open(infile, 'rt') as f: for line in f: @@ -88,6 +98,12 @@ def parse_input_headers(infiles): qcfgs[match.group(1)] = value continue + + match = re.match(r'^TRANSLATE\("(.*)"\)$', line) + if match: + i18ns.add(match.group(1)) + continue + # is this a QSTR line? match = re.match(r'^Q\((.*)\)$', line) if not match: @@ -121,11 +137,11 @@ def parse_input_headers(infiles): order -= 100000 qstrs[ident] = (order, ident, qstr) - if not qcfgs: + if not qcfgs and qstrs: sys.stderr.write("ERROR: Empty preprocessor output - check for errors above\n") sys.exit(1) - return qcfgs, qstrs + return qcfgs, qstrs, i18ns def make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr): qbytes = bytes_cons(qstr, 'utf8') @@ -144,7 +160,7 @@ def make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr): qhash_str = ('\\x%02x' * cfg_bytes_hash) % tuple(((qhash >> (8 * i)) & 0xff) for i in range(cfg_bytes_hash)) return '(const byte*)"%s%s" "%s"' % (qhash_str, qlen_str, qdata) -def print_qstr_data(qcfgs, qstrs): +def print_qstr_data(qcfgs, qstrs, i18ns): # get config variables cfg_bytes_len = int(qcfgs['BYTES_IN_LEN']) cfg_bytes_hash = int(qcfgs['BYTES_IN_HASH']) @@ -156,14 +172,48 @@ def print_qstr_data(qcfgs, qstrs): # add NULL qstr with no hash or data print('QDEF(MP_QSTR_NULL, (const byte*)"%s%s" "")' % ('\\x00' * cfg_bytes_hash, '\\x00' * cfg_bytes_len)) + total_qstr_size = 0 # go through each qstr and print it out for order, ident, qstr in sorted(qstrs.values(), key=lambda x: x[0]): qbytes = make_bytes(cfg_bytes_len, cfg_bytes_hash, qstr) print('QDEF(MP_QSTR_%s, %s)' % (ident, qbytes)) + total_qstr_size += len(qstr) + + total_text_size = 0 + for original, translation in i18ns: + print("TRANSLATION(\"{}\", \"{}\")".format(original, translation)) + total_text_size += len(translation) -def do_work(infiles): - qcfgs, qstrs = parse_input_headers(infiles) - print_qstr_data(qcfgs, qstrs) + print() + print("// {} bytes worth of qstr".format(total_qstr_size)) + print("// {} bytes worth of translations".format(total_text_size)) + +def print_qstr_enums(qstrs): + # print out the starter of the generated C header file + print('// This file was automatically generated by makeqstrdata.py') + print('') + + # add NULL qstr with no hash or data + print('QENUM(MP_QSTR_NULL)') + + # go through each qstr and print it out + for order, ident, qstr in sorted(qstrs.values(), key=lambda x: x[0]): + print('QENUM(MP_QSTR_%s)' % (ident,)) if __name__ == "__main__": - do_work(sys.argv[1:]) + import argparse + + parser = argparse.ArgumentParser(description='Process QSTR definitions into headers for compilation') + parser.add_argument('infiles', metavar='N', type=str, nargs='+', + help='an integer for the accumulator') + parser.add_argument('--translation', default=None, type=str, + help='translations for i18n() items') + + args = parser.parse_args() + + qcfgs, qstrs, i18ns = parse_input_headers(args.infiles) + if args.translation: + translations = translate(args.translation, i18ns) + print_qstr_data(qcfgs, qstrs, translations) + else: + print_qstr_enums(qstrs) -- cgit v1.2.3