From 46f57800576a9c3c69e607ff6e8c340081bde110 Mon Sep 17 00:00:00 2001 From: m1ngsama Date: Sun, 24 May 2026 15:20:01 +0800 Subject: [PATCH] i18n: index text catalog by language --- docs/CHANGELOG.md | 2 ++ include/common.h | 3 ++- src/i18n.c | 2 ++ src/i18n_text.c | 17 ++++++++++------- tests/unit/test_i18n.c | 2 ++ 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f945963..82b42c4 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -52,6 +52,8 @@ one internal language registry. - Removed the unused `MODE_HELP` enum value and refreshed development-guide module descriptions for the split between language parsing and text lookup. +- `i18n_text` now indexes localized strings by `UI_LANG_*` instead of storing + English/Chinese as hard-coded struct fields. - Documented i18n and user-facing text rules for English-first source text, stable command syntax, concise help copy, and translation-only localization. diff --git a/include/common.h b/include/common.h index bbdff97..14ba70f 100644 --- a/include/common.h +++ b/include/common.h @@ -46,7 +46,8 @@ typedef enum { /* UI language */ typedef enum { UI_LANG_EN, - UI_LANG_ZH + UI_LANG_ZH, + UI_LANG_COUNT } ui_lang_t; /* Runtime helpers */ diff --git a/src/i18n.c b/src/i18n.c index 850d01f..8a06c4c 100644 --- a/src/i18n.c +++ b/src/i18n.c @@ -12,6 +12,8 @@ static const ui_lang_definition_t ui_lang_defs[] = { {UI_LANG_EN, "en", {"en", "c", "posix", NULL}}, {UI_LANG_ZH, "zh", {"zh", NULL}} }; +typedef char ui_lang_defs_must_cover_enum[ + sizeof(ui_lang_defs) / sizeof(ui_lang_defs[0]) == UI_LANG_COUNT ? 1 : -1]; static const char *skip_space(const char *value) { while (value && *value && diff --git a/src/i18n_text.c b/src/i18n_text.c index cfe5368..6221972 100644 --- a/src/i18n_text.c +++ b/src/i18n_text.c @@ -1,8 +1,7 @@ #include "i18n.h" typedef struct { - const char *en; - const char *zh; + const char *text[UI_LANG_COUNT]; } i18n_text_entry_t; static const i18n_text_entry_t text_catalog[I18N_TEXT_COUNT] = { @@ -209,12 +208,16 @@ const char *i18n_text(ui_lang_t lang, i18n_text_id_t id) { return ""; } - const i18n_text_entry_t *entry = &text_catalog[id]; - if (lang == UI_LANG_ZH && entry->zh) { - return entry->zh; + if ((int)lang < 0 || lang >= UI_LANG_COUNT) { + lang = UI_LANG_EN; } - if (entry->en) { - return entry->en; + + const i18n_text_entry_t *entry = &text_catalog[id]; + if (entry->text[lang]) { + return entry->text[lang]; + } + if (entry->text[UI_LANG_EN]) { + return entry->text[UI_LANG_EN]; } return ""; } diff --git a/tests/unit/test_i18n.c b/tests/unit/test_i18n.c index 5fa2a7d..4c0af8c 100644 --- a/tests/unit/test_i18n.c +++ b/tests/unit/test_i18n.c @@ -83,6 +83,8 @@ TEST(text_lookup_matches_language) { "display name") != NULL); assert(strstr(i18n_text(UI_LANG_ZH, I18N_USERNAME_PROMPT), "用户名") != NULL); + assert(strstr(i18n_text((ui_lang_t)99, I18N_USERNAME_PROMPT), + "display name") != NULL); assert(strstr(i18n_text(UI_LANG_EN, I18N_WELCOME_SUBTITLE), "anonymous chat") != NULL); assert(strstr(i18n_text(UI_LANG_ZH, I18N_WELCOME_SUBTITLE),