From db4ad99ad8bd801204ebf05043b44e8978c8ce47 Mon Sep 17 00:00:00 2001 From: Albert Cahalan Date: Sun, 22 Nov 2009 09:46:41 +0000 Subject: [PATCH] lang/locale work much better now --- src/i18n.c | 68 ++++++++++++++++++++++++++++++++++++------------- src/parse.gperf | 1 + src/parse.h | 1 + src/tuxpaint.c | 34 +++++++++++++++++++++++++ 4 files changed, 86 insertions(+), 18 deletions(-) diff --git a/src/i18n.c b/src/i18n.c index f7d2627c7..b4bfaa646 100644 --- a/src/i18n.c +++ b/src/i18n.c @@ -517,12 +517,14 @@ int get_current_language(void) return langint; } +#ifdef ABUSE_ENV static void abuse_env(const char *restrict name, const char *restrict value) { char s[40]; snprintf(s, sizeof s, "%s=%s", name, value); putenv(strdup(s)); } +#endif static int search_int_array(int l, int *array) { @@ -564,7 +566,7 @@ static const char *language_to_locale(const char *langstr) show_lang_usage(59); } -void set_langint_from_locale_string(const char *restrict loc) +static void set_langint_from_locale_string(const char *restrict loc) { if (!loc) return; @@ -604,13 +606,15 @@ void set_langint_from_locale_string(const char *restrict loc) } } -static int set_current_language(void) MUST_CHECK; -static int set_current_language(void) +static int set_current_language(const char *restrict locale_choice) MUST_CHECK; +static int set_current_language(const char *restrict loc) { - char *loc; int i; int y_nudge = 0; + setlocale(LC_ALL, loc); + ctype_utf8(); + bindtextdomain("tuxpaint", LOCALEDIR); /* Old version of glibc does not have bind_textdomain_codeset() */ #if defined __GLIBC__ && __GLIBC__ == 2 && __GLIBC_MINOR__ >=2 || __GLIBC__ > 2 || __APPLE__ @@ -620,20 +624,28 @@ static int set_current_language(void) #ifdef _WIN32 bind_textdomain_codeset("tuxpaint", "UTF-8"); +#ifdef ABUSE_ENV loc = getenv("LANGUAGE"); if (!loc) +#else + if (!*loc) +#endif { loc = _nl_locale_name(LC_MESSAGES, ""); +#ifdef ABUSE_ENV if (loc) abuse_env("LANGUAGE",loc); +#endif } #else // NULL: Used to direct setlocale() to query the current // internationalised environment and return the name of the locale(). loc = setlocale(LC_MESSAGES, NULL); +#ifdef ABUSE_ENV if (loc && strstr(loc, "LC_MESSAGES")) loc = getenv("LANG"); +#endif #endif set_langint_from_locale_string(loc); @@ -642,8 +654,8 @@ static int set_current_language(void) short_lang_prefix = strdup(lang_prefix); /* When in doubt, cut off country code */ - if (strchr(short_lang_prefix, '_') != NULL) - strcpy(strchr(short_lang_prefix, '_'), "\0"); + if (strchr(short_lang_prefix, '_')) + *strchr(short_lang_prefix, '_') = '\0'; need_own_font = search_int_array(langint, lang_use_own_font); need_right_to_left = search_int_array(langint, lang_use_right_to_left); @@ -672,7 +684,7 @@ static int set_current_language(void) return y_nudge; } - +#ifdef ABUSE_ENV int setup_i18n(const char *restrict lang, const char *restrict locale) { printf("lang %p, locale %p\n", lang, locale); @@ -685,7 +697,6 @@ int setup_i18n(const char *restrict lang, const char *restrict locale) exit(0); } abuse_env("LANG",locale); - setlocale(LC_ALL, ""); /* use arg ? */ } if(lang) { @@ -693,21 +704,42 @@ int setup_i18n(const char *restrict lang, const char *restrict locale) abuse_env("LANGUAGE",newlocale); abuse_env("LC_ALL",newlocale); - - // Specifies an implementation-dependent native environment. - // For XSI-conformant systems, this corresponds to the value - // of the associated environment variables, LC_* and LANG - setlocale(LC_ALL, ""); } - ctype_utf8(); - return set_current_language(); + // The "" is being passed to setlocale. + // It specifies an implementation-dependent native environment. + // For XSI-conformant systems, this corresponds to the value + // of the associated environment variables, LC_* and LANG + return set_current_language(""); } +#else +int setup_i18n(const char *restrict lang, const char *restrict locale) +{ + printf("lang %p, locale %p\n", lang, locale); + printf("lang \"%s\", locale \"%s\"\n", lang, locale); + + if(locale) + { + if(!strcmp(locale,"help")) + { + show_locale_usage(stdout,"tuxpaint"); + exit(0); + } + } + else + locale = ""; + + if(lang) + locale = language_to_locale(lang); + + return set_current_language(locale); +} +#endif int smash_i18n(void) { +#ifdef ABUSE_ENV putenv((char *) "LANG=C"); putenv((char *) "OUTPUT_CHARSET=C"); - setlocale(LC_ALL, "C"); - ctype_utf8(); - return set_current_language(); +#endif + return set_current_language("C"); } diff --git a/src/parse.gperf b/src/parse.gperf index c76177dd7..c677c3b12 100644 --- a/src/parse.gperf +++ b/src/parse.gperf @@ -16,6 +16,7 @@ const char PARSE_YES[] = "yes"; const char PARSE_NO[] = "no"; +const char PARSE_CLOBBER[] = ":-("; // for painful lang/locale priority situation struct cfg { diff --git a/src/parse.h b/src/parse.h index ceb57ee0f..8b11a0538 100644 --- a/src/parse.h +++ b/src/parse.h @@ -3,6 +3,7 @@ extern const char PARSE_YES[]; extern const char PARSE_NO[]; +extern const char PARSE_CLOBBER[]; struct cfginfo { diff --git a/src/tuxpaint.c b/src/tuxpaint.c index 57fb7d0a8..7d226d6f3 100644 --- a/src/tuxpaint.c +++ b/src/tuxpaint.c @@ -18945,6 +18945,20 @@ static void parse_file_options(struct cfginfo *restrict tmpcfg, const char *file parse_one_option(tmpcfg,str,strdup(arg),filename); } fclose(fi); + + // These interact in horrid ways. + if(tmpcfg->parsertmp_lang && tmpcfg->parsertmp_locale) + fprintf( + stderr, + "Warning: option 'lang=%s' overrides option 'locale=%s' in '%s'\n", + tmpcfg->parsertmp_lang, + tmpcfg->parsertmp_locale, + filename + ); + if(tmpcfg->parsertmp_lang) + tmpcfg->parsertmp_locale = PARSE_CLOBBER; + else if(tmpcfg->parsertmp_locale) + tmpcfg->parsertmp_lang = PARSE_CLOBBER; } static void parse_argv_options(struct cfginfo *restrict tmpcfg, char *argv[]) @@ -18989,6 +19003,22 @@ static void parse_argv_options(struct cfginfo *restrict tmpcfg, char *argv[]) fprintf(stderr, "%s is not understood\n", *argv); show_usage(63); } + + // These interact in horrid ways. + if(tmpcfg->parsertmp_lang && tmpcfg->parsertmp_locale) + { + fprintf( + stderr, + "Error: command line option '--lang=%s' overrides option '--locale=%s'\n", + tmpcfg->parsertmp_lang, + tmpcfg->parsertmp_locale + ); + exit(92); + } + if(tmpcfg->parsertmp_lang) + tmpcfg->parsertmp_locale = PARSE_CLOBBER; + else if(tmpcfg->parsertmp_locale) + tmpcfg->parsertmp_lang = PARSE_CLOBBER; } // merge two configs, with the winner taking priority @@ -19091,6 +19121,10 @@ static void setup_config(char *argv[]) datadir = tmpcfg.datadir ? tmpcfg.datadir : savedir; + if(tmpcfg.parsertmp_lang == PARSE_CLOBBER) + tmpcfg.parsertmp_lang = NULL; + if(tmpcfg.parsertmp_locale == PARSE_CLOBBER) + tmpcfg.parsertmp_locale = NULL; button_label_y_nudge = setup_i18n(tmpcfg.parsertmp_lang, tmpcfg.parsertmp_locale); #if 0