mirror of
https://oauth2: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@github.com/m1ngsama/TNT.git
synced 2026-06-26 05:44:38 +08:00
i18n: localize startup cli text
This commit is contained in:
parent
fd6cdbf627
commit
73655d0e70
7 changed files with 157 additions and 21 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -16,3 +16,4 @@ tests/unit/test_i18n
|
|||
tests/unit/test_system_message
|
||||
tests/unit/test_help_text
|
||||
tests/unit/test_support_text
|
||||
tests/unit/test_cli_text
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
- Exec-mode help, usage errors, unknown-command feedback, and post validation
|
||||
messages now follow `TNT_LANG` while preserving stable machine-readable
|
||||
command output.
|
||||
- Startup CLI help and option errors now live in a dedicated `cli_text` module
|
||||
and follow `TNT_LANG` / locale for English and Chinese users.
|
||||
|
||||
### Changed
|
||||
- NORMAL mode now opens at the latest visible messages instead of the oldest
|
||||
|
|
|
|||
12
include/cli_text.h
Normal file
12
include/cli_text.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef CLI_TEXT_H
|
||||
#define CLI_TEXT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void cli_text_append_help(char *buffer, size_t buf_size, size_t *pos,
|
||||
const char *program_name, help_lang_t lang);
|
||||
const char *cli_text_invalid_port_format(help_lang_t lang);
|
||||
const char *cli_text_unknown_option_format(help_lang_t lang);
|
||||
const char *cli_text_short_usage_format(help_lang_t lang);
|
||||
|
||||
#endif /* CLI_TEXT_H */
|
||||
62
src/cli_text.c
Normal file
62
src/cli_text.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#include "cli_text.h"
|
||||
|
||||
void cli_text_append_help(char *buffer, size_t buf_size, size_t *pos,
|
||||
const char *program_name, help_lang_t lang) {
|
||||
const char *program = (program_name && program_name[0] != '\0')
|
||||
? program_name
|
||||
: "tnt";
|
||||
|
||||
if (lang == LANG_ZH) {
|
||||
buffer_appendf(buffer, buf_size, pos,
|
||||
"tnt %s - 匿名 SSH 聊天服务器\n\n"
|
||||
"用法: %s [选项]\n\n"
|
||||
"选项:\n"
|
||||
" -p, --port PORT 监听 PORT (默认: %d)\n"
|
||||
" -d, --state-dir DIR 将主机密钥和日志存放在 DIR\n"
|
||||
" -V, --version 显示版本\n"
|
||||
" -h, --help 显示此帮助\n"
|
||||
"\n"
|
||||
"环境变量:\n"
|
||||
" PORT 默认监听端口\n"
|
||||
" TNT_STATE_DIR 状态目录\n"
|
||||
" TNT_ACCESS_TOKEN 要求 SSH 认证使用此密码\n"
|
||||
" TNT_LANG UI 语言: en 或 zh (默认跟随 locale)\n"
|
||||
" TNT_MAX_CONNECTIONS 全局连接数限制 (默认: 64)\n"
|
||||
" TNT_RATE_LIMIT 设为 0 可禁用速率限制\n"
|
||||
" TNT_IDLE_TIMEOUT 空闲断开时间,单位秒 (默认: 1800)\n",
|
||||
TNT_VERSION, program, DEFAULT_PORT);
|
||||
return;
|
||||
}
|
||||
|
||||
buffer_appendf(buffer, buf_size, pos,
|
||||
"tnt %s - anonymous SSH chat server\n\n"
|
||||
"Usage: %s [options]\n\n"
|
||||
"Options:\n"
|
||||
" -p, --port PORT Listen on PORT (default: %d)\n"
|
||||
" -d, --state-dir DIR Store host key and logs in DIR\n"
|
||||
" -V, --version Show version\n"
|
||||
" -h, --help Show this help\n"
|
||||
"\n"
|
||||
"Environment:\n"
|
||||
" PORT Default listening port\n"
|
||||
" TNT_STATE_DIR State directory\n"
|
||||
" TNT_ACCESS_TOKEN Require this password for SSH auth\n"
|
||||
" TNT_LANG UI language: en or zh (default: locale)\n"
|
||||
" TNT_MAX_CONNECTIONS Global connection limit (default: 64)\n"
|
||||
" TNT_RATE_LIMIT Set to 0 to disable rate limiting\n"
|
||||
" TNT_IDLE_TIMEOUT Idle disconnect timeout in seconds (default: 1800)\n",
|
||||
TNT_VERSION, program, DEFAULT_PORT);
|
||||
}
|
||||
|
||||
const char *cli_text_invalid_port_format(help_lang_t lang) {
|
||||
return lang == LANG_ZH ? "端口无效: %s\n" : "Invalid port: %s\n";
|
||||
}
|
||||
|
||||
const char *cli_text_unknown_option_format(help_lang_t lang) {
|
||||
return lang == LANG_ZH ? "未知选项: %s\n" : "Unknown option: %s\n";
|
||||
}
|
||||
|
||||
const char *cli_text_short_usage_format(help_lang_t lang) {
|
||||
return lang == LANG_ZH ? "用法: %s [-p PORT] [-d DIR] [-h]\n"
|
||||
: "Usage: %s [-p PORT] [-d DIR] [-h]\n";
|
||||
}
|
||||
34
src/main.c
34
src/main.c
|
|
@ -1,7 +1,9 @@
|
|||
#include "common.h"
|
||||
#include "ssh_server.h"
|
||||
#include "chat_room.h"
|
||||
#include "cli_text.h"
|
||||
#include "common.h"
|
||||
#include "i18n.h"
|
||||
#include "message.h"
|
||||
#include "ssh_server.h"
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
|
@ -18,6 +20,7 @@ static void signal_handler(int sig) {
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
int port = DEFAULT_PORT;
|
||||
help_lang_t lang = i18n_default_lang();
|
||||
|
||||
/* Environment provides defaults; command-line flags override it. */
|
||||
const char *port_env = getenv("PORT");
|
||||
|
|
@ -36,7 +39,8 @@ int main(int argc, char **argv) {
|
|||
char *end;
|
||||
long val = strtol(argv[i + 1], &end, 10);
|
||||
if (*end != '\0' || val <= 0 || val > 65535) {
|
||||
fprintf(stderr, "Invalid port: %s\n", argv[i + 1]);
|
||||
fprintf(stderr, cli_text_invalid_port_format(lang),
|
||||
argv[i + 1]);
|
||||
return 1;
|
||||
}
|
||||
port = (int)val;
|
||||
|
|
@ -52,25 +56,15 @@ int main(int argc, char **argv) {
|
|||
printf("tnt %s\n", TNT_VERSION);
|
||||
return 0;
|
||||
} else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
|
||||
printf("tnt %s - anonymous SSH chat server\n\n", TNT_VERSION);
|
||||
printf("Usage: %s [options]\n\n", argv[0]);
|
||||
printf("Options:\n");
|
||||
printf(" -p, --port PORT Listen on PORT (default: %d)\n", DEFAULT_PORT);
|
||||
printf(" -d, --state-dir DIR Store host key and logs in DIR\n");
|
||||
printf(" -V, --version Show version\n");
|
||||
printf(" -h, --help Show this help\n");
|
||||
printf("\nEnvironment:\n");
|
||||
printf(" PORT Default listening port\n");
|
||||
printf(" TNT_STATE_DIR State directory\n");
|
||||
printf(" TNT_ACCESS_TOKEN Require this password for SSH auth\n");
|
||||
printf(" TNT_LANG UI language: en or zh (default: locale)\n");
|
||||
printf(" TNT_MAX_CONNECTIONS Global connection limit (default: 64)\n");
|
||||
printf(" TNT_RATE_LIMIT Set to 0 to disable rate limiting\n");
|
||||
printf(" TNT_IDLE_TIMEOUT Idle disconnect timeout in seconds (default: 1800)\n");
|
||||
char output[2048] = {0};
|
||||
size_t pos = 0;
|
||||
|
||||
cli_text_append_help(output, sizeof(output), &pos, argv[0], lang);
|
||||
fputs(output, stdout);
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown option: %s\n", argv[i]);
|
||||
fprintf(stderr, "Usage: %s [-p PORT] [-d DIR] [-h]\n", argv[0]);
|
||||
fprintf(stderr, cli_text_unknown_option_format(lang), argv[i]);
|
||||
fprintf(stderr, cli_text_short_usage_format(lang), argv[0]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ endif
|
|||
UTF8_SRC = ../../src/utf8.c
|
||||
MESSAGE_SRC = ../../src/message.c
|
||||
COMMON_SRC = ../../src/common.c
|
||||
CLI_TEXT_SRC = ../../src/cli_text.c
|
||||
CHAT_ROOM_SRC = ../../src/chat_room.c
|
||||
HISTORY_VIEW_SRC = ../../src/history_view.c
|
||||
I18N_SRC = ../../src/i18n.c
|
||||
|
|
@ -20,7 +21,7 @@ SYSTEM_MESSAGE_SRC = ../../src/system_message.c
|
|||
HELP_TEXT_SRC = ../../src/help_text.c
|
||||
SUPPORT_TEXT_SRC = ../../src/support_text.c
|
||||
|
||||
TESTS = test_utf8 test_message test_chat_room test_history_view test_i18n test_system_message test_help_text test_support_text
|
||||
TESTS = test_utf8 test_message test_chat_room test_history_view test_i18n test_system_message test_help_text test_support_text test_cli_text
|
||||
|
||||
.PHONY: all clean run
|
||||
|
||||
|
|
@ -50,6 +51,9 @@ test_help_text: test_help_text.c $(HELP_TEXT_SRC) $(COMMON_SRC)
|
|||
test_support_text: test_support_text.c $(SUPPORT_TEXT_SRC)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
test_cli_text: test_cli_text.c $(CLI_TEXT_SRC) $(COMMON_SRC)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
||||
|
||||
run: all
|
||||
@echo "=== Running UTF-8 Tests ==="
|
||||
./test_utf8
|
||||
|
|
@ -74,6 +78,9 @@ run: all
|
|||
@echo ""
|
||||
@echo "=== Running Support Text Tests ==="
|
||||
./test_support_text
|
||||
@echo ""
|
||||
@echo "=== Running CLI Text Tests ==="
|
||||
./test_cli_text
|
||||
|
||||
clean:
|
||||
rm -f $(TESTS) *.o test_messages.log
|
||||
|
|
|
|||
58
tests/unit/test_cli_text.c
Normal file
58
tests/unit/test_cli_text.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* Unit tests for command-line help and error text */
|
||||
|
||||
#include "../../include/cli_text.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TEST(name) static void test_##name()
|
||||
#define RUN_TEST(name) do { \
|
||||
printf("Running %s... ", #name); \
|
||||
test_##name(); \
|
||||
printf("✓\n"); \
|
||||
tests_passed++; \
|
||||
} while(0)
|
||||
|
||||
static int tests_passed = 0;
|
||||
|
||||
TEST(help_matches_language) {
|
||||
char output[2048] = {0};
|
||||
size_t pos = 0;
|
||||
|
||||
cli_text_append_help(output, sizeof(output), &pos, "tnt", LANG_EN);
|
||||
assert(strstr(output, "anonymous SSH chat server") != NULL);
|
||||
assert(strstr(output, "Usage: tnt [options]") != NULL);
|
||||
assert(strstr(output, "TNT_LANG") != NULL);
|
||||
|
||||
memset(output, 0, sizeof(output));
|
||||
pos = 0;
|
||||
cli_text_append_help(output, sizeof(output), &pos, "tnt", LANG_ZH);
|
||||
assert(strstr(output, "匿名 SSH 聊天服务器") != NULL);
|
||||
assert(strstr(output, "用法: tnt [选项]") != NULL);
|
||||
assert(strstr(output, "TNT_LANG") != NULL);
|
||||
}
|
||||
|
||||
TEST(error_formats_match_language) {
|
||||
assert(strcmp(cli_text_invalid_port_format(LANG_EN),
|
||||
"Invalid port: %s\n") == 0);
|
||||
assert(strcmp(cli_text_invalid_port_format(LANG_ZH),
|
||||
"端口无效: %s\n") == 0);
|
||||
assert(strcmp(cli_text_unknown_option_format(LANG_EN),
|
||||
"Unknown option: %s\n") == 0);
|
||||
assert(strcmp(cli_text_unknown_option_format(LANG_ZH),
|
||||
"未知选项: %s\n") == 0);
|
||||
assert(strcmp(cli_text_short_usage_format(LANG_EN),
|
||||
"Usage: %s [-p PORT] [-d DIR] [-h]\n") == 0);
|
||||
assert(strcmp(cli_text_short_usage_format(LANG_ZH),
|
||||
"用法: %s [-p PORT] [-d DIR] [-h]\n") == 0);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
printf("Running CLI text unit tests...\n\n");
|
||||
|
||||
RUN_TEST(help_matches_language);
|
||||
RUN_TEST(error_formats_match_language);
|
||||
|
||||
printf("\n✓ All %d tests passed!\n", tests_passed);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in a new issue