diff options
author | Lukas Fleischer <calcurse@cryptocrack.de> | 2013-08-27 19:32:02 +0200 |
---|---|---|
committer | Lukas Fleischer <calcurse@cryptocrack.de> | 2013-08-27 19:33:28 +0200 |
commit | bd4f4a136fc218f0854f5ee5219149ce5b0acdb3 (patch) | |
tree | 204a702d6a68939edc4b816ef481c6542cdbe807 | |
parent | ef0f9e64118559f58e2a4c830d3247b464b6345c (diff) | |
download | calcurse-bd4f4a136fc218f0854f5ee5219149ce5b0acdb3.zip |
Display translated help pages
Use an algorithm similar to gettext's locale resolution to find an
appropriate translation to display. Fall back to the English version.
Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
-rw-r--r-- | src/calcurse.h | 1 | ||||
-rw-r--r-- | src/help.c | 59 | ||||
-rw-r--r-- | src/io.c | 7 |
3 files changed, 64 insertions, 3 deletions
diff --git a/src/calcurse.h b/src/calcurse.h index 38b18e1..6333946 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -757,6 +757,7 @@ void io_load_app(void); void io_load_todo(void); void io_load_keys(const char *); int io_check_dir(const char *); +unsigned io_dir_exists(const char *); unsigned io_file_exists(const char *); int io_check_file(const char *); int io_check_data_files(void); @@ -36,21 +36,74 @@ #include "calcurse.h" +static int find_basedir(const char *locale_info[], unsigned n, char *basedir) +{ + int i; + char *locale = NULL; + int ret = 0; + + for (i = 0; i < n; i++) { + if (!locale_info[i]) + continue; + locale = strdup(locale_info[i]); + + snprintf(basedir, BUFSIZ, DOCDIR "/%s", locale); + if (io_dir_exists(basedir)) { + ret = 1; + goto cleanup; + } + + strtok(locale, ".@"); + + snprintf(basedir, BUFSIZ, DOCDIR "/%s", locale); + if (io_dir_exists(basedir)) { + ret = 1; + goto cleanup; + } + + strtok(locale, "_"); + + snprintf(basedir, BUFSIZ, DOCDIR "/%s", locale); + if (io_dir_exists(basedir)) { + ret = 1; + goto cleanup; + } + + free(locale); + locale = NULL; + } + +cleanup: + if (locale) + free(locale); + return ret; +} + int display_help(const char *topic) { + const char *locale_info[] = { + getenv("LANGUAGE"), + getenv("LC_ALL"), + getenv("LC_MESSAGE"), + getenv("LANG") + }; + char basedir[BUFSIZ]; char path[BUFSIZ]; if (!topic) topic = "intro"; - snprintf(path, BUFSIZ, DOCDIR "/%s.txt", topic); + if (!find_basedir(locale_info, ARRAY_SIZE(locale_info), basedir)) + snprintf(basedir, BUFSIZ, DOCDIR); + + snprintf(path, BUFSIZ, "%s/%s.txt", basedir, topic); if (!io_file_exists(path) && keys_str2int(topic) > 0 && keys_get_action(keys_str2int(topic)) > 0) { int ch = keys_str2int(topic); enum key action = keys_get_action(ch); topic = keys_get_label(action); - snprintf(path, BUFSIZ, DOCDIR "/%s.txt", topic); + snprintf(path, BUFSIZ, "%s/%s.txt", basedir, topic); } if (!io_file_exists(path)) { @@ -132,7 +185,7 @@ int display_help(const char *topic) topic = "priority"; else if (!strcmp(topic, "lower-priority")) topic = "priority"; - snprintf(path, BUFSIZ, DOCDIR "/%s.txt", topic); + snprintf(path, BUFSIZ, "%s/%s.txt", basedir, topic); } if (io_file_exists(path)) { @@ -872,6 +872,13 @@ int io_check_dir(const char *dir) } } +unsigned io_dir_exists(const char *path) +{ + struct stat st; + + return (!stat(path, &st) && S_ISDIR(st.st_mode)); +} + unsigned io_file_exists(const char *file) { FILE *fd; |