#include "config.h" #include #include #include #include #include #include #include "logerr.h" #include "catalog.h" static const char *const CATALOG_NAME = NAME; static nl_catd catalog_descriptor = NULL; static const char *const NLSPATH = LOCALEDIR "/%l_%t/LC_MESSAGES/%N.cat" ":" LOCALEDIR "/%l/LC_MESSAGES/%N.cat"; static const char *const NLSPATH_KEY = "NLSPATH"; int i18n_init(void) { int rc = -1; static const int should_overwrite = 0; if (setenv(NLSPATH_KEY, NLSPATH, should_overwrite)) { logerr("setenv(\"%s\", \"%s\", 0): %s\n", NLSPATH_KEY, NLSPATH, strerror(errno)); goto out; } catalog_descriptor = catopen(CATALOG_NAME, 0); if (catalog_descriptor != NULL && catalog_descriptor == (nl_catd)-1) { logerr("catopen(\"%s\", 0): %s\n", CATALOG_NAME, strerror(errno)); catalog_descriptor = NULL; goto out; } rc = 0; out: return rc; } int i18n_destroy(void) { int rc = -1; if (catalog_descriptor != NULL) { if (catclose(catalog_descriptor)) { logerr("catclose(...): %s\n", strerror(errno)); goto out; } } rc = 0; out: if (catalog_descriptor != NULL) { catalog_descriptor = NULL; } return rc; } /** * Infallible: always returns a valid string, no matter what. */ const char * s(const char* const MSGS[], const int msg_id) { assert(msg_id > 0); // FIXME: assert within bounds! // printf("sizeof(MSGS): %ld\n", sizeof(MSGS)); if (catalog_descriptor == NULL) { return MSGS[msg_id]; } errno = 0; const char *const ret = catgets(catalog_descriptor, NL_SETD, msg_id, MSGS[msg_id]); if (errno) { logerr("catgets(%d): %s\n", msg_id, strerror(errno)); } return ret; } int s_print_msgs( const char *const MSGS[], FILE *restrict stream, const int msg_begin, const int msg_end ) { int rc = -1; for (int i = msg_begin; i <= msg_end; i++) { if (fprintf(stream, "%s", s(MSGS, i)) < 0) { logerr("fprintf(stream, \"%%s\", _(%d)): %s\n", i, strerror(errno)); goto out; } } rc = 0; out: return rc; } int s_print_msg(const char *const MSGS[], FILE *const fd, const int msg_id) { return s_print_msgs(MSGS, fd, msg_id, msg_id); } int dump_translatable_strings(const char *const MSGS[]) { int rc = -1; for (size_t i = 1; MSGS[i]; i++) { if (printf("%ld ", i) < 0) { logerr("printf(\"%%ld\", %d): %s\n", i); goto out; } for (size_t j = 0; MSGS[i][j]; j++) { if (MSGS[i][j] == '\n') { if (printf("\\n") < 0) { logerr("printf(\"\\\\n\"): %s\n", strerror(errno)); goto out; } } else { if (printf("%c", MSGS[i][j]) < 0) { logerr("printf(\"%%c\", " "MSGS[%ld][%ld]): %s\n", i, j, strerror(errno)); goto out; } } } if (printf("\n\n") < 0) { logerr("printf(\"\\n\\n\"): %s\n", strerror(errno)); goto out; } } rc = 0; out: return rc; }