i18n: index text catalog by language

This commit is contained in:
m1ngsama 2026-05-24 15:20:01 +08:00
parent 69d3b76512
commit 46f5780057
5 changed files with 18 additions and 8 deletions

View file

@ -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.

View file

@ -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 */

View file

@ -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 &&

View file

@ -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 "";
}

View file

@ -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),