On 15.03.2018 11:40, Eli Zaretskii wrote:
From: lrn1...@gmail.com
Cc: Eli Zaretskii <e...@gnu.org>
Date: Wed, 14 Mar 2018 01:26:27 +0300

For English UI and Russian format setting:

GetUserDefaultUILanguage() returns:
0x409 (primary ID 0x9 sub ID 0x1 (meaning en_US)).

GetUserPreferredUILanguages() returns:
"0409" for language ID and "en-US" for language name.
(1 language, in a 00-terminated string).


For Russian UI and English format setting:

GetUserDefaultUILanguage() returns:
0x419 (primary ID 0x19 sub ID 0x1 (meaning ru_RU)).

GetUserPreferredUILanguages() returns:
"0419" for language ID and "ru-RU" for language name.
"0409" for language ID and "en-US" for language name.
(2 languages, in a 0-delimited, 00-terminated string).

Since there's no POSIX api for returning a list of locales, we'd be OK with
just GetUserDefaultUILanguage() (although MSDN recommends
GetUserPreferredUILanguages(), since it returns strings and thus can represent
custom locales; though we might need new code for parsing its output).

I think just calling setlocale should be enough, and if gettext calls
gl_locale_name, you will have what you want.  Calling Win32 APIs
directly is not something I recommend, unless there's no other way of
doing something reasonable by using CRT functions.


Well, that's a pity. And here i already made a patch for this...

Sorry, it's not a git format-patch (turns out gettext git repo doesn't carry all these multiple copies of gnulib around, so there's almost nothing to patch there).
diff -ur gettext-0.19.7.orig/gettext-runtime/gnulib-lib/localename.c 
gettext-0.19.7/gettext-runtime/gnulib-lib/localename.c
--- gettext-runtime/gnulib-lib/localename.c     2015-12-27 23:08:01.000000000 
+0000
+++ gettext-runtime/gnulib-lib/localename.c     2018-03-14 14:30:49.694668700 
+0000
@@ -2935,6 +2935,23 @@
 
 # if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin 
*/
   {
+    LANGID langid;
+
+    /* Use native Windows API UI language ID.  */
+    langid = GetUserDefaultUILanguage ();
+
+    return gl_locale_name_from_win32_LANGID (langid);
+  }
+# endif
+#endif
+}
+
+const char *
+gl_locale_name_default_for_category (int category)
+{
+#if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
+  if (category != LC_MESSAGES && category != LC_COLLATE && category != 
LC_CTYPE)
+  {
     LCID lcid;
 
     /* Use native Windows API locale ID.  */
@@ -2942,10 +2959,11 @@
 
     return gl_locale_name_from_win32_LCID (lcid);
   }
-# endif
 #endif
+  return gl_locale_name_default ();
 }
 
+
 /* Determine the current locale's name, and canonicalize it into XPG syntax
      language[_territory][.codeset][@modifier]
    The codeset part in the result is not reliable; the locale_charset()
@@ -2965,5 +2983,5 @@
   if (retval != NULL)
     return retval;
 
-  return gl_locale_name_default ();
+  return gl_locale_name_default_for_category (category);
 }
diff -ur gettext-0.19.7.orig/gettext-runtime/gnulib-lib/localename.h 
gettext-0.19.7/gettext-runtime/gnulib-lib/localename.h
--- gettext-runtime/gnulib-lib/localename.h     2015-12-27 23:08:01.000000000 
+0000
+++ gettext-runtime/gnulib-lib/localename.h     2018-03-14 14:31:24.138001700 
+0000
@@ -25,7 +25,7 @@
 /* Determine the current locale's name.
    It considers both the POSIX notion of locale name (see functions
    gl_locale_name_thread and gl_locale_name_posix) and the system notion
-   of locale name (see function gl_locale_name_default).
+   of locale name (see function gl_locale_name_default_for_category).
    CATEGORY is a locale category abbreviation, as defined in <locale.h>,
    but not LC_ALL. E.g. LC_MESSAGES.
    CATEGORYNAME is the name of CATEGORY as a string, e.g. "LC_MESSAGES".
@@ -89,6 +89,29 @@
 #if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE \
       || defined _WIN32 || defined __WIN32__ || defined __CYGWIN__)
   _GL_ATTRIBUTE_CONST
+#endif
+  ;
+
+/* Determine the default locale's name for the given category.
+   This is the current locale's name for the given category,
+   if not specified by uselocale() calls, by setlocale() calls, or by
+   environment variables.  This locale name is usually determined by systems
+   settings that the user can manipulate through a GUI.
+
+   Quoting POSIX:2001:
+     "All implementations shall define a locale as the default locale,
+      to be invoked when no environment variables are set, or set to the
+      empty string.  This default locale can be the C locale or any other
+      implementation-defined locale.  Some implementations may provide
+      facilities for local installation administrators to set the default
+      locale, customizing it for each location.  IEEE Std 1003.1-2001 does
+      not require such a facility."
+
+   The result must not be freed; it is statically allocated.  */
+extern const char * gl_locale_name_default_for_category (int category)
+#if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE \
+      || defined _WIN32 || defined __WIN32__ || defined __CYGWIN__)
+  _GL_ATTRIBUTE_CONST
 #endif
   ;
 
