listhelper-moderate
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug-gnu-utils post from address@hidden requires approval


From: bug-gnu-utils-owner
Subject: bug-gnu-utils post from address@hidden requires approval
Date: Tue, 03 Jul 2007 18:08:00 -0400

As list administrator, your authorization is requested for the
following mailing list posting:

    List:    address@hidden
    From:    address@hidden
    Subject: Win32 MUI support for libintl/gettext
    Reason:  Post by non-member to a members-only list

At your convenience, visit:

    http://lists.gnu.org/mailman/admindb/bug-gnu-utils
        
to approve or deny the request.
--- Begin Message --- Subject: Win32 MUI support for libintl/gettext Date: Wed, 04 Jul 2007 00:01:01 +0200 User-agent: Thunderbird 1.5 (Windows/20051201)
Not sure where I should send this... Adds full support for Windows MUI,
in all of its (documented) flavors.

Barring implementation bugs, gettext on Windows will *finally* pick the
"right" language by default: it will try GetUserPreferredUILanguages
first (Windows Vista and later), then GetUserDefaultUILanguage (Windows
2000/Windows Me and later), then it will try the HCKU\Control
Panel\Desktop\ResourceLocale key (Windows 95 and later), and finally it
will try to match the language the system is localized in (from the
kernel32.dll version information resource).

MUI support is provided as an implementation of
_nl_language_preferences_default(), so it will play nice with the rest
of libintl. The language id to string code from localename.c has been
isolated in a function, _nl_langid_name_np (plus the _nl_lcid_name_np
helper), because it's now used from more than one place; also, I have
implemented a helper function called _nl_rfc3066_to_posix_np, that
converts a locale identifier from the RFC-3066/1766 format used by
Windows into the POSIX format expected by libintl; the "_np" suffix
follows historical POSIX threads practice to mark "Non Portable" routines.

Gettext doesn't link on my machine, so I cannot test it (also, I don't
have Windows Vista, which would exercise the majority of the code added
by this patch). Sorry about that. I hope you'll find this patch useful
and apply it


diff -r -u3 gettext-0.16\gettext-runtime\intl\gettextP.h 
gettext-0.16-patched\gettext-runtime\intl\gettextP.h
--- gettext-0.16\gettext-runtime\intl\gettextP.h        Wed Aug 10 12:57:11 2005
+++ gettext-0.16-patched\gettext-runtime\intl\gettextP.h        Wed Mar 28 
17:06:24 2007
@@ -219,6 +219,13 @@
 const char *_nl_locale_name_posix (int category, const char *categoryname);
 const char *_nl_locale_name_default (void);
 const char *_nl_locale_name (int category, const char *categoryname);
