123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- import os
- import sys
- import re
- from typing import List, Tuple, Dict
- FileList = List[str]
- FlatList = Dict[str, Tuple[str]]
- class RunError(Exception):
- def __init__(self, message="RunError: run as module is not allowed."):
- self.message = message
- class ArgError(Exception):
- def __init__(self, message="ArgError: just 6 arg is allowed."):
- self.message = message
- if __name__ != '__main__':
- raise RunError()
- argv = sys.argv
- if len(argv) < 6:
- print(f"{len(argv)}")
- raise ArgError()
- output_dir = argv[1]
- export_h = argv[2]
- export = argv[3]
- translation = argv[4]
- input_dir = argv[5:]
- translation_output = os.path.join(output_dir, "tr")
- base_tr_file = os.path.join(translation, "base.py")
- try:
- os.makedirs(output_dir)
- except OSError:
- ...
- try:
- os.makedirs(translation_output)
- except OSError:
- ...
- base_tr = {}
- if os.path.exists(base_tr_file):
- with open(base_tr_file, "r", encoding="utf-8") as f:
- code = f.read()
- exec(code, base_tr, base_tr)
- def getFileFromPath(paths: List[str], file_type_: str) -> FileList:
- tmp: FileList = []
- for path in paths:
- for file_path, dir_names, file_names in os.walk(path):
- for names in file_names:
- file_type = os.path.splitext(names)[-1]
- if file_type == file_type_:
- tmp.append(os.path.join(file_path, names))
- return tmp
- file_list: FileList = getFileFromPath(input_dir, '.c')
- pattern = re.compile(r'HT_getText\(([\S]+),[\s]*(\"[^\"]*\")\)')
- flat_list: FlatList = {}
- for file in file_list:
- with open(file, "r", encoding="utf-8") as f:
- data = f.readline()
- while data:
- result: List[str] = pattern.findall(data)
- for i in result:
- if i[0] in flat_list and flat_list[i[0]][0] != "": # 若果是空字串则可以覆盖
- continue
- if i[0] not in flat_list:
- tmp = i[1]
- if tmp == "\"<base-tr>\"":
- tmp = f"\"{base_tr.get(i[0], None)}\""
- default_ = tmp.replace('\n', '\\n').replace('\r', '')
- flat_list[i[0]] = (default_,) # 生成一个数组
- data = f.readline()
- with open(os.path.join(output_dir, f"_ht.c"), "w", encoding="utf-8") as fc:
- with open(os.path.join(output_dir, f"_ht.h"), "w", encoding="utf-8") as fh:
- head = f'''/*
- * File: _ht.c/_ht.c
- * The file is automatically generated by Huan-GetText
- * Encoding: utf-8
- */'''
- fc.write(head + '\n\n')
- fh.write(head + '\n\n')
- fh.write(f"#include \"{export_h}.h\"\n")
- fc.write(f"#include \"_ht.h\"\n")
- fh.write("#define HT_getText(name, ...) (HT_TEXT_ ## name)\n")
- fh.write(f"{export} int HT_initGetText(char *lang);\n")
- fc.write("#undef HT_getText\n")
- for i in flat_list:
- fc.write(f"{export} const char *HT_TEXT_{i} = {flat_list[i][0]};\n")
- fh.write(f"{export} const char *HT_TEXT_{i};\n")
- fc.write('''\n
- /* define initGetText */
- /* need dlfcn or dlfcn-win32 */
- #include "dlfcn.h"
- #include "stdlib.h"
- static void *handle = NULL;
- static void destructExit(void) {
- dlclose(handle);
- }
- int HT_initGetText(char *lang) {
- if (lang == NULL || handle != NULL)
- return 2;
- handle = dlopen(lang, RTLD_NOW);
- if (handle == NULL)
- return 1;
- atexit(destructExit);
- char **tmp;\n\n''')
- for i in flat_list:
- fc.write(f''' tmp = dlsym(handle, "HT__TEXT_{i}");\n''')
- fc.write(f''' if (tmp != NULL) HT_TEXT_{i} = *tmp;\n\n''')
- fc.write(' return 0;\n}\n')
- for i in flat_list:
- print(f"TEXT: {i}")
- translation_list: FileList = getFileFromPath([translation], '.py')
- for t in translation_list:
- name = os.path.splitext(os.path.split(t)[-1])[0]
- if name == 'base':
- continue
- print(f"tr: {name}")
- with open(t, "r", encoding="utf-8") as f:
- code = f.read()
- var = {}
- for i in flat_list:
- var[i] = flat_list[i][0][1:-2] # [1:-2] 去除引号
- exec(code, var, var)
- with open(os.path.join(translation_output, f"{name}.c"), "w", encoding="utf-8") as fc:
- fc.write(f"#include \"{export_h}.h\"\n")
- for i in flat_list: # 根据 flat_list 生成变量
- res = var[i].replace('\n', '\\n').replace('\r', '')
- fc.write(f"{export} const char *const HT__TEXT_{i} = \"{res}\";\n")
|