diff -ur gettext-0.19.7.orig/gettext-runtime/gnulib-lib/setlocale.c 
gettext-0.19.7/gettext-runtime/gnulib-lib/setlocale.c
--- gettext-runtime/gnulib-lib/setlocale.c      2015-12-27 23:08:01.000000000 
+0000
+++ gettext-runtime/gnulib-lib/setlocale.c      2018-03-14 14:39:19.640044900 
+0000
@@ -840,7 +840,7 @@
           base_name =
             gl_locale_name_environ (LC_CTYPE, category_to_name (LC_CTYPE));
           if (base_name == NULL)
-            base_name = gl_locale_name_default ();
+            base_name = gl_locale_name_default_for_category (LC_CTYPE);
 
           if (setlocale_unixlike (LC_ALL, base_name) == NULL)
             goto fail;
@@ -860,7 +860,7 @@
 
               name = gl_locale_name_environ (cat, category_to_name (cat));
               if (name == NULL)
-                name = gl_locale_name_default ();
+                name = gl_locale_name_default_for_category (cat);
 
               /* If name is the same as base_name, it has already been set
                  through the setlocale call before the loop.  */
@@ -888,7 +888,7 @@
           const char *name =
             gl_locale_name_environ (category, category_to_name (category));
           if (name == NULL)
-            name = gl_locale_name_default ();
+            name = gl_locale_name_default_for_category (category);
 
           return setlocale_single (category, name);
         }
diff -ur gettext-0.19.7.orig/gettext-runtime/intl/dcigettext.c 
gettext-0.19.7/gettext-runtime/intl/dcigettext.c
--- gettext-runtime/intl/dcigettext.c   2015-12-23 07:08:27.000000000 +0000
+++ gettext-runtime/intl/dcigettext.c   2018-03-14 14:41:45.371558600 +0000
@@ -1561,7 +1561,7 @@
       locale = _nl_locale_name_posix (category, categoryname);
       if (locale == NULL)
        {
-         locale = _nl_locale_name_default ();
+         locale = _nl_locale_name_default_for_category (category);
          locale_defaulted = 1;
        }
     }
diff -ur gettext-0.19.7.orig/gettext-runtime/intl/gettextP.h 
gettext-0.19.7/gettext-runtime/intl/gettextP.h
--- gettext-runtime/intl/gettextP.h     2015-12-23 07:08:27.000000000 +0000
+++ gettext-runtime/intl/gettextP.h     2018-03-14 14:41:29.858745100 +0000
@@ -251,6 +251,8 @@
                                            const char *categoryname);
 # define gl_locale_name_default _nl_locale_name_default
 extern const char *_nl_locale_name_default (void);
+# define gl_locale_name_default_for_category 
_nl_locale_name_default_for_category
+extern const char *_nl_locale_name_default_for_category (int category);
 # define gl_locale_name _nl_locale_name
 /* extern const char *_nl_locale_name (int category,
                                       const char *categoryname); */
diff -ur gettext-0.19.7.orig/gettext-runtime/intl/localename.c 
gettext-0.19.7/gettext-runtime/intl/localename.c
--- gettext-runtime/intl/localename.c   2015-12-08 12:50:04.000000000 +0000
+++ gettext-runtime/intl/localename.c   2018-03-14 14:30:49.694668700 +0000
@@ -2935,6 +2935,23 @@
 
 # if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin 
