gen_c_from_strings_file.py.svn-base
来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· SVN-BASE 代码 · 共 251 行
SVN-BASE
251 行
import string
from extract_strings import load_strings_file, strings_file, get_lang_list
def as_utf8(n):
if n < 0x7f:
assert 0 # don't pass me those
if n < 0x7ff:
y = ((n >> 6) & 0x1f) | 0xC0 # 110yyyyy
z = (n & 0x3f) | 0x80 # 10zzzzzz
return [y,z]
if n < 0xffff:
x = ((n >> 12) & 0x0f) | 0xE0
y = ((n >> 6) & 0x3f) | 0x80
z = (n & 0x3f) | 0x80
return [x,y,z]
assert 0 # too lazy to encode those
# TODO: stupid C escaping fails on e.g. \xcbb
def c_hex2(n):
h = hex(n)[2:]
if 1 == len(h):
h = "x0" + h
else:
assert 2 == len(h)
h = "x" + h
assert 3 == len(h)
h = "\\" + h
h = " \"" + h + "\" "
return h
def c_hex(n):
h = hex(n)[2:]
if 1 == len(h):
h = "x0" + h
else:
assert 2 == len(h)
h = "x" + h
assert 3 == len(h)
h = "\\" + h
return h
def c_oct(n):
o = oct(n)
if 1 == len(o):
return "\\00" + o
elif 2 == len(o):
return "\\0" + o
elif 3 == len(o):
return "\\" + o
elif 4 == len(o):
assert '0' == o[0]
return "\\" + o[1:]
def cstr_esc(n):
return c_oct(n)
def c_escape(txt):
if None == txt:
return "NULL"
a = []
for c in txt:
if ord(c) <= 0x7f:
a.append(c)
else:
chars = as_utf8(ord(c))
for c2 in chars:
a.append(cstr_esc(c2))
txt = string.join(a,"")
txt.replace("\"", r'\"')
txt = '"%s"' % txt
return txt
def get_trans_for_lang(strings_dict, keys, lang_arg):
trans = []
for k in keys:
vals = strings_dict[k]
txt = None
for v in vals:
(lang, tr) = v
if lang_arg == lang:
txt = tr
trans.append(txt)
return trans
# line append
def lapp(l, txt):
l.append(txt)
#print txt
def gen_cpp_safe_start(l):
lapp(l, "")
lapp(l, "#ifdef __cplusplus")
lapp(l, "extern \"C\"")
lapp(l, "{")
lapp(l, "#endif")
lapp(l, "")
def gen_cpp_safe_stop(l):
lapp(l, "")
lapp(l, "#ifdef __cplusplus")
lapp(l, "}")
lapp(l, "#endif")
lapp(l, "")
def write_lines_to_file(lines, file_name):
txt = string.join(lines, "\n") + "\n"
fo = open(file_name, "wb")
fo.write(txt)
fo.close()
def gen_h_code(strings_dict, file_name):
l = []
lapp(l, "#ifndef TRANSLATIONS_TXT_H__")
lapp(l, "#define TRANSLATIONS_TXT_H__")
gen_cpp_safe_start(l)
lapp(l, "extern int g_transLangsCount;")
lapp(l, "extern const char *g_transLangs[];")
lapp(l, "extern int g_transTranslationsCount;")
lapp(l, "extern const char *g_transTranslations[];")
gen_cpp_safe_stop(l)
lapp(l, "#endif")
write_lines_to_file(l, file_name)
def gen_c_code(strings_dict, file_name):
l = []
default_lang = "en"
langs = get_lang_list(strings_dict)
assert default_lang not in langs
langs = [default_lang] + langs
langs_count = len(langs)
lapp(l, "/* Generated by script gen_c_from_strings_file.py")
lapp(l, " DO NOT EDIT MANUALLY */")
lapp(l, "#ifndef NULL")
lapp(l, "#define NULL 0")
lapp(l, "#endif")
gen_cpp_safe_start(l)
lapp(l, "int g_transLangsCount = %d;" % langs_count)
translations_count = len(strings_dict)
lapp(l, "")
lapp(l, "const char *g_transLangs[] = {")
langs_c = [c_escape(tmp) for tmp in langs]
txt = " %s" % string.join(langs_c, ", ")
lapp(l, txt)
lapp(l, "};")
lapp(l, "")
lapp(l, "int g_transTranslationsCount = %d;\n" % translations_count)
lapp(l, "const char *g_transTranslations[] = {")
keys = strings_dict.keys()
keys.sort()
for t in range(langs_count):
if 0 == t:
trans = keys
else:
lang = langs[t]
trans = get_trans_for_lang(strings_dict, keys, lang)
lapp(l, "")
lapp(l, " /* Translations for language %s */" % langs[t])
trans_c = [" %s," % c_escape(t) for t in trans]
for t in trans_c:
lapp(l, t)
lapp(l, "};")
gen_cpp_safe_stop(l)
write_lines_to_file(l, file_name)
def to_idm(iso): return "IDM_LANG_" + iso.upper().replace("-", "_")
def lang_sort_func(x,y):
# special case: english is first
if x[0] == "en": return -1
if y[0] == "en": return 1
return cmp(x[1], y[1])
def gen_lang_menu_def_h(langs, file_name):
langs.sort(lang_sort_func)
l = []
lapp(l, """
/* Generated by script gen_c_from_strings_file.py
DO NOT EDIT MANUALLY */
#ifndef LANG_MENU_DEF_H__
#define LANG_MENU_DEF_H__
""")
lapp(l, "#define LANGS_COUNT %d" % len(langs))
lapp(l, "")
lapp(l, """
typedef struct MenuDef {
const char *m_title;
int m_id;
int m_flags;
} MenuDef;
typedef struct LangDef {
const char* _langName;
int _langId;
} LangDef;
extern LangDef g_langs[LANGS_COUNT];
extern MenuDef g_menuDefLang[LANGS_COUNT];
""")
lapp(l, "#endif")
write_lines_to_file(l, file_name)
def gen_lang_menu_def_c(langs, file_name):
langs.sort(lang_sort_func)
l = []
lapp(l, """
/* Generated by script gen_c_from_strings_file.py
DO NOT EDIT MANUALLY */
#include "Resource.h"
#include "LangMenuDef.h"
""")
lapp(l, "LangDef g_langs[LANGS_COUNT] = {")
for lang in langs:
lang_iso = lang[0]
lang_name = lang[1]
txt = ' {"' + lang_iso + '", ' + to_idm(lang_iso) + "},"
lapp(l, txt)
lapp(l, "};")
lapp(l, "")
lapp(l, "MenuDef g_menuDefLang[LANGS_COUNT] = {")
for lang in langs:
lang_iso = lang[0]
lang_name = lang[1]
txt = ' { ' + c_escape(lang_name) + ', '
txt += to_idm(lang_iso)
txt += " },"
lapp(l, txt)
lapp(l, "};")
write_lines_to_file(l, file_name)
def gen_code(strings_dict, langs, h_file_name, c_file_name):
gen_h_code(strings_dict, h_file_name)
gen_c_code(strings_dict, c_file_name)
gen_lang_menu_def_c(langs, "LangMenuDef.cpp")
gen_lang_menu_def_h(langs, "LangMenuDef.h")
def main():
(strings_dict, langs) = load_strings_file(strings_file)
h_file_name = "translations_txt.h"
c_file_name = "translations_txt.c"
gen_code(strings_dict, langs, h_file_name, c_file_name)
if __name__ == "__main__":
main()
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?