+
+# ifdef _WIN32
+const char *_nl_lcid_name_np(unsigned long lcid);
+const char *_nl_langid_name_np(unsigned short langid);
+const char *_nl_rfc3066_to_posix_np(char * rfc3066, size_t length);
+# endif
+
 #endif

 struct loaded_l10nfile *_nl_find_domain (const char *__dirname, char *__locale,
diff -r -u3 gettext-0.16\gettext-runtime\intl\langprefs.c 
gettext-0.16-patched\gettext-runtime\intl\langprefs.c
--- gettext-0.16\gettext-runtime\intl\langprefs.c       Mon Oct 16 14:11:18 2006
+++ gettext-0.16-patched\gettext-runtime\intl\langprefs.c       Mon Apr 16 
13:20:44 2007
@@ -22,8 +22,11 @@
 # include <config.h>
 #endif

+#include <assert.h>
 #include <stdlib.h>

+#include "gettextP.h"
+
 #if HAVE_CFPREFERENCESCOPYAPPVALUE
 # include <string.h>
 # include <CoreFoundation/CFPreferences.h>
@@ -33,6 +36,28 @@
 extern void _nl_locale_name_canonicalize (char *name);
 #endif

+#ifdef _WIN32
+
+/* Prevent namespace pollution */
+#define WIN32_LEAN_AND_MEAN
+#define NOMINMAX
+
+/* Latest MUI APIs require Vista or later */
+#define _WIN32_WINNT 0x0600
+
+#define STRICT
+
+#include <windows.h>
+
+/* NOTE: MinGW has a wrong definition of ENUMRESLANGPROC */
+BOOL CALLBACK enum_res_lang(HANDLE hModule, LPCTSTR lpszType, LPCTSTR 
lpszName, WORD wIDLanguage, LONG lParam)
+{
+  lParam = (LONG_PTR)_nl_langid_name_np(wIDLanguage);
+  return FALSE;
+}
+
+#endif
+
 /* Determine the user's language preferences, as a colon separated list of
    locale names in XPG syntax
      address@hidden
@@ -123,6 +148,213 @@
       }
     if (cached_languages != NULL)
       return cached_languages;
+  }
+#endif
+
+#ifdef _WIN32
+
+#ifndef MUI_LANGUAGE_NAME
+#define MUI_LANGUAGE_NAME 8
+#endif
+
+#ifndef STATUS_BUFFER_OVERFLOW
+#define STATUS_BUFFER_OVERFLOW 0x80000005L
+#endif
+
+  {
+    static const char * cached_languages = NULL;
+    static int cache_initialized = 0;
+
+    HMODULE hKernel32;
+       HKEY hkResourceLocale;
+
+    if(cache_initialized)
+      return cached_languages;
+
+    /* First we try to use the proper MUI APIs */
+    hKernel32 = GetModuleHandleA("kernel32");
+
+    if(hKernel32)
+    {
+      DWORD (WINAPI * pfnGetUserPreferredUILanguages)
+      (
+        ULONG dwFlags,
+        PULONG pulNumLanguages,
+        PWSTR pwszLanguagesBuffer,
+        PULONG pcchLanguagesBuffer
+      );
+
+      LANGID (WINAPI * pfnGetUserDefaultUILanguage)(void);
+
+      /* The proper API (Vista and later) */
+      pfnGetUserPreferredUILanguages = (void *)GetProcAddress(hKernel32, 
"GetUserPreferredUILanguages");
+
+      if(pfnGetUserPreferredUILanguages)
+      {
+        ULONG ulNumLanguages;
+        PWSTR pwszLanguagesBuffer;
+        ULONG cchLanguagesBuffer = 0;
+        DWORD dwRet;
+        char * lang_names = NULL;
+
+        /* Determine buffer size */
+        dwRet = pfnGetUserPreferredUILanguages
+        (
+          MUI_LANGUAGE_NAME,
+          &ulNumLanguages,
+          NULL,
+          &cchLanguagesBuffer
+        );
+
+        if(dwRet || GetLastError() != STATUS_BUFFER_OVERFLOW || 
cchLanguagesBuffer == 0)
+          goto l_win32_failure;
+
+        pwszLanguagesBuffer = malloc(sizeof(WCHAR) * cchLanguagesBuffer);
+
+        /* Retrieve the list of preferred UI languages */
+        dwRet = pfnGetUserPreferredUILanguages
+        (
+          MUI_LANGUAGE_NAME,
+          &ulNumLanguages,
+          pwszLanguagesBuffer,
+          &cchLanguagesBuffer
+        );
+
+        /* Convert the list from NUL-delimited WCHAR[] RFC 3066 to 
colon-delimited char[] POSIX */
+        if(dwRet)
+        {
+          lang_names = malloc(cchLanguagesBuffer + 1);
+
+          if(lang_names)
+          {
+                   ULONG i;
+            size_t n = 0;
+
+            for(i = 0; i < ulNumLanguages; ++ i)
+            {
+              size_t entry_start = n;
+
+              for( ; ; ++ n)
+              {
+                if(pwszLanguagesBuffer[n] == 0)
+                {
+                  lang_names[n] = ':';
+                  break;
+                }
+                else if(pwszLanguagesBuffer[n] == (WCHAR)':')
+                {
+                  /* That's unfortunate... */
+                  lang_names[n] = '_';
+                }
+                else
+                {
+                  /* We assume language names are representable in ASCII */
+                  lang_names[n] = (char)pwszLanguagesBuffer[n];
+                }
+              }
+
+              _nl_rfc3066_to_posix_np(lang_names + entry_start, n - 
entry_start);
+            }
+          }
+        }
+
+        free(pwszLanguagesBuffer);
+
+        if(lang_names == NULL)
+          goto l_win32_failure;
+
+        cached_languages = lang_names;
+        goto l_win32_leave;
+      }
+
+      /* A reasonable fallback (Windows 2000 and later and Windows Me) */
+      pfnGetUserDefaultUILanguage = (void *)GetProcAddress(hKernel32, 
"GetUserDefaultUILanguage");
+
+      if(pfnGetUserDefaultUILanguage)
+      {
+        const char *lang_names;
+
+        lang_names = _nl_langid_name_np(pfnGetUserDefaultUILanguage());
+
+        if(lang_names == NULL)
+          goto l_win32_failure;
+
+        cached_languages = lang_names;
+        goto l_win32_leave;
+      }
+    }
+
+    /* Windows 95 stores the user's default UI language in the registry */
+    if(RegOpenKeyExA(HKEY_CURRENT_USER, "Control 
Panel\\Desktop\\ResourceLocale", 0, KEY_QUERY_VALUE, &hkResourceLocale) == 
NO_ERROR)
+    {
+      DWORD dwType;
+      CHAR Data[sizeof("00000409")];
+      DWORD cbData = sizeof(Data);
+      DWORD dwError;
+
+      dwError = RegQueryValueExA(hkResourceLocale, NULL, NULL, &dwType, Data, 
&cbData);
+      RegCloseKey(hkResourceLocale);
+
+      /* Ensure we read a string */
+      if(dwError == NO_ERROR && dwType == REG_SZ)
+      {
+        assert(cbData <= sizeof(Data));
+
+        /* Ensure it's at most 8 characters long */
+        if(cbData < sizeof(Data) || Data[sizeof(Data) - 1] == 0)
+        {
+          unsigned long lcid;
+          char *end;
+
+          /* Ensure it's NUL-terminated */
+          if(cbData < sizeof(Data))
+            Data[cbData] = 0;
+
+          /* Parse it as a hexadecimal number */
+          lcid = strtoul(Data, &end, 16);
+
+          /* Ensure it was a hexadecimal number */
+          if(*end == 0)
+          {
+            const char *lang_names;
+
+            /* Get the language name */
+            lang_names = _nl_lcid_name_np(lcid);
+
+            if(lang_names == NULL)
+              goto l_win32_failure;
+
+            cached_languages = lang_names;
+            goto l_win32_leave;
+          }
+        }
+      }
+    }
+
+    /* If all else fails, match the hard-coded UI language of the system */
+    if(hKernel32)
+    {
+      char * lang_names = NULL;
+
+      EnumResourceLanguages(hKernel32, RT_VERSION, MAKEINTRESOURCE(1), 
enum_res_lang, (LONG_PTR)&lang_names);
+
+      if(lang_names == NULL)
+        goto l_win32_failure;
+
+      cached_languages = lang_names;
+      goto l_win32_leave;
+    }
+
+    /* No way to know the UI language: just give up */
+
+l_win32_leave:
+    cache_initialized = 1;
+
+    if(cached_languages)
+      return cached_languages;
+
+l_win32_failure:
+    ;
   }
 #endif

diff -r -u3 gettext-0.16\gettext-runtime\intl\localename.c 
gettext-0.16-patched\gettext-runtime\intl\localename.c
--- gettext-0.16\gettext-runtime\intl\localename.c      Wed Oct 25 13:40:33 2006
+++ gettext-0.16-patched\gettext-runtime\intl\localename.c      Mon Apr 16 
13:15:49 2007
@@ -691,6 +691,464 @@
 # ifndef SUBLANG_UZBEK_CYRILLIC
 # define SUBLANG_UZBEK_CYRILLIC 0x02
 # endif
+
+# ifndef LOCALE_SNAME
+# define LOCALE_SNAME 0x5c
+# endif
+
+const char *_nl_rfc3066_to_posix_np(char * rfc3066, size_t length)
+{
+  size_t i = 0;
+
+  for(; i < length; ++ i)
+  {
+    if(rfc3066[i] == '-')
+    {
+      rfc3066[i] = '_';
+      ++ i;
+
+      for(; i < length; ++ i)
+      {
+        /* RFC 3066 allows more than two subtags, but doesn't standardize them 
*/
+        if(rfc3066[i] == '-')
+        {
+          rfc3066[i] = 0;
+          break;
+        }
+
+        /* We assume ASCII */
+        if(rfc3066[i] >= 'a' && rfc3066[i] <= 'z')
+          rfc3066[i] = _toupper(rfc3066[i]);
+      }
+    }
+  }
+
+  return rfc3066;
+}
+
+const char *_nl_langid_name_np(unsigned short langid)
+{
+  int primary, sub;
+  int cchLocaleName;
+  static char szLocaleName[85];
+
+  /* Windows Vista and later: we can query native NLS support */
+  /* From Windows documentation: "Using SORT_DEFAULT always creates a locale
+     name that is the same as the corresponding language name." */
+  cchLocaleName = GetLocaleInfoA
+  (
+    MAKELCID(langid, SORT_DEFAULT),
+    LOCALE_SNAME,
+       szLocaleName,
+    sizeof(szLocaleName)
+  );
+
+  if(cchLocaleName)
+    return _nl_rfc3066_to_posix_np(szLocaleName, cchLocaleName);
+
+  /* Internet Explorer 4 and later: a LCID -> RFC1766 map is kept in 
HKEY_CLASSES_ROOT\Mime\Database\Rfc1766 */
+  /* TODO? */
+
+  /* Split into language and territory part.  */
+  primary = PRIMARYLANGID (langid);
+  sub = SUBLANGID (langid);
+
+  /* Dispatch on language.
+     See also http://www.unicode.org/unicode/onlinedat/languages.html .
+     For details about languages, see http://www.ethnologue.com/ .  */
+  switch (primary)
+    {
+    case LANG_AFRIKAANS: return "af_ZA";
+    case LANG_ALBANIAN: return "sq_AL";
+    case LANG_AMHARIC: return "am_ET";
+    case LANG_ARABIC:
+      switch (sub)
+        {
+        case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
+        case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
+        case SUBLANG_ARABIC_EGYPT: return "ar_EG";
+        case SUBLANG_ARABIC_LIBYA: return "ar_LY";
+        case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
+        case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
+        case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
+        case SUBLANG_ARABIC_OMAN: return "ar_OM";
+        case SUBLANG_ARABIC_YEMEN: return "ar_YE";
+        case SUBLANG_ARABIC_SYRIA: return "ar_SY";
+        case SUBLANG_ARABIC_JORDAN: return "ar_JO";
+        case SUBLANG_ARABIC_LEBANON: return "ar_LB";
+        case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
+        case SUBLANG_ARABIC_UAE: return "ar_AE";
+        case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
+        case SUBLANG_ARABIC_QATAR: return "ar_QA";
+        }
+      return "ar";
+    case LANG_ARMENIAN: return "hy_AM";
+    case LANG_ASSAMESE: return "as_IN";
+    case LANG_AZERI:
+      switch (sub)
+        {
+        /* FIXME: Adjust this when Azerbaijani locales appear on Unix.  */
+        case SUBLANG_AZERI_LATIN: return "address@hidden";
+        case SUBLANG_AZERI_CYRILLIC: return "address@hidden";
+        }
+      return "az";
+    case LANG_BASQUE:
+      switch (sub)
+        {
+        case SUBLANG_DEFAULT: return "eu_ES";
+        }
+      return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR".  */
+    case LANG_BELARUSIAN: return "be_BY";
+    case LANG_BENGALI:
+      switch (sub)
+        {
+        case SUBLANG_BENGALI_INDIA: return "bn_IN";
+        case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
+        }
+      return "bn";
+    case LANG_BULGARIAN: return "bg_BG";
+    case LANG_BURMESE: return "my_MM";
+    case LANG_CAMBODIAN: return "km_KH";
+    case LANG_CATALAN: return "ca_ES";
+    case LANG_CHEROKEE: return "chr_US";
+    case LANG_CHINESE:
+      switch (sub)
+        {
+        case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW";
+        case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN";
+        case SUBLANG_CHINESE_HONGKONG: return "zh_HK";
+        case SUBLANG_CHINESE_SINGAPORE: return "zh_SG";
+        case SUBLANG_CHINESE_MACAU: return "zh_MO";
+        }
+      return "zh";
+    case LANG_CROATIAN:       /* LANG_CROATIAN == LANG_SERBIAN
+               * What used to be called Serbo-Croatian
+               * should really now be two separate
+               * languages because of political reasons.
+               * (Says tml, who knows nothing about Serbian
+               * or Croatian.)
+               * (I can feel those flames coming already.)
+               */
+      switch (sub)
+        {
+        case SUBLANG_DEFAULT: return "hr_HR";
+        case SUBLANG_SERBIAN_LATIN: return "sr_CS";
+        case SUBLANG_SERBIAN_CYRILLIC: return "address@hidden";
+        }
+      return "hr";
+    case LANG_CZECH: return "cs_CZ";
+    case LANG_DANISH: return "da_DK";
+    case LANG_DIVEHI: return "dv_MV";
+    case LANG_DUTCH:
+      switch (sub)
+        {
+        case SUBLANG_DUTCH: return "nl_NL";
+        case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
+        }
+      return "nl";
+    case LANG_EDO: return "bin_NG";
+    case LANG_ENGLISH:
+      switch (sub)
+        {
+        /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
+         * English was the language spoken in England.
+         * Oh well.
+         */
+        case SUBLANG_ENGLISH_US: return "en_US";
+        case SUBLANG_ENGLISH_UK: return "en_GB";
+        case SUBLANG_ENGLISH_AUS: return "en_AU";
+        case SUBLANG_ENGLISH_CAN: return "en_CA";
+        case SUBLANG_ENGLISH_NZ: return "en_NZ";
+        case SUBLANG_ENGLISH_EIRE: return "en_IE";
+        case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
+        case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
+        case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
+        case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
+        case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
+        case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
+        case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
+        case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
+        case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
+        case SUBLANG_ENGLISH_INDIA: return "en_IN";
+        case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
+        case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
+        }
+      return "en";
+    case LANG_ESTONIAN: return "et_EE";
+    case LANG_FAEROESE: return "fo_FO";
+    case LANG_FARSI: return "fa_IR";
+    case LANG_FINNISH: return "fi_FI";
+    case LANG_FRENCH:
+      switch (sub)
+        {
+        case SUBLANG_FRENCH: return "fr_FR";
+        case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
+        case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
+        case SUBLANG_FRENCH_SWISS: return "fr_CH";
+        case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
+        case SUBLANG_FRENCH_MONACO: return "fr_MC";
+        case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
+        case SUBLANG_FRENCH_REUNION: return "fr_RE";
+        case SUBLANG_FRENCH_CONGO: return "fr_CG";
+        case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
+        case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
+        case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
+        case SUBLANG_FRENCH_MALI: return "fr_ML";
+        case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
+        case SUBLANG_FRENCH_HAITI: return "fr_HT";
+        }
+      return "fr";
+    case LANG_FRISIAN: return "fy_NL";
+    case LANG_FULFULDE:
+    /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin.  */
+    return "ff_NG";
+    case LANG_GAELIC:
+      switch (sub)
+        {
+        case 0x01: /* SCOTTISH */ return "gd_GB";
+        case 0x02: /* IRISH */ return "ga_IE";
+        }
+      return "C";
+    case LANG_GALICIAN: return "gl_ES";
+    case LANG_GEORGIAN: return "ka_GE";
+    case LANG_GERMAN:
+      switch (sub)
+        {
+        case SUBLANG_GERMAN: return "de_DE";
+        case SUBLANG_GERMAN_SWISS: return "de_CH";
+        case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
+        case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
+        case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
+        }
+      return "de";
+    case LANG_GREEK: return "el_GR";
+    case LANG_GUARANI: return "gn_PY";
+    case LANG_GUJARATI: return "gu_IN";
+    case LANG_HAUSA: return "ha_NG";
+    case LANG_HAWAIIAN:
+    /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
+       or Hawaii Creole English ("cpe_US", 600000 speakers)?  */
+    return "cpe_US";
+    case LANG_HEBREW: return "he_IL";
+    case LANG_HINDI: return "hi_IN";
+    case LANG_HUNGARIAN: return "hu_HU";
+    case LANG_IBIBIO: return "nic_NG";
+    case LANG_ICELANDIC: return "is_IS";
+    case LANG_IGBO: return "ig_NG";
+    case LANG_INDONESIAN: return "id_ID";
+    case LANG_INUKTITUT: return "iu_CA";
+    case LANG_ITALIAN:
+      switch (sub)
+        {
+        case SUBLANG_ITALIAN: return "it_IT";
+        case SUBLANG_ITALIAN_SWISS: return "it_CH";
+        }
+      return "it";
+    case LANG_JAPANESE: return "ja_JP";
+    case LANG_KANNADA: return "kn_IN";
+    case LANG_KANURI: return "kr_NG";
+    case LANG_KASHMIRI:
+      switch (sub)
+        {
+        case SUBLANG_DEFAULT: return "ks_PK";
+        case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
+        }
+      return "ks";
+    case LANG_KAZAK: return "kk_KZ";
+    case LANG_KONKANI:
+    /* FIXME: Adjust this when such locales appear on Unix.  */
+    return "kok_IN";
+    case LANG_KOREAN: return "ko_KR";
+    case LANG_KYRGYZ: return "ky_KG";
+    case LANG_LAO: return "lo_LA";
+    case LANG_LATIN: return "la_VA";
+    case LANG_LATVIAN: return "lv_LV";
+    case LANG_LITHUANIAN: return "lt_LT";
+    case LANG_MACEDONIAN: return "mk_MK";
+    case LANG_MALAY:
+      switch (sub)
+        {
+        case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
+        case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
+        }
+      return "ms";
+    case LANG_MALAYALAM: return "ml_IN";
+    case LANG_MALTESE: return "mt_MT";
+    case LANG_MANIPURI:
+      /* FIXME: Adjust this when such locales appear on Unix.  */
+      return "mni_IN";
+    case LANG_MARATHI: return "mr_IN";
+    case LANG_MONGOLIAN:
+      switch (sub)
+        {
+        case SUBLANG_DEFAULT: return "mn_MN";
+        }
+      return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN".  */
+    case LANG_NEPALI:
+      switch (sub)
+        {
+        case SUBLANG_DEFAULT: return "ne_NP";
+        case SUBLANG_NEPALI_INDIA: return "ne_IN";
+        }
+      return "ne";
+    case LANG_NORWEGIAN:
+      switch (sub)
+        {
+        case SUBLANG_NORWEGIAN_BOKMAL: return "nb_NO";
+        case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
+        }
+      return "no";
+    case LANG_ORIYA: return "or_IN";
+    case LANG_OROMO: return "om_ET";
+    case LANG_PAPIAMENTU: return "pap_AN";
+    case LANG_PASHTO:
+      return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF".  */
+    case LANG_POLISH: return "pl_PL";
+    case LANG_PORTUGUESE:
+      switch (sub)
+        {
+        case SUBLANG_PORTUGUESE: return "pt_PT";
+        /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
+           Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
+        case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
+        }
+      return "pt";
+    case LANG_PUNJABI:
+      switch (sub)
+        {
+        case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
+        case SUBLANG_PUNJABI_PAKISTAN: return "pa_PK"; /* Arabic script */
+        }
+      return "pa";
+    case LANG_RHAETO_ROMANCE: return "rm_CH";
+    case LANG_ROMANIAN:
+      switch (sub)
+        {
+        case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
+        case SUBLANG_ROMANIAN_MOLDOVA: return "ro_MD";
+        }
+      return "ro";
+    case LANG_RUSSIAN:
+      switch (sub)
+        {
+        case SUBLANG_DEFAULT: return "ru_RU";
+        }
+      return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD".  */
+    case LANG_SAAMI: /* actually Northern Sami */ return "se_NO";
+    case LANG_SANSKRIT: return "sa_IN";
+    case LANG_SINDHI:
+      switch (sub)
+        {
+        case SUBLANG_SINDHI_INDIA: return "sd_IN";
+        case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
+        }
+      return "sd";
+    case LANG_SINHALESE: return "si_LK";
+    case LANG_SLOVAK: return "sk_SK";
+    case LANG_SLOVENIAN: return "sl_SI";
+    case LANG_SOMALI: return "so_SO";
+    case LANG_SORBIAN:
+      /* FIXME: Adjust this when such locales appear on Unix.  */
+      return "wen_DE";
+    case LANG_SPANISH:
+      switch (sub)
+        {
+        case SUBLANG_SPANISH: return "es_ES";
+        case SUBLANG_SPANISH_MEXICAN: return "es_MX";
+        case SUBLANG_SPANISH_MODERN:
+          return "address@hidden";     /* not seen on Unix */
+        case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
+        case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
+        case SUBLANG_SPANISH_PANAMA: return "es_PA";
+        case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
+        case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
+        case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
+        case SUBLANG_SPANISH_PERU: return "es_PE";
+        case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
+        case SUBLANG_SPANISH_ECUADOR: return "es_EC";
+        case SUBLANG_SPANISH_CHILE: return "es_CL";
+        case SUBLANG_SPANISH_URUGUAY: return "es_UY";
+        case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
+        case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
+        case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
+        case SUBLANG_SPANISH_HONDURAS: return "es_HN";
+        case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
+        case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
+        }
+      return "es";
+    case LANG_SUTU: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
+    case LANG_SWAHILI: return "sw_KE";
+    case LANG_SWEDISH:
+      switch (sub)
+        {
+        case SUBLANG_DEFAULT: return "sv_SE";
+        case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
+        }
+      return "sv";
+    case LANG_SYRIAC: return "syr_TR"; /* An extinct language.  */
+    case LANG_TAGALOG: return "tl_PH";
+    case LANG_TAJIK: return "tg_TJ";
+    case LANG_TAMAZIGHT:
+      switch (sub)
+        {
+        /* FIXME: Adjust this when Tamazight locales appear on Unix.  */
+        case SUBLANG_TAMAZIGHT_ARABIC: return "address@hidden";
+        case SUBLANG_TAMAZIGHT_LATIN: return "address@hidden";
+        }
+      return "ber_MA";
+    case LANG_TAMIL:
+      switch (sub)
+        {
+        case SUBLANG_DEFAULT: return "ta_IN";
+        }
+      return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG".  */
+    case LANG_TATAR: return "tt_RU";
+    case LANG_TELUGU: return "te_IN";
+    case LANG_THAI: return "th_TH";
+    case LANG_TIBETAN: return "bo_CN";
+    case LANG_TIGRINYA:
+      switch (sub)
+        {
+        case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
+        case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
+        }
+      return "ti";
+    case LANG_TSONGA: return "ts_ZA";
+    case LANG_TSWANA: return "tn_BW";
+    case LANG_TURKISH: return "tr_TR";
+    case LANG_TURKMEN: return "tk_TM";
+    case LANG_UKRAINIAN: return "uk_UA";
+    case LANG_URDU:
+      switch (sub)
+        {
+        case SUBLANG_URDU_PAKISTAN: return "ur_PK";
+        case SUBLANG_URDU_INDIA: return "ur_IN";
+        }
+      return "ur";
+    case LANG_UZBEK:
+      switch (sub)
+        {
+        case SUBLANG_UZBEK_LATIN: return "uz_UZ";
+        case SUBLANG_UZBEK_CYRILLIC: return "address@hidden";
+        }
+      return "uz";
+    case LANG_VENDA: return "ve_ZA";
+    case LANG_VIETNAMESE: return "vi_VN";
+    case LANG_WELSH: return "cy_GB";
+    case LANG_XHOSA: return "xh_ZA";
+    case LANG_YI: return "sit_CN";
+    case LANG_YIDDISH: return "yi_IL";
+    case LANG_YORUBA: return "yo_NG";
+    case LANG_ZULU: return "zu_ZA";
+    default: return "C";
+    }
+}
+
+const char *_nl_lcid_name_np(unsigned long lcid)
+{
+  /* Strip off the sorting rules, keep only the language part.  */
+  return _nl_langid_name_np(LANGIDFROMLCID(lcid));
+}
 #endif

 # if HAVE_CFLOCALECOPYCURRENT || HAVE_CFPREFERENCESCOPYAPPVALUE
@@ -1078,409 +1536,7 @@

 # if defined(WIN32_NATIVE) /* WIN32, not Cygwin */
   {
-    LCID lcid;
-    LANGID langid;
-    int primary, sub;
-
-    /* Use native Win32 API locale ID.  */
-    lcid = GetThreadLocale ();
-
-    /* Strip off the sorting rules, keep only the language part.  */
-    langid = LANGIDFROMLCID (lcid);
-
-    /* Split into language and territory part.  */
-    primary = PRIMARYLANGID (langid);
-    sub = SUBLANGID (langid);
-
-    /* Dispatch on language.
-       See also http://www.unicode.org/unicode/onlinedat/languages.html .
-       For details about languages, see http://www.ethnologue.com/ .  */
-    switch (primary)
-      {
-      case LANG_AFRIKAANS: return "af_ZA";
-      case LANG_ALBANIAN: return "sq_AL";
-      case LANG_AMHARIC: return "am_ET";
-      case LANG_ARABIC:
-       switch (sub)
-         {
-         case SUBLANG_ARABIC_SAUDI_ARABIA: return "ar_SA";
-         case SUBLANG_ARABIC_IRAQ: return "ar_IQ";
-         case SUBLANG_ARABIC_EGYPT: return "ar_EG";
-         case SUBLANG_ARABIC_LIBYA: return "ar_LY";
-         case SUBLANG_ARABIC_ALGERIA: return "ar_DZ";
-         case SUBLANG_ARABIC_MOROCCO: return "ar_MA";
-         case SUBLANG_ARABIC_TUNISIA: return "ar_TN";
-         case SUBLANG_ARABIC_OMAN: return "ar_OM";
-         case SUBLANG_ARABIC_YEMEN: return "ar_YE";
-         case SUBLANG_ARABIC_SYRIA: return "ar_SY";
-         case SUBLANG_ARABIC_JORDAN: return "ar_JO";
-         case SUBLANG_ARABIC_LEBANON: return "ar_LB";
-         case SUBLANG_ARABIC_KUWAIT: return "ar_KW";
-         case SUBLANG_ARABIC_UAE: return "ar_AE";
-         case SUBLANG_ARABIC_BAHRAIN: return "ar_BH";
-         case SUBLANG_ARABIC_QATAR: return "ar_QA";
-         }
-       return "ar";
-      case LANG_ARMENIAN: return "hy_AM";
-      case LANG_ASSAMESE: return "as_IN";
-      case LANG_AZERI:
-       switch (sub)
-         {
-         /* FIXME: Adjust this when Azerbaijani locales appear on Unix.  */
-         case SUBLANG_AZERI_LATIN: return "address@hidden";
-         case SUBLANG_AZERI_CYRILLIC: return "address@hidden";
-         }
-       return "az";
-      case LANG_BASQUE:
-       switch (sub)
-         {
-         case SUBLANG_DEFAULT: return "eu_ES";
-         }
-       return "eu"; /* Ambiguous: could be "eu_ES" or "eu_FR".  */
-      case LANG_BELARUSIAN: return "be_BY";
-      case LANG_BENGALI:
-       switch (sub)
-         {
-         case SUBLANG_BENGALI_INDIA: return "bn_IN";
-         case SUBLANG_BENGALI_BANGLADESH: return "bn_BD";
-         }
-       return "bn";
-      case LANG_BULGARIAN: return "bg_BG";
-      case LANG_BURMESE: return "my_MM";
-      case LANG_CAMBODIAN: return "km_KH";
-      case LANG_CATALAN: return "ca_ES";
-      case LANG_CHEROKEE: return "chr_US";
-      case LANG_CHINESE:
-       switch (sub)
-         {
-         case SUBLANG_CHINESE_TRADITIONAL: return "zh_TW";
-         case SUBLANG_CHINESE_SIMPLIFIED: return "zh_CN";
-         case SUBLANG_CHINESE_HONGKONG: return "zh_HK";
-         case SUBLANG_CHINESE_SINGAPORE: return "zh_SG";
-         case SUBLANG_CHINESE_MACAU: return "zh_MO";
-         }
-       return "zh";
-      case LANG_CROATIAN:       /* LANG_CROATIAN == LANG_SERBIAN
-                                * What used to be called Serbo-Croatian
-                                * should really now be two separate
-                                * languages because of political reasons.
-                                * (Says tml, who knows nothing about Serbian
-                                * or Croatian.)
-                                * (I can feel those flames coming already.)
-                                */
-       switch (sub)
-         {
-         case SUBLANG_DEFAULT: return "hr_HR";
-         case SUBLANG_SERBIAN_LATIN: return "sr_CS";
-         case SUBLANG_SERBIAN_CYRILLIC: return "address@hidden";
-         }
-       return "hr";
-      case LANG_CZECH: return "cs_CZ";
-      case LANG_DANISH: return "da_DK";
-      case LANG_DIVEHI: return "dv_MV";
-      case LANG_DUTCH:
-       switch (sub)
-         {
-         case SUBLANG_DUTCH: return "nl_NL";
-         case SUBLANG_DUTCH_BELGIAN: /* FLEMISH, VLAAMS */ return "nl_BE";
-         }
-       return "nl";
-      case LANG_EDO: return "bin_NG";
-      case LANG_ENGLISH:
-       switch (sub)
-         {
-         /* SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. Heh. I thought
-          * English was the language spoken in England.
-          * Oh well.
-          */
-         case SUBLANG_ENGLISH_US: return "en_US";
-         case SUBLANG_ENGLISH_UK: return "en_GB";
-         case SUBLANG_ENGLISH_AUS: return "en_AU";
-         case SUBLANG_ENGLISH_CAN: return "en_CA";
-         case SUBLANG_ENGLISH_NZ: return "en_NZ";
-         case SUBLANG_ENGLISH_EIRE: return "en_IE";
-         case SUBLANG_ENGLISH_SOUTH_AFRICA: return "en_ZA";
-         case SUBLANG_ENGLISH_JAMAICA: return "en_JM";
-         case SUBLANG_ENGLISH_CARIBBEAN: return "en_GD"; /* Grenada? */
-         case SUBLANG_ENGLISH_BELIZE: return "en_BZ";
-         case SUBLANG_ENGLISH_TRINIDAD: return "en_TT";
-         case SUBLANG_ENGLISH_ZIMBABWE: return "en_ZW";
-         case SUBLANG_ENGLISH_PHILIPPINES: return "en_PH";
-         case SUBLANG_ENGLISH_INDONESIA: return "en_ID";
-         case SUBLANG_ENGLISH_HONGKONG: return "en_HK";
-         case SUBLANG_ENGLISH_INDIA: return "en_IN";
-         case SUBLANG_ENGLISH_MALAYSIA: return "en_MY";
-         case SUBLANG_ENGLISH_SINGAPORE: return "en_SG";
-         }
-       return "en";
-      case LANG_ESTONIAN: return "et_EE";
-      case LANG_FAEROESE: return "fo_FO";
-      case LANG_FARSI: return "fa_IR";
-      case LANG_FINNISH: return "fi_FI";
-      case LANG_FRENCH:
-       switch (sub)
-         {
-         case SUBLANG_FRENCH: return "fr_FR";
-         case SUBLANG_FRENCH_BELGIAN: /* WALLOON */ return "fr_BE";
-         case SUBLANG_FRENCH_CANADIAN: return "fr_CA";
-         case SUBLANG_FRENCH_SWISS: return "fr_CH";
-         case SUBLANG_FRENCH_LUXEMBOURG: return "fr_LU";
-         case SUBLANG_FRENCH_MONACO: return "fr_MC";
-         case SUBLANG_FRENCH_WESTINDIES: return "fr"; /* Caribbean? */
-         case SUBLANG_FRENCH_REUNION: return "fr_RE";
-         case SUBLANG_FRENCH_CONGO: return "fr_CG";
-         case SUBLANG_FRENCH_SENEGAL: return "fr_SN";
-         case SUBLANG_FRENCH_CAMEROON: return "fr_CM";
-         case SUBLANG_FRENCH_COTEDIVOIRE: return "fr_CI";
-         case SUBLANG_FRENCH_MALI: return "fr_ML";
-         case SUBLANG_FRENCH_MOROCCO: return "fr_MA";
-         case SUBLANG_FRENCH_HAITI: return "fr_HT";
-         }
-       return "fr";
-      case LANG_FRISIAN: return "fy_NL";
-      case LANG_FULFULDE:
-       /* Spoken in Nigeria, Guinea, Senegal, Mali, Niger, Cameroon, Benin.  */
-       return "ff_NG";
-      case LANG_GAELIC:
-       switch (sub)
-         {
-         case 0x01: /* SCOTTISH */ return "gd_GB";
-         case 0x02: /* IRISH */ return "ga_IE";
-         }
-       return "C";
-      case LANG_GALICIAN: return "gl_ES";
-      case LANG_GEORGIAN: return "ka_GE";
-      case LANG_GERMAN:
-       switch (sub)
-         {
-         case SUBLANG_GERMAN: return "de_DE";
-         case SUBLANG_GERMAN_SWISS: return "de_CH";
-         case SUBLANG_GERMAN_AUSTRIAN: return "de_AT";
-         case SUBLANG_GERMAN_LUXEMBOURG: return "de_LU";
-         case SUBLANG_GERMAN_LIECHTENSTEIN: return "de_LI";
-         }
-       return "de";
-      case LANG_GREEK: return "el_GR";
-      case LANG_GUARANI: return "gn_PY";
-      case LANG_GUJARATI: return "gu_IN";
-      case LANG_HAUSA: return "ha_NG";
-      case LANG_HAWAIIAN:
-       /* FIXME: Do they mean Hawaiian ("haw_US", 1000 speakers)
-          or Hawaii Creole English ("cpe_US", 600000 speakers)?  */
-       return "cpe_US";
-      case LANG_HEBREW: return "he_IL";
-      case LANG_HINDI: return "hi_IN";
-      case LANG_HUNGARIAN: return "hu_HU";
-      case LANG_IBIBIO: return "nic_NG";
-      case LANG_ICELANDIC: return "is_IS";
-      case LANG_IGBO: return "ig_NG";
-      case LANG_INDONESIAN: return "id_ID";
-      case LANG_INUKTITUT: return "iu_CA";
-      case LANG_ITALIAN:
-       switch (sub)
-         {
-         case SUBLANG_ITALIAN: return "it_IT";
-         case SUBLANG_ITALIAN_SWISS: return "it_CH";
-         }
-       return "it";
-      case LANG_JAPANESE: return "ja_JP";
-      case LANG_KANNADA: return "kn_IN";
-      case LANG_KANURI: return "kr_NG";
-      case LANG_KASHMIRI:
-       switch (sub)
-         {
-         case SUBLANG_DEFAULT: return "ks_PK";
-         case SUBLANG_KASHMIRI_INDIA: return "ks_IN";
-         }
-       return "ks";
-      case LANG_KAZAK: return "kk_KZ";
-      case LANG_KONKANI:
-       /* FIXME: Adjust this when such locales appear on Unix.  */
-       return "kok_IN";
-      case LANG_KOREAN: return "ko_KR";
-      case LANG_KYRGYZ: return "ky_KG";
-      case LANG_LAO: return "lo_LA";
-      case LANG_LATIN: return "la_VA";
-      case LANG_LATVIAN: return "lv_LV";
-      case LANG_LITHUANIAN: return "lt_LT";
-      case LANG_MACEDONIAN: return "mk_MK";
-      case LANG_MALAY:
-       switch (sub)
-         {
-         case SUBLANG_MALAY_MALAYSIA: return "ms_MY";
-         case SUBLANG_MALAY_BRUNEI_DARUSSALAM: return "ms_BN";
-         }
-       return "ms";
-      case LANG_MALAYALAM: return "ml_IN";
-      case LANG_MALTESE: return "mt_MT";
-      case LANG_MANIPURI:
-       /* FIXME: Adjust this when such locales appear on Unix.  */
-       return "mni_IN";
-      case LANG_MARATHI: return "mr_IN";
-      case LANG_MONGOLIAN:
-       switch (sub)
-         {
-         case SUBLANG_DEFAULT: return "mn_MN";
-         }
-       return "mn"; /* Ambiguous: could be "mn_CN" or "mn_MN".  */
-      case LANG_NEPALI:
-       switch (sub)
-         {
-         case SUBLANG_DEFAULT: return "ne_NP";
-         case SUBLANG_NEPALI_INDIA: return "ne_IN";
-         }
-       return "ne";
-      case LANG_NORWEGIAN:
-       switch (sub)
-         {
-         case SUBLANG_NORWEGIAN_BOKMAL: return "nb_NO";
-         case SUBLANG_NORWEGIAN_NYNORSK: return "nn_NO";
-         }
-       return "no";
-      case LANG_ORIYA: return "or_IN";
-      case LANG_OROMO: return "om_ET";
-      case LANG_PAPIAMENTU: return "pap_AN";
-      case LANG_PASHTO:
-       return "ps"; /* Ambiguous: could be "ps_PK" or "ps_AF".  */
-      case LANG_POLISH: return "pl_PL";
-      case LANG_PORTUGUESE:
-       switch (sub)
-         {
-         case SUBLANG_PORTUGUESE: return "pt_PT";
-         /* Hmm. SUBLANG_PORTUGUESE_BRAZILIAN == SUBLANG_DEFAULT.
-            Same phenomenon as SUBLANG_ENGLISH_US == SUBLANG_DEFAULT. */
-         case SUBLANG_PORTUGUESE_BRAZILIAN: return "pt_BR";
-         }
-       return "pt";
-      case LANG_PUNJABI:
-       switch (sub)
-         {
-         case SUBLANG_PUNJABI_INDIA: return "pa_IN"; /* Gurmukhi script */
-         case SUBLANG_PUNJABI_PAKISTAN: return "pa_PK"; /* Arabic script */
-         }
-       return "pa";
-      case LANG_RHAETO_ROMANCE: return "rm_CH";
-      case LANG_ROMANIAN:
-       switch (sub)
-         {
-         case SUBLANG_ROMANIAN_ROMANIA: return "ro_RO";
-         case SUBLANG_ROMANIAN_MOLDOVA: return "ro_MD";
-         }
-       return "ro";
-      case LANG_RUSSIAN:
-       switch (sub)
-         {
-         case SUBLANG_DEFAULT: return "ru_RU";
-         }
-       return "ru"; /* Ambiguous: could be "ru_RU" or "ru_UA" or "ru_MD".  */
-      case LANG_SAAMI: /* actually Northern Sami */ return "se_NO";
-      case LANG_SANSKRIT: return "sa_IN";
-      case LANG_SINDHI:
-       switch (sub)
-         {
-         case SUBLANG_SINDHI_INDIA: return "sd_IN";
-         case SUBLANG_SINDHI_PAKISTAN: return "sd_PK";
-         }
-       return "sd";
-      case LANG_SINHALESE: return "si_LK";
-      case LANG_SLOVAK: return "sk_SK";
-      case LANG_SLOVENIAN: return "sl_SI";
-      case LANG_SOMALI: return "so_SO";
-      case LANG_SORBIAN:
-       /* FIXME: Adjust this when such locales appear on Unix.  */
-       return "wen_DE";
-      case LANG_SPANISH:
-       switch (sub)
-         {
-         case SUBLANG_SPANISH: return "es_ES";
-         case SUBLANG_SPANISH_MEXICAN: return "es_MX";
-         case SUBLANG_SPANISH_MODERN:
-           return "address@hidden";    /* not seen on Unix */
-         case SUBLANG_SPANISH_GUATEMALA: return "es_GT";
-         case SUBLANG_SPANISH_COSTA_RICA: return "es_CR";
-         case SUBLANG_SPANISH_PANAMA: return "es_PA";
-         case SUBLANG_SPANISH_DOMINICAN_REPUBLIC: return "es_DO";
-         case SUBLANG_SPANISH_VENEZUELA: return "es_VE";
-         case SUBLANG_SPANISH_COLOMBIA: return "es_CO";
-         case SUBLANG_SPANISH_PERU: return "es_PE";
-         case SUBLANG_SPANISH_ARGENTINA: return "es_AR";
-         case SUBLANG_SPANISH_ECUADOR: return "es_EC";
-         case SUBLANG_SPANISH_CHILE: return "es_CL";
-         case SUBLANG_SPANISH_URUGUAY: return "es_UY";
-         case SUBLANG_SPANISH_PARAGUAY: return "es_PY";
-         case SUBLANG_SPANISH_BOLIVIA: return "es_BO";
-         case SUBLANG_SPANISH_EL_SALVADOR: return "es_SV";
-         case SUBLANG_SPANISH_HONDURAS: return "es_HN";
-         case SUBLANG_SPANISH_NICARAGUA: return "es_NI";
-         case SUBLANG_SPANISH_PUERTO_RICO: return "es_PR";
-         }
-       return "es";
-      case LANG_SUTU: return "bnt_TZ"; /* or "st_LS" or "nso_ZA"? */
-      case LANG_SWAHILI: return "sw_KE";
-      case LANG_SWEDISH:
-       switch (sub)
-         {
-         case SUBLANG_DEFAULT: return "sv_SE";
-         case SUBLANG_SWEDISH_FINLAND: return "sv_FI";
-         }
-       return "sv";
-      case LANG_SYRIAC: return "syr_TR"; /* An extinct language.  */
-      case LANG_TAGALOG: return "tl_PH";
-      case LANG_TAJIK: return "tg_TJ";
-      case LANG_TAMAZIGHT:
-       switch (sub)
-         {
-         /* FIXME: Adjust this when Tamazight locales appear on Unix.  */
-         case SUBLANG_TAMAZIGHT_ARABIC: return "address@hidden";
-         case SUBLANG_TAMAZIGHT_LATIN: return "address@hidden";
-         }
-       return "ber_MA";
-      case LANG_TAMIL:
-       switch (sub)
-         {
-         case SUBLANG_DEFAULT: return "ta_IN";
-         }
-       return "ta"; /* Ambiguous: could be "ta_IN" or "ta_LK" or "ta_SG".  */
-      case LANG_TATAR: return "tt_RU";
-      case LANG_TELUGU: return "te_IN";
-      case LANG_THAI: return "th_TH";
-      case LANG_TIBETAN: return "bo_CN";
-      case LANG_TIGRINYA:
-       switch (sub)
-         {
-         case SUBLANG_TIGRINYA_ETHIOPIA: return "ti_ET";
-         case SUBLANG_TIGRINYA_ERITREA: return "ti_ER";
-         }
-       return "ti";
-      case LANG_TSONGA: return "ts_ZA";
-      case LANG_TSWANA: return "tn_BW";
-      case LANG_TURKISH: return "tr_TR";
-      case LANG_TURKMEN: return "tk_TM";
-      case LANG_UKRAINIAN: return "uk_UA";
-      case LANG_URDU:
-       switch (sub)
-         {
-         case SUBLANG_URDU_PAKISTAN: return "ur_PK";
-         case SUBLANG_URDU_INDIA: return "ur_IN";
-         }
-       return "ur";
-      case LANG_UZBEK:
-       switch (sub)
-         {
-         case SUBLANG_UZBEK_LATIN: return "uz_UZ";
-         case SUBLANG_UZBEK_CYRILLIC: return "address@hidden";
-         }
-       return "uz";
-      case LANG_VENDA: return "ve_ZA";
-      case LANG_VIETNAMESE: return "vi_VN";
-      case LANG_WELSH: return "cy_GB";
-      case LANG_XHOSA: return "xh_ZA";
-      case LANG_YI: return "sit_CN";
-      case LANG_YIDDISH: return "yi_IL";
-      case LANG_YORUBA: return "yo_NG";
-      case LANG_ZULU: return "zu_ZA";
-      default: return "C";
-      }
+    return _nl_lcid_name_np(GetThreadLocale());
   }
 # endif
 #endif


--- End Message ---
--- Begin Message --- Subject: confirm ce820ab288ca72972c079522551c33a8b686e03a
If you reply to this message, keeping the Subject: header intact,
Mailman will discard the held message.  Do this if the message is
spam.  If you reply to this message and include an Approved: header
with the list password in it, the message will be approved for posting
to the list.  The Approved: header can also appear in the first line
of the body of the reply.

--- End Message ---

reply via email to

[Prev in Thread] Current Thread [Next in Thread]