*/
   {
+    LANGID langid;
+
+    /* Use native Windows API UI language ID.  */
+    langid = GetUserDefaultUILanguage ();
+
+    return gl_locale_name_from_win32_LANGID (langid);
+  }
+# endif
+#endif
+}
+
+const char *
+gl_locale_name_default_for_category (int category)
+{
+#if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
+  if (category != LC_MESSAGES && category != LC_COLLATE && category != 
LC_CTYPE)
+  {
     LCID lcid;
 
     /* Use native Windows API locale ID.  */
@@ -2942,10 +2959,11 @@
 
     return gl_locale_name_from_win32_LCID (lcid);
   }
-# endif
 #endif
+  return gl_locale_name_default ();
 }
 
+
 /* Determine the current locale's name, and canonicalize it into XPG syntax
      language[_territory][.codeset][@modifier]
    The codeset part in the result is not reliable; the locale_charset()
@@ -2965,5 +2983,5 @@
   if (retval != NULL)
     return retval;
 
-  return gl_locale_name_default ();
+  return gl_locale_name_default_for_category (category);
 }
diff -ur gettext-0.19.7.orig/gettext-runtime/intl/setlocale.c 
gettext-0.19.7/gettext-runtime/intl/setlocale.c
--- gettext-runtime/intl/setlocale.c    2015-06-05 21:52:52.000000000 +0000
+++ gettext-runtime/intl/setlocale.c    2018-03-14 14:40:00.472555000 +0000
@@ -850,7 +850,7 @@
           base_name =
             gl_locale_name_environ (LC_CTYPE, category_to_name (LC_CTYPE));
           if (base_name == NULL)
-            base_name = gl_locale_name_default ();
+            base_name = gl_locale_name_default_for_category (LC_CTYPE);
 
           if (setlocale_unixlike (LC_ALL, base_name) == NULL)
             goto fail;
@@ -870,7 +870,7 @@
 
               name = gl_locale_name_environ (cat, category_to_name (cat));
               if (name == NULL)
-                name = gl_locale_name_default ();
+                name = gl_locale_name_default_for_category (cat);
 
               /* If name is the same as base_name, it has already been set
                  through the setlocale call before the loop.  */
@@ -900,7 +900,7 @@
           const char *name =
             gl_locale_name_environ (category, category_to_name (category));
           if (name == NULL)
-            name = gl_locale_name_default ();
+            name = gl_locale_name_default_for_category (category);
 
           result = setlocale_single (category, name);
           if (result != NULL)
@@ -991,7 +991,7 @@
           base_name =
             gl_locale_name_environ (LC_CTYPE, category_to_name (LC_CTYPE));
           if (base_name == NULL)
-            base_name = gl_locale_name_default ();
+            base_name = gl_locale_name_default_for_category (LC_CTYPE);
 
           base = newlocale (LC_ALL_MASK, base_name, base);
           if (base == NULL)
@@ -1006,7 +1006,7 @@
               name =
                 gl_locale_name_environ (category, category_to_name (category));
               if (name == NULL)
-                name = gl_locale_name_default ();
+                name = gl_locale_name_default_for_category (category);
 
               /* If name is the same as base_name, it has already been set
                  through the setlocale call before the loop.  */
@@ -1037,7 +1037,7 @@
 
                   name = gl_locale_name_environ (cat, category_to_name (cat));
                   if (name == NULL)
-                    name = gl_locale_name_default ();
+                    name = gl_locale_name_default_for_category (cat);
 
                   copy = newlocale (cat_mask, name, base);
                   if (copy == NULL)
diff -ur gettext-0.19.7.orig/gettext-tools/gnulib-lib/localename.c 
gettext-0.19.7/gettext-tools/gnulib-lib/localename.c
--- gettext-tools/gnulib-lib/localename.c       2015-12-27 23:08:31.000000000 
+0000
+++ gettext-tools/gnulib-lib/localename.c       2018-03-14 14:30:49.694668700 
+0000
@@ -2935,6 +2935,23 @@
 
 # if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin 
*/
   {
+    LANGID langid;
+
+    /* Use native Windows API UI language ID.  */
+    langid = GetUserDefaultUILanguage ();
+
+    return gl_locale_name_from_win32_LANGID (langid);
+  }
+# endif
+#endif
+}
+
+const char *
+gl_locale_name_default_for_category (int category)
+{
+#if defined WINDOWS_NATIVE || defined __CYGWIN__ /* Native Windows or Cygwin */
+  if (category != LC_MESSAGES && category != LC_COLLATE && category != 
LC_CTYPE)
+  {
     LCID lcid;
 
     /* Use native Windows API locale ID.  */
@@ -2942,10 +2959,11 @@
 
     return gl_locale_name_from_win32_LCID (lcid);
   }
-# endif
 #endif
+  return gl_locale_name_default ();
 }
 
+
 /* Determine the current locale's name, and canonicalize it into XPG syntax
      language[_territory][.codeset][@modifier]
    The codeset part in the result is not reliable; the locale_charset()
@@ -2965,5 +2983,5 @@
   if (retval != NULL)
     return retval;
 
-  return gl_locale_name_default ();
+  return gl_locale_name_default_for_category (category);
 }
diff -ur gettext-0.19.7.orig/gettext-tools/gnulib-lib/localename.h 
gettext-0.19.7/gettext-tools/gnulib-lib/localename.h
--- gettext-tools/gnulib-lib/localename.h       2015-12-27 23:08:31.000000000 
+0000
+++ gettext-tools/gnulib-lib/localename.h       2018-03-14 14:31:24.138001700 
+0000
@@ -25,7 +25,7 @@
 /* Determine the current locale's name.
    It considers both the POSIX notion of locale name (see functions
    gl_locale_name_thread and gl_locale_name_posix) and the system notion
-   of locale name (see function gl_locale_name_default).
+   of locale name (see function gl_locale_name_default_for_category).
    CATEGORY is a locale category abbreviation, as defined in <locale.h>,
    but not LC_ALL. E.g. LC_MESSAGES.
    CATEGORYNAME is the name of CATEGORY as a string, e.g. "LC_MESSAGES".
@@ -89,6 +89,29 @@
 #if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE \
       || defined _WIN32 || defined __WIN32__ || defined __CYGWIN__)
   _GL_ATTRIBUTE_CONST
+#endif
+  ;
+
+/* Determine the default locale's name for the given category.
+   This is the current locale's name for the given category,
+   if not specified by uselocale() calls, by setlocale() calls, or by
+   environment variables.  This locale name is usually determined by systems
+   settings that the user can manipulate through a GUI.
+
+   Quoting POSIX:2001:
+     "All implementations shall define a locale as the default locale,
+      to be invoked when no environment variables are set, or set to the
+      empty string.  This default locale can be the C locale or any other
+      implementation-defined locale.  Some implementations may provide
+      facilities for local installation administrators to set the default
+      locale, customizing it for each location.  IEEE Std 1003.1-2001 does
+      not require such a facility."
+
+   The result must not be freed; it is statically allocated.  */
+extern const char * gl_locale_name_default_for_category (int category)
+#if !(HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE \
+      || defined _WIN32 || defined __WIN32__ || defined __CYGWIN__)
+  _GL_ATTRIBUTE_CONST
 #endif
   ;
 
diff -ur gettext-0.19.7.orig/gettext-tools/gnulib-lib/setlocale.c 
gettext-0.19.7/gettext-tools/gnulib-lib/setlocale.c
--- gettext-tools/gnulib-lib/setlocale.c        2015-12-27 23:08:31.000000000 
+0000
+++ gettext-tools/gnulib-lib/setlocale.c        2018-03-14 14:39:25.375200100 
+0000
@@ -840,7 +840,7 @@
           base_name =
             gl_locale_name_environ (LC_CTYPE, category_to_name (LC_CTYPE));
           if (base_name == NULL)
-            base_name = gl_locale_name_default ();
+            base_name = gl_locale_name_default_for_category (LC_CTYPE);
 
           if (setlocale_unixlike (LC_ALL, base_name) == NULL)
             goto fail;
@@ -860,7 +860,7 @@
 
               name = gl_locale_name_environ (cat, category_to_name (cat));
               if (name == NULL)
-                name = gl_locale_name_default ();
+                name = gl_locale_name_default_for_category (cat);
 
               /* If name is the same as base_name, it has already been set
                  through the setlocale call before the loop.  */
@@ -888,7 +888,7 @@
           const char *name =
             gl_locale_name_environ (category, category_to_name (category));
           if (name == NULL)
