diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 8127228..4e4dac1 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -10,6 +10,8 @@ usage text now uses ASCII metavariables such as `` and ``. - Standardized user-facing `:msg` / `:inbox` terminology around "private message" / "私信" instead of mixing it with "whisper" wording. +- Kept localized startup CLI syntax stable by using `用法: tnt [options]` + instead of localizing the `[options]` metavariable. - Renamed the internal language state from help-oriented names to UI-language names (`ui_lang_t`, `client->ui_lang`, and `i18n_*_ui_lang`) so future i18n work has a correctly named seam. diff --git a/src/cli_text.c b/src/cli_text.c index 87f8249..6c2802f 100644 --- a/src/cli_text.c +++ b/src/cli_text.c @@ -9,7 +9,7 @@ void cli_text_append_help(char *buffer, size_t buf_size, size_t *pos, if (lang == UI_LANG_ZH) { buffer_appendf(buffer, buf_size, pos, "tnt %s - 匿名 SSH 聊天服务器\n\n" - "用法: %s [选项]\n\n" + "用法: %s [options]\n\n" "选项:\n" " -p, --port PORT 监听 PORT (默认: %d)\n" " -d, --state-dir DIR 将主机密钥和日志存放在 DIR\n" diff --git a/tests/unit/test_cli_text.c b/tests/unit/test_cli_text.c index ff972a6..048f504 100644 --- a/tests/unit/test_cli_text.c +++ b/tests/unit/test_cli_text.c @@ -28,7 +28,8 @@ TEST(help_matches_language) { pos = 0; cli_text_append_help(output, sizeof(output), &pos, "tnt", UI_LANG_ZH); assert(strstr(output, "匿名 SSH 聊天服务器") != NULL); - assert(strstr(output, "用法: tnt [选项]") != NULL); + assert(strstr(output, "用法: tnt [options]") != NULL); + assert(strstr(output, "[选项]") == NULL); assert(strstr(output, "TNT_LANG") != NULL); } diff --git a/tests/unit/test_command_catalog.c b/tests/unit/test_command_catalog.c index dce3e40..5445a9c 100644 --- a/tests/unit/test_command_catalog.c +++ b/tests/unit/test_command_catalog.c @@ -1,6 +1,7 @@ /* Unit tests for command catalog names, aliases, and generated help text */ #include "../../include/command_catalog.h" +#include "text_assert.h" #include #include #include @@ -77,6 +78,7 @@ TEST(generates_localized_help_sections) { assert(strstr(zh, "<用户>") == NULL); assert(strstr(zh, "<消息>") == NULL); assert(strstr(zh, ":support") == NULL); + assert_ascii_angle_placeholders(zh); } int main(void) { diff --git a/tests/unit/test_help_text.c b/tests/unit/test_help_text.c index 1bc3a0d..7589746 100644 --- a/tests/unit/test_help_text.c +++ b/tests/unit/test_help_text.c @@ -1,6 +1,7 @@ /* Unit tests for help text ownership and language selection */ #include "../../include/help_text.h" +#include "text_assert.h" #include #include #include @@ -43,6 +44,7 @@ TEST(full_help_matches_language) { assert(strstr(zh, ":support") == NULL); assert(strstr(zh, ":commands") == NULL); assert(strstr(zh, "切换英文/中文") != NULL); + assert_ascii_angle_placeholders(zh); } int main(void) { diff --git a/tests/unit/test_i18n.c b/tests/unit/test_i18n.c index 7870f6a..e2f6a82 100644 --- a/tests/unit/test_i18n.c +++ b/tests/unit/test_i18n.c @@ -1,6 +1,7 @@ /* Unit tests for i18n language selection and text lookup */ #include "../../include/i18n.h" +#include "text_assert.h" #include #include #include @@ -164,6 +165,8 @@ TEST(text_catalog_is_complete) { for (int id = 0; id < I18N_TEXT_COUNT; id++) { assert(i18n_text(UI_LANG_EN, (i18n_text_id_t)id)[0] != '\0'); assert(i18n_text(UI_LANG_ZH, (i18n_text_id_t)id)[0] != '\0'); + assert_ascii_angle_placeholders( + i18n_text(UI_LANG_ZH, (i18n_text_id_t)id)); } assert(strcmp(i18n_text(UI_LANG_EN, diff --git a/tests/unit/test_manual_text.c b/tests/unit/test_manual_text.c index 47b8730..cec002d 100644 --- a/tests/unit/test_manual_text.c +++ b/tests/unit/test_manual_text.c @@ -1,6 +1,7 @@ /* Unit tests for concise manual text language selection */ #include "../../include/manual_text.h" +#include "text_assert.h" #include #include #include @@ -58,6 +59,7 @@ TEST(interactive_manual_matches_language) { assert(strstr(zh, ":support") == NULL); assert(strstr(zh, ":commands") == NULL); assert(count_lines(zh) <= 20); + assert_ascii_angle_placeholders(zh); } int main(void) { diff --git a/tests/unit/text_assert.h b/tests/unit/text_assert.h new file mode 100644 index 0000000..14e16cd --- /dev/null +++ b/tests/unit/text_assert.h @@ -0,0 +1,24 @@ +#ifndef TEST_TEXT_ASSERT_H +#define TEST_TEXT_ASSERT_H + +#include + +static void assert_ascii_angle_placeholders(const char *text) { + int in_placeholder = 0; + + while (text && *text) { + unsigned char ch = (unsigned char)*text; + + if (ch == '<') { + in_placeholder = 1; + } else if (ch == '>') { + in_placeholder = 0; + } else if (in_placeholder) { + assert(ch < 128); + } + + text++; + } +} + +#endif /* TEST_TEXT_ASSERT_H */