hgt.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. import os
  2. import sys
  3. import re
  4. from typing import List, Tuple, Dict
  5. FileList = List[str]
  6. FlatList = Dict[str, Tuple[str]]
  7. class RunError(Exception):
  8. def __init__(self, message="RunError: run as module is not allowed."):
  9. self.message = message
  10. class ArgError(Exception):
  11. def __init__(self, message="ArgError: just 6 arg is allowed."):
  12. self.message = message
  13. if __name__ != '__main__':
  14. raise RunError()
  15. argv = sys.argv
  16. if len(argv) < 6:
  17. print(f"{len(argv)}")
  18. raise ArgError()
  19. output_dir = argv[1]
  20. export_h = argv[2]
  21. export = argv[3]
  22. translation = argv[4]
  23. input_dir = argv[5:]
  24. translation_output = os.path.join(output_dir, "tr")
  25. base_tr_file = os.path.join(translation, "base.py")
  26. try:
  27. os.makedirs(output_dir)
  28. except OSError:
  29. ...
  30. try:
  31. os.makedirs(translation_output)
  32. except OSError:
  33. ...
  34. base_tr = {}
  35. if os.path.exists(base_tr_file):
  36. with open(base_tr_file, "r", encoding="utf-8") as f:
  37. code = f.read()
  38. exec(code, base_tr, base_tr)
  39. def getFileFromPath(paths: List[str], file_type_: str) -> FileList:
  40. tmp: FileList = []
  41. for path in paths:
  42. for file_path, dir_names, file_names in os.walk(path):
  43. for names in file_names:
  44. file_type = os.path.splitext(names)[-1]
  45. if file_type == file_type_:
  46. tmp.append(os.path.join(file_path, names))
  47. return tmp
  48. file_list: FileList = getFileFromPath(input_dir, '.c')
  49. pattern = re.compile(r'HT_getText\(([\S]+),[\s]*(\"[^\"]*\")\)')
  50. flat_list: FlatList = {}
  51. for file in file_list:
  52. with open(file, "r", encoding="utf-8") as f:
  53. data = f.readline()
  54. while data:
  55. result: List[str] = pattern.findall(data)
  56. for i in result:
  57. if i[0] in flat_list and flat_list[i[0]][0] != "": # 若果是空字串则可以覆盖
  58. continue
  59. if i[0] not in flat_list:
  60. tmp = i[1]
  61. if tmp == "\"<base-tr>\"":
  62. tmp = f"\"{base_tr.get(i[0], None)}\""
  63. default_ = tmp.replace('\n', '\\n').replace('\r', '')
  64. flat_list[i[0]] = (default_,) # 生成一个数组
  65. data = f.readline()
  66. with open(os.path.join(output_dir, f"_ht.c"), "w", encoding="utf-8") as fc:
  67. with open(os.path.join(output_dir, f"_ht.h"), "w", encoding="utf-8") as fh:
  68. head = f'''/*
  69. * File: _ht.c/_ht.c
  70. * The file is automatically generated by Huan-GetText
  71. * Encoding: utf-8
  72. */'''
  73. fc.write(head + '\n\n')
  74. fh.write(head + '\n\n')
  75. fh.write(f"#include \"{export_h}.h\"\n")
  76. fc.write(f"#include \"_ht.h\"\n")
  77. fh.write("#define HT_getText(name, ...) (HT_TEXT_ ## name)\n")
  78. fh.write(f"{export} int HT_initGetText(char *lang);\n")
  79. fc.write("#undef HT_getText\n")
  80. for i in flat_list:
  81. fc.write(f"{export} const char *HT_TEXT_{i} = {flat_list[i][0]};\n")
  82. fh.write(f"{export} const char *HT_TEXT_{i};\n")
  83. fc.write('''\n
  84. /* define initGetText */
  85. /* need dlfcn or dlfcn-win32 */
  86. #include "dlfcn.h"
  87. #include "stdlib.h"
  88. static void *handle = NULL;
  89. static void destructExit(void) {
  90. dlclose(handle);
  91. }
  92. int HT_initGetText(char *lang) {
  93. if (lang == NULL || handle != NULL)
  94. return 2;
  95. handle = dlopen(lang, RTLD_NOW);
  96. if (handle == NULL)
  97. return 1;
  98. atexit(destructExit);
  99. char **tmp;\n\n''')
  100. for i in flat_list:
  101. fc.write(f''' tmp = dlsym(handle, "HT__TEXT_{i}");\n''')
  102. fc.write(f''' if (tmp != NULL) HT_TEXT_{i} = *tmp;\n\n''')
  103. fc.write(' return 0;\n}\n')
  104. for i in flat_list:
  105. print(f"TEXT: {i}")
  106. translation_list: FileList = getFileFromPath([translation], '.py')
  107. for t in translation_list:
  108. name = os.path.splitext(os.path.split(t)[-1])[0]
  109. if name == 'base':
  110. continue
  111. print(f"tr: {name}")
  112. with open(t, "r", encoding="utf-8") as f:
  113. code = f.read()
  114. var = {}
  115. for i in flat_list:
  116. var[i] = flat_list[i][0][1:-2] # [1:-2] 去除引号
  117. exec(code, var, var)
  118. with open(os.path.join(translation_output, f"{name}.c"), "w", encoding="utf-8") as fc:
  119. fc.write(f"#include \"{export_h}.h\"\n")
  120. for i in flat_list: # 根据 flat_list 生成变量
  121. res = var[i].replace('\n', '\\n').replace('\r', '')
  122. fc.write(f"{export} const char *const HT__TEXT_{i} = \"{res}\";\n")