-            name = gl_locale_name_default ();
+            name = gl_locale_name_default_for_category (category);
 
           return setlocale_single (category, name);
         }
diff -ur gettext-0.19.7.orig/gettext-tools/gnulib-tests/test-localename.c 
gettext-0.19.7/gettext-tools/gnulib-tests/test-localename.c
--- gettext-tools/gnulib-tests/test-localename.c        2015-12-27 
23:08:33.000000000 +0000
+++ gettext-tools/gnulib-tests/test-localename.c        2018-03-14 
14:36:38.770152700 +0000
@@ -83,9 +83,9 @@
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
-                  gl_locale_name_default ()) == 0);
+                  gl_locale_name_default_for_category (LC_MESSAGES)) == 0);
   ASSERT (strcmp (gl_locale_name (LC_NUMERIC, "LC_NUMERIC"),
-                  gl_locale_name_default ()) == 0);
+                  gl_locale_name_default_for_category (LC_NUMERIC)) == 0);
 
   /* Check that an empty environment variable is treated like an unset
      environment variable.  */
@@ -96,7 +96,7 @@
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
-                  gl_locale_name_default ()) == 0);
+                  gl_locale_name_default_for_category (LC_MESSAGES)) == 0);
 
   unsetenv ("LC_ALL");
   setenv ("LC_CTYPE", "", 1);
@@ -104,7 +104,7 @@
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
-                  gl_locale_name_default ()) == 0);
+                  gl_locale_name_default_for_category (LC_MESSAGES)) == 0);
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
@@ -112,7 +112,7 @@
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
-                  gl_locale_name_default ()) == 0);
+                  gl_locale_name_default_for_category (LC_MESSAGES)) == 0);
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
@@ -120,7 +120,7 @@
   setenv ("LANG", "", 1);
   setlocale (LC_ALL, "");
   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
-                  gl_locale_name_default ()) == 0);
+                  gl_locale_name_default_for_category (LC_MESSAGES)) == 0);
 
   /* Check that LC_ALL overrides the others, and LANG is overridden by the
      others.  */
@@ -167,7 +167,7 @@
   if (setlocale (LC_ALL, "") != NULL)
     {
       name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
-      ASSERT (strcmp (name, gl_locale_name_default ()) == 0);
+      ASSERT (strcmp (name, gl_locale_name_default_for_category (LC_CTYPE)) == 
0);
       name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
     }
@@ -484,9 +484,9 @@
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || strcmp (name, gl_locale_name_default_for_category 
(LC_MESSAGES)) == 0);
   name = gl_locale_name_posix (LC_NUMERIC, "LC_NUMERIC");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || strcmp (name, gl_locale_name_default_for_category 
(LC_NUMERIC)) == 0);
 
   /* Check that an empty environment variable is treated like an unset
      environment variable.  */
@@ -497,7 +497,7 @@
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || strcmp (name, gl_locale_name_default_for_category 
(LC_MESSAGES)) == 0);
 
   unsetenv ("LC_ALL");
   setenv ("LC_CTYPE", "", 1);
@@ -505,7 +505,7 @@
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || strcmp (name, gl_locale_name_default_for_category 
(LC_MESSAGES)) == 0);
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
@@ -513,7 +513,7 @@
   unsetenv ("LANG");
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || strcmp (name, gl_locale_name_default_for_category 
(LC_MESSAGES)) == 0);
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
@@ -521,7 +521,7 @@
   setenv ("LANG", "", 1);
   setlocale (LC_ALL, "");
   name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
-  ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+  ASSERT (name == NULL || strcmp (name, gl_locale_name_default_for_category 
(LC_MESSAGES)) == 0);
 
   /* Check that LC_ALL overrides the others, and LANG is overridden by the
      others.  */
@@ -571,7 +571,7 @@
   if (setlocale (LC_ALL, "") != NULL)
     {
       name = gl_locale_name_posix (LC_CTYPE, "LC_CTYPE");
-      ASSERT (name == NULL || strcmp (name, gl_locale_name_default ()) == 0);
+      ASSERT (name == NULL || strcmp (name, 
gl_locale_name_default_for_category (LC_CTYPE)) == 0);
       name = gl_locale_name_posix (LC_MESSAGES, "LC_MESSAGES");
       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
     }

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to