mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 05:34:39 +08:00
i18n: centralize language definitions
This commit is contained in:
parent
155e535b8a
commit
f99103ede6
3 changed files with 40 additions and 12 deletions
|
|
@ -48,6 +48,8 @@
|
|||
as command arguments.
|
||||
- Full-screen help now uses `l` to cycle the UI language through the i18n
|
||||
module instead of hard-coding one key per language.
|
||||
- Language parsing, language-code output, and help-language cycling now share
|
||||
one internal language registry.
|
||||
- Documented i18n and user-facing text rules for English-first source text,
|
||||
stable command syntax, concise help copy, and translation-only localization.
|
||||
|
||||
|
|
|
|||
48
src/i18n.c
48
src/i18n.c
|
|
@ -2,6 +2,17 @@
|
|||
|
||||
#include <ctype.h>
|
||||
|
||||
typedef struct {
|
||||
ui_lang_t lang;
|
||||
const char *code;
|
||||
const char *prefixes[4];
|
||||
} ui_lang_definition_t;
|
||||
|
||||
static const ui_lang_definition_t ui_lang_defs[] = {
|
||||
{UI_LANG_EN, "en", {"en", "c", "posix", NULL}},
|
||||
{UI_LANG_ZH, "zh", {"zh", NULL}}
|
||||
};
|
||||
|
||||
static const char *skip_space(const char *value) {
|
||||
while (value && *value &&
|
||||
isspace((unsigned char)*value)) {
|
||||
|
|
@ -41,16 +52,15 @@ bool i18n_try_parse_ui_lang(const char *value, ui_lang_t *lang) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (starts_with_lang(value, "zh")) {
|
||||
if (lang) *lang = UI_LANG_ZH;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (starts_with_lang(value, "en") ||
|
||||
starts_with_lang(value, "c") ||
|
||||
starts_with_lang(value, "posix")) {
|
||||
if (lang) *lang = UI_LANG_EN;
|
||||
return true;
|
||||
for (size_t i = 0; i < sizeof(ui_lang_defs) / sizeof(ui_lang_defs[0]); i++) {
|
||||
for (size_t j = 0; ui_lang_defs[i].prefixes[j]; j++) {
|
||||
if (starts_with_lang(value, ui_lang_defs[i].prefixes[j])) {
|
||||
if (lang) {
|
||||
*lang = ui_lang_defs[i].lang;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -82,9 +92,23 @@ ui_lang_t i18n_default_ui_lang(void) {
|
|||
}
|
||||
|
||||
ui_lang_t i18n_next_ui_lang(ui_lang_t lang) {
|
||||
return lang == UI_LANG_EN ? UI_LANG_ZH : UI_LANG_EN;
|
||||
size_t count = sizeof(ui_lang_defs) / sizeof(ui_lang_defs[0]);
|
||||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (ui_lang_defs[i].lang == lang) {
|
||||
return ui_lang_defs[(i + 1) % count].lang;
|
||||
}
|
||||
}
|
||||
|
||||
return ui_lang_defs[0].lang;
|
||||
}
|
||||
|
||||
const char *i18n_ui_lang_code(ui_lang_t lang) {
|
||||
return lang == UI_LANG_ZH ? "zh" : "en";
|
||||
for (size_t i = 0; i < sizeof(ui_lang_defs) / sizeof(ui_lang_defs[0]); i++) {
|
||||
if (ui_lang_defs[i].lang == lang) {
|
||||
return ui_lang_defs[i].code;
|
||||
}
|
||||
}
|
||||
|
||||
return ui_lang_defs[0].code;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,8 +145,10 @@ TEST(text_lookup_matches_language) {
|
|||
"未知命令") != NULL);
|
||||
assert(strcmp(i18n_ui_lang_code(UI_LANG_EN), "en") == 0);
|
||||
assert(strcmp(i18n_ui_lang_code(UI_LANG_ZH), "zh") == 0);
|
||||
assert(strcmp(i18n_ui_lang_code((ui_lang_t)99), "en") == 0);
|
||||
assert(i18n_next_ui_lang(UI_LANG_EN) == UI_LANG_ZH);
|
||||
assert(i18n_next_ui_lang(UI_LANG_ZH) == UI_LANG_EN);
|
||||
assert(i18n_next_ui_lang((ui_lang_t)99) == UI_LANG_EN);
|
||||
}
|
||||
|
||||
TEST(text_catalog_is_complete) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue