diff options
author | Werner Koch <[email protected]> | 2018-12-07 13:46:25 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2018-12-07 13:50:05 +0000 |
commit | 0b190ce89de7b3df873c3896d5126c7882b82e18 (patch) | |
tree | f1721d4dd91fa1929c817fa14d53d89875af325c | |
parent | doc: Replace gpg-error-config by gpgrt-config. (diff) | |
download | libgpg-error-0b190ce89de7b3df873c3896d5126c7882b82e18.tar.gz libgpg-error-0b190ce89de7b3df873c3896d5126c7882b82e18.zip |
Add W32-only function gpgrt_w32_override_locale.
* src/w32-gettext.c (struct override_locale): new.
(my_nl_locale_name): Take care of that.
(gpgrt_w32_override_locale): New.
* src/gpg-error.def.in: Add gpgrt_w32_override_locale.
* src/gpg-error.c: New command --locale for Windows.
--
GnuPG-bug-id: 3733
Signed-off-by: Werner Koch <[email protected]>
-rw-r--r-- | src/gpg-error.c | 38 | ||||
-rw-r--r-- | src/gpg-error.def.in | 1 | ||||
-rw-r--r-- | src/w32-add.h | 4 | ||||
-rw-r--r-- | src/w32-gettext.c | 73 |
4 files changed, 95 insertions, 21 deletions
diff --git a/src/gpg-error.c b/src/gpg-error.c index ade2bae..13703ef 100644 --- a/src/gpg-error.c +++ b/src/gpg-error.c @@ -483,6 +483,7 @@ main (int argc, char *argv[]) CMD_LIB_VERSION = 501, CMD_LIST, CMD_DEFINES, + CMD_LOCALE, OPT_DESC }; static gpgrt_opt_t opts[] = { @@ -492,6 +493,13 @@ main (int argc, char *argv[]) "Print all error codes"), ARGPARSE_c (CMD_DEFINES, "defines", "Print all error codes as #define lines"), + ARGPARSE_c (CMD_LOCALE, "locale", +#if HAVE_W32_SYSTEM + "Return the locale used for gettext" +#else + "@" +#endif + ), ARGPARSE_s_n (OPT_DESC, "desc", "Print with error description"), ARGPARSE_end() @@ -500,6 +508,7 @@ main (int argc, char *argv[]) int i; int listmode = 0; + int localemode = 0; int desc = 0; const char *source_sym; const char *error_sym; @@ -518,18 +527,41 @@ main (int argc, char *argv[]) case CMD_LIB_VERSION: break; case CMD_LIST: listmode = 1; break; case CMD_DEFINES: listmode = 2; break; + case CMD_LOCALE: localemode = 1; break; case OPT_DESC: desc = 1; break; - default: pargs.err = ARGPARSE_PRINT_WARNING; break; } } gpgrt_argparse (NULL, &pargs, NULL); /* Free internal memory. */ - if ((argc && listmode) || (!argc && !listmode)) + if (localemode) + { + if (argc > 1) + gpgrt_usage (1); + } + else if ((argc && listmode) || (!argc && !listmode)) gpgrt_usage (1); + if (localemode) + { +#if HAVE_W32_SYSTEM + if (argc) + { + /* Warning: What we do here is not allowed because + * gpgrt_w32_override_locale needs to be called as early as + * possible. However for this very purpose it is okay. */ + if (**argv >= '0' && **argv <= '9') + gpgrt_w32_override_locale (NULL, strtoul (*argv, NULL, 0)); + else + gpgrt_w32_override_locale (*argv, 0); + } - if (listmode == 1) + printf ("%s\n", gettext_localename ()); +#else + log_info ("this command is only useful on Windows\n"); +#endif + } + else if (listmode == 1) { for (i=0; i < GPG_ERR_SOURCE_DIM; i++) { diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in index f03a7e3..0eca3c7 100644 --- a/src/gpg-error.def.in +++ b/src/gpg-error.def.in @@ -224,5 +224,6 @@ EXPORTS gpgrt_fprintf_sf @171 gpgrt_fprintf_sf_unlocked @172 + gpgrt_w32_override_locale @173 ;; end of file with public symbols for Windows. diff --git a/src/w32-add.h b/src/w32-add.h index 07e3c7d..3428961 100644 --- a/src/w32-add.h +++ b/src/w32-add.h @@ -37,6 +37,10 @@ int _gpg_w32_gettext_use_utf8 (int value); # define gettext_use_utf8(a) _gpg_w32_gettext_use_utf8 (a) #endif /*GPG_ERR_ENABLE_GETTEXT_MACROS*/ +/* Force the use of the locale NAME or if NAME is NULL the one derived + * from LANGID. This function must be used early and is not thread-safe. */ +void gpgrt_w32_override_locale (const char *name, unsigned short langid); + /* A simple iconv implementation w/o the need for an extra DLL. */ struct _gpgrt_w32_iconv_s; diff --git a/src/w32-gettext.c b/src/w32-gettext.c index 3b54ebd..11e4f3d 100644 --- a/src/w32-gettext.c +++ b/src/w32-gettext.c @@ -53,6 +53,16 @@ #include "init.h" #include "gpg-error.h" +/* Override values initialized by gpgrt_w32_override_locale. If NAME + * is not the empty string LANGID will be used. */ +static struct +{ + unsigned short active; /* If not zero this override is active. */ + unsigned short langid; + char name[28]; +} override_locale; + + #ifdef HAVE_W32CE_SYSTEM /* Forward declaration. */ static wchar_t *utf8_to_wchar (const char *string, size_t length, size_t *retlen); @@ -647,33 +657,42 @@ my_nl_locale_name (const char *categoryname) #ifndef HAVE_W32CE_SYSTEM const char *retval; #endif - LCID lcid; LANGID langid; int primary, sub; - /* Let the user override the system settings through environment - variables, as on POSIX systems. */ + if (override_locale.active) + { + if (*override_locale.name) + return override_locale.name; + langid = override_locale.langid; + } + else + { + LCID lcid; + + /* Let the user override the system settings through environment + * variables, as on POSIX systems. */ #ifndef HAVE_W32CE_SYSTEM - retval = getenv ("LC_ALL"); - if (retval != NULL && retval[0] != '\0') - return retval; - retval = getenv (categoryname); - if (retval != NULL && retval[0] != '\0') - return retval; - retval = getenv ("LANG"); - if (retval != NULL && retval[0] != '\0') - return retval; + retval = getenv ("LC_ALL"); + if (retval != NULL && retval[0] != '\0') + return retval; + retval = getenv (categoryname); + if (retval != NULL && retval[0] != '\0') + return retval; + retval = getenv ("LANG"); + if (retval != NULL && retval[0] != '\0') + return retval; #endif /*!HAVE_W32CE_SYSTEM*/ - /* Use native Win32 API locale ID. */ + /* Use native Win32 API locale ID. */ #ifdef HAVE_W32CE_SYSTEM - lcid = GetSystemDefaultLCID (); + lcid = GetSystemDefaultLCID (); #else - lcid = GetThreadLocale (); + lcid = GetThreadLocale (); #endif - - /* Strip off the sorting rules, keep only the language part. */ - langid = LANGIDFROMLCID (lcid); + /* Strip off the sorting rules, keep only the language part. */ + langid = LANGIDFROMLCID (lcid); + } /* Split into language and territory part. */ primary = PRIMARYLANGID (langid); @@ -1922,6 +1941,24 @@ _gpg_w32_gettext_use_utf8 (int value) } +/* Force the use of the locale NAME or if NAME is NULL the locale + * derived from LANGID will be used. This function is not thread-safe + * and must be used early - even before gpgrt_check_version. */ +void +gpgrt_w32_override_locale (const char *name, unsigned short langid) +{ + if (name) + { + strncpy (override_locale.name, name, sizeof (override_locale.name) - 1); + override_locale.name[sizeof (override_locale.name) - 1] = 0; + } + else + *override_locale.name = 0; + override_locale.langid = langid; + override_locale.active = 1; +} + + #ifdef TEST int main (int argc, char **argv) |