aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gpg-error.c38
-rw-r--r--src/gpg-error.def.in1
-rw-r--r--src/w32-add.h4
-rw-r--r--src/w32-gettext.c73
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)