26typedef struct translation {
48 const char *env_vars[] = {
"LANGUAGE",
"LC_ALL",
"LC_MESSAGES",
"LANG"};
50 setlocale( LC_ALL,
"" );
53 setlocale( LC_NUMERIC,
"C" );
56 SDL_Locale *locales = SDL_GetPreferredLocales();
57 if (locales != NULL) {
58 if (locales[0].language != NULL) {
67 for (
size_t i=0; i <
sizeof(env_vars)/
sizeof(env_vars[0]); i++) {
68 const char *language = SDL_getenv( env_vars[i] );
69 if (language != NULL && *language != 0) {
128 char root[256], **paths, **available_langs;
137 if (!strcmp( lang, ptrans->language )) {
144 newtrans->
language = strdup( lang );
150 available_langs = PHYSFS_enumerateFiles( GETTEXT_PATH );
155 while (lang != NULL && *lang != 0) {
156 size_t map_size, lang_part_len;
157 const char *lang_part = lang, *lang_match;
158 lang = strchr(lang,
':');
160 lang_part_len = strlen(lang_part);
162 lang_part_len = (size_t)(lang-lang_part);
166 if (lang_match == NULL)
168 snprintf( root,
sizeof(root), GETTEXT_PATH
"%s", lang_match );
171 const char *map =
ndata_read( paths[i], &map_size );
175 DEBUG( _(
"Adding translations from %s"), paths[i] );
181 PHYSFS_freeList( available_langs );
192 const char *best = NULL;
198 for (
size_t i=0; available[i]!=NULL; i++) {
199 int c = strncmp( lang, available[i],
MIN( lang_len, strlen(available[i]) ) );
222 const char *trans =
msgcat_ngettext( &chain[i], msgid, msgid_plural, n );
228 return n>1 && msgid_plural!=NULL ? msgid_plural : msgid;
236 const char *trans = _( lookup );
237 return trans==lookup ? msgid : trans;
267 char **dirs = PHYSFS_enumerateFiles( GETTEXT_PATH );
270 for (
size_t i=0; dirs[i]!=NULL; i++) {
275 PHYSFS_freeList( dirs );
287 uint32_t translated = 0;
288 char **paths, dirpath[
PATH_MAX], buf[12];
291 if (!strcmp( lang,
"en" ))
298 snprintf( dirpath,
sizeof(dirpath), GETTEXT_PATH
"%s", lang );
303 file = PHYSFS_openRead( paths[j] );
307 size = PHYSFS_readBytes( file, buf, 12 );
322 SDL_asprintf( &lookup,
"%s" GETTEXT_CONTEXT_GLUE
"%s", msgctxt, msgid );
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
const char * gettext_ngettext(const char *msgid, const char *msgid_plural, uint64_t n)
Return a translated version of the input, using the current language catalogs.
void gettext_exit(void)
Free resources associated with the translation system. This invalidates previously returned pointers ...
static translation_t * gettext_activeTranslation
double gettext_languageCoverage(const char *lang)
Return the fraction of strings which have a translation into the given language.
void gettext_setLanguage(const char *lang)
Set the translation language.
const char * gettext_getLanguage(void)
Gets the active (primary) translation language. Even in case of a complex locale, this will be the na...
static const char * gettext_matchLanguage(const char *lang, size_t lang_len, char *const *available)
Pick the best match from "available" (a physfs listing) for the string-slice with address lang,...
const char * pgettext_var(const char *msgctxt, const char *msgid)
static void gettext_readStats(void)
Read the GETTEXT_STATS_PATH data and compute gettext_nstrings. (Common case: just a "naev....
static translation_t * gettext_translations
static char * gettext_systemLanguage
LanguageOption * gettext_languageOptions(void)
List the available languages, with completeness statistics.
const char * gettext_getSystemLanguage(void)
Gets the current system language as detected by Naev.
static uint32_t gettext_nstrings
void gettext_init(void)
Initialize the translation system. There's no presumption that PhysicsFS is available,...
const char * gettext_pgettext_impl(const char *lookup, const char *msgid)
Helper function for p_(): Return _(lookup) with a fallback of msgid rather than lookup.
const char * msgcat_ngettext(const msgcat_t *p, const char *msgid1, const char *msgid2, uint64_t n)
Return a translation, if present, from the given message catalog.
void msgcat_init(msgcat_t *p, const void *map, size_t map_size)
Initialize a msgcat_t, given the contents and content-length of a .mo file.
uint32_t msgcat_nstringsFromHeader(const char buf[12])
Return the number of strings in a message catalog, given its first 12 bytes.
Header file with generic functions and naev-specifics.
void * ndata_read(const char *path, size_t *filesize)
Reads a file from the ndata (will be NUL terminated).
char ** ndata_listRecursive(const char *path)
Lists all the visible files in a directory, at any depth.
struct translation * next