--- lib/localcharset.c~0	2010-01-01 13:02:02 +0200
+++ lib/localcharset.c	2014-06-12 12:23:39 +0300
@@ -35,6 +35,7 @@
 
 #if defined _WIN32 || defined __WIN32__
 # define WIN32_NATIVE
+# include <locale.h>
 #endif
 
 #if defined __EMX__
@@ -459,14 +460,34 @@ locale_charset (void)
 
   static char buf[2 + 10 + 1];
 
-  /* Woe32 has a function returning the locale's codepage as a number:
-     GetACP().
-     When the output goes to a console window, it needs to be provided in
-     GetOEMCP() encoding if the console is using a raster font, or in
-     GetConsoleOutputCP() encoding if it is using a TrueType font.
-     But in GUI programs and for output sent to files and pipes, GetACP()
-     encoding is the best bet.  */
-  sprintf (buf, "CP%u", GetACP ());
+  /* The Windows API has a function returning the locale's codepage as
+     a number, but the value doesn't change according to what the
+     'setlocale' call specified.  So we use it as a last resort, in
+     case the string returned by 'setlocale' doesn't specify the
+     codepage.  */
+  char *current_locale = setlocale (LC_ALL, NULL);
+  char *pdot;
+
+  /* If they set different locales for different categories,
+     'setlocale' will return a semi-colon separated list of locale
+     values.  To make sure we use the correct one, we choose LC_CTYPE.  */
+  if (strchr (current_locale, ';'))
+    current_locale = setlocale (LC_CTYPE, NULL);
+
+  pdot = strrchr (current_locale, '.');
+  if (pdot)
+    sprintf (buf, "CP%s", pdot + 1);
+  else
+    {
+      /* Woe32 has a function returning the system locale's default
+	 codepage as a number: GetACP().  When the output goes to a
+	 console window, it needs to be provided in GetOEMCP()
+	 encoding if the console is using a raster font, or in
+	 GetConsoleOutputCP() encoding if it is using a TrueType font.
+	 But in GUI programs and for output sent to files and pipes,
+	 GetACP() encoding is the best bet.  */
+      sprintf (buf, "CP%u", GetACP ());
+    }
   codeset = buf;
 
 #elif defined OS2


--- lib/localename.c~0	2010-04-03 12:43:57 +0300
+++ lib/localename.c	2014-08-07 09:27:05 +0300
@@ -57,11 +57,15 @@
 
 #if defined _WIN32 || defined __WIN32__
 # define WIN32_NATIVE
+# if !defined IN_LIBINTL
+#  include "glthread/lock.h"
+# endif
 #endif
 
 #if defined WIN32_NATIVE || defined __CYGWIN__ /* WIN32 or Cygwin */
 # define WIN32_LEAN_AND_MEAN
 # include <windows.h>
+# include <winnls.h>
 /* List of language codes, sorted by value:
    0x01 LANG_ARABIC
    0x02 LANG_BULGARIAN
@@ -1126,6 +1130,9 @@
 # ifndef LOCALE_SNAME
 # define LOCALE_SNAME 0x5c
 # endif
+# ifndef LOCALE_NAME_MAX_LENGTH
+# define LOCALE_NAME_MAX_LENGTH 85
+# endif
 #endif
 
 
@@ -2504,6 +2511,78 @@ gl_locale_name_from_win32_LCID (LCID lci
   return gl_locale_name_from_win32_LANGID (langid);
 }
 
+#ifdef WIN32_NATIVE
+
+/* Two variables to interface between get_lcid and the EnumLocales
+   callback function below.  */
+static LCID found_lcid;
+static char lname[LC_MAX * (LOCALE_NAME_MAX_LENGTH + 1) + 1];
+
+/* Callback function for EnumLocales.  */
+static BOOL CALLBACK
+enum_locales_fn (LPTSTR locale_num_str)
+{
+  char *endp;
+  char locval[2 * LOCALE_NAME_MAX_LENGTH + 1 + 1];
+  LCID try_lcid = strtoul (locale_num_str, &endp, 16);
+
+  if (GetLocaleInfo (try_lcid, LOCALE_SENGLANGUAGE,
+		     locval, LOCALE_NAME_MAX_LENGTH))
+    {
+      strcat (locval, "_");
+      if (GetLocaleInfo (try_lcid, LOCALE_SENGCOUNTRY,
+			 locval + strlen (locval), LOCALE_NAME_MAX_LENGTH))
+	{
+	  size_t locval_len = strlen (locval);
+
+	  if (strncmp (locval, lname, locval_len) == 0
+	      && (lname[locval_len] == '.'
+		  || lname[locval_len] == '\0'))
+	    {
+	      found_lcid = try_lcid;
+	      return FALSE;
+	    }
+	}
+    }
+  return TRUE;
+}
+
+/* This lock protects the get_lcid against multiple simultaneous calls.  */
+gl_lock_define_initialized(static, get_lcid_lock)
+
+/* Return the Locale ID (LCID) number given the locale's name, a
+   string, in LOCALE_NAME.  This works by enumerating all the locales
+   supported by the system, until we find one whose name matches
+   LOCALE_NAME.  */
+static LCID
+get_lcid (const char *locale_name)
+{
+  /* A simple cache.  */
+  static LCID last_lcid;
+  static char last_locale[1000];
+
+  /* Lock while looking for an LCID, to protect access to static
+     variables: last_lcid, last_locale, found_lcid, and lname.  */
+  gl_lock_lock (get_lcid_lock);
+  if (last_lcid > 0 && strcmp (locale_name, last_locale) == 0)
+    {
+      gl_lock_unlock (get_lcid_lock);
+      return last_lcid;
+    }
+  strncpy (lname, locale_name, sizeof (lname) - 1);
+  lname[sizeof (lname) - 1] = '\0';
+  found_lcid = 0;
+  EnumSystemLocales (enum_locales_fn, LCID_SUPPORTED);
+  if (found_lcid > 0)
+    {
+      last_lcid = found_lcid;
+      strcpy (last_locale, locale_name);
+    }
+  gl_lock_unlock (get_lcid_lock);
+  return found_lcid;
+}
+
+#endif
 #endif
 
 
@@ -2761,6 +2840,26 @@ gl_locale_name_thread (int category, con
   const char *name = gl_locale_name_thread_unsafe (category, categoryname);
   if (name != NULL)
     return struniq (name);
+#elif defined WIN32_NATIVE
+  if (LC_MIN <= category && category <= LC_MAX)
+    {
+      char *locname = setlocale (category, NULL);
+
+      /* If CATEGORY is LC_ALL, the result might be a semi-colon
+	 separated list of locales.  We need only one, so we take the
+	 one corresponding to LC_CTYPE, as the most important for
+	 character translations.  */
+      if (strchr (locname, ';'))
+	locname = setlocale (LC_CTYPE, NULL);
+
+    /* Convert locale name to LCID.  We don't want to use
+       LocaleNameToLCID because (a) it is only available since Vista,
+       and (b) it doesn't accept locale names returned by 'setlocale'.  */
+    LCID lcid = get_lcid (locname);
+
+    if (lcid > 0)
+      return gl_locale_name_from_win32_LCID (lcid);
+  }
 #endif
   return NULL;
 }
--- tests/test-xalloc-die.c~0	2010-01-01 13:02:13 +0200
+++ tests/test-xalloc-die.c	2014-06-12 11:55:47 +0300
@@ -19,6 +19,7 @@
 #include <config.h>
 
 #include "xalloc.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 
 int
--- tests/uniname/test-uninames.c~0	2010-01-01 13:02:15 +0200
+++ tests/uniname/test-uninames.c	2014-06-12 11:55:03 +0300
@@ -23,6 +23,7 @@
 
 #include "xalloc.h"
 #include "uniname.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 
 /* The names according to the UnicodeData.txt file, modified to contain the
--- tests/uninorm/test-u32-nfc-big.c~0	2010-03-29 05:39:13 +0300
+++ tests/uninorm/test-u32-nfc-big.c	2014-06-12 11:56:40 +0300
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 
 #include "unistr.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "test-u32-normalize-big.h"
 
--- tests/uninorm/test-u32-nfd-big.c~0	2010-03-29 05:39:13 +0300
+++ tests/uninorm/test-u32-nfd-big.c	2014-06-12 11:57:14 +0300
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 
 #include "unistr.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "test-u32-normalize-big.h"
 
--- tests/uninorm/test-u32-nfkc-big.c~0	2010-03-29 05:39:13 +0300
+++ tests/uninorm/test-u32-nfkc-big.c	2014-06-12 11:57:36 +0300
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 
 #include "unistr.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "test-u32-normalize-big.h"
 
--- tests/uninorm/test-u32-nfkd-big.c~0	2010-03-29 05:39:13 +0300
+++ tests/uninorm/test-u32-nfkd-big.c	2014-06-12 11:57:52 +0300
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 
 #include "unistr.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "test-u32-normalize-big.h"
 
--- tests/unistdio/test-u16-vsnprintf1.c~0	2010-01-01 13:02:16 +0200
+++ tests/unistdio/test-u16-vsnprintf1.c	2014-06-12 11:58:36 +0300
@@ -29,6 +29,7 @@
 
 #include "unistr.h"
 #include "xalloc.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "macros.h"
 
--- tests/unistdio/test-u32-vsnprintf1.c~0	2010-01-01 13:02:16 +0200
+++ tests/unistdio/test-u32-vsnprintf1.c	2014-06-12 11:59:19 +0300
@@ -29,6 +29,7 @@
 
 #include "unistr.h"
 #include "xalloc.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "macros.h"
 
--- tests/unistdio/test-u8-vsnprintf1.c~0	2010-01-01 13:02:16 +0200
+++ tests/unistdio/test-u8-vsnprintf1.c	2014-06-12 12:00:07 +0300
@@ -29,6 +29,7 @@
 
 #include "unistr.h"
 #include "xalloc.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "macros.h"
 
--- tests/unistdio/test-ulc-vsnprintf1.c~0	2010-01-01 13:02:16 +0200
+++ tests/unistdio/test-ulc-vsnprintf1.c	2014-06-12 12:00:44 +0300
@@ -27,6 +27,7 @@
 #include <string.h>
 
 #include "xalloc.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "macros.h"
 
--- tests/unistdio/test-ulc-vsprintf1.c~0	2010-01-01 13:02:16 +0200
+++ tests/unistdio/test-ulc-vsprintf1.c	2014-06-12 12:00:59 +0300
@@ -27,6 +27,7 @@
 #include <string.h>
 
 #include "xalloc.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "macros.h"
 
--- tests/unistdio/test-u16-vsprintf1.c~0	2010-01-01 13:02:16 +0200
+++ tests/unistdio/test-u16-vsprintf1.c	2014-06-12 11:58:57 +0300
@@ -29,6 +29,7 @@
 
 #include "unistr.h"
 #include "xalloc.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "macros.h"
 
--- tests/unistdio/test-u32-vsprintf1.c~0	2010-01-01 13:02:16 +0200
+++ tests/unistdio/test-u32-vsprintf1.c	2014-06-12 11:59:41 +0300
@@ -29,6 +29,7 @@
 
 #include "unistr.h"
 #include "xalloc.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "macros.h"
 
--- tests/unistdio/test-u8-vsprintf1.c~0	2010-01-01 13:02:16 +0200
+++ tests/unistdio/test-u8-vsprintf1.c	2014-06-12 12:00:22 +0300
@@ -29,6 +29,7 @@
 
 #include "unistr.h"
 #include "xalloc.h"
+#undef ENABLE_RELOCATABLE /* avoid defining set_program_name as a macro */
 #include "progname.h"
 #include "macros.h"
 
--- tests/test-localename.c~0	2014-06-12 16:31:07 +0300
+++ tests/test-localename.c	2014-06-15 09:46:00 +0300
@@ -69,7 +69,11 @@ test_locale_name (void)
   ASSERT (gl_locale_name (LC_MESSAGES, "LC_MESSAGES") != NULL);
 
   /* Get into a defined state,  */
+#ifdef __MINGW32__
+  setlocale (LC_ALL, "enu_USA.1252");
+#else
   setlocale (LC_ALL, "en_US.UTF-8");
+#endif
 #if HAVE_NEWLOCALE
   uselocale (LC_GLOBAL_LOCALE);
 #endif
@@ -97,6 +101,8 @@ test_locale_name (void)
   setlocale (LC_ALL, "");
   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
                   gl_locale_name_default ()) == 0);
+  ASSERT (strcmp (gl_locale_name (LC_NUMERIC, "LC_NUMERIC"),
+                  gl_locale_name_default ()) == 0);
 
   unsetenv ("LC_ALL");
   setenv ("LC_CTYPE", "", 1);
@@ -105,6 +111,8 @@ test_locale_name (void)
   setlocale (LC_ALL, "");
   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
                   gl_locale_name_default ()) == 0);
+  ASSERT (strcmp (gl_locale_name (LC_NUMERIC, "LC_NUMERIC"),
+                  gl_locale_name_default ()) == 0);
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
@@ -113,6 +121,8 @@ test_locale_name (void)
   setlocale (LC_ALL, "");
   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
                   gl_locale_name_default ()) == 0);
+  ASSERT (strcmp (gl_locale_name (LC_NUMERIC, "LC_NUMERIC"),
+                  gl_locale_name_default ()) == 0);
 
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
@@ -121,22 +131,32 @@ test_locale_name (void)
   setlocale (LC_ALL, "");
   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"),
                   gl_locale_name_default ()) == 0);
+  ASSERT (strcmp (gl_locale_name (LC_NUMERIC, "LC_NUMERIC"),
+                  gl_locale_name_default ()) == 0);
 
   /* Check that LC_ALL overrides the others, and LANG is overridden by the
      others.  */
 
-  setenv ("LC_ALL", "C", 1);
   unsetenv ("LC_CTYPE");
   unsetenv ("LC_MESSAGES");
   unsetenv ("LANG");
-  setlocale (LC_ALL, "");
+  setenv ("LC_ALL", "C", 1);
+  setlocale (LC_ALL, "C");
+#ifdef __MINGW32__
+  ASSERT (strcmp (gl_locale_name (LC_CTYPE, "LC_CTYPE"), "C") == 0);
+#endif
   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
 
   unsetenv ("LC_ALL");
-  setenv ("LC_CTYPE", "C", 1);
   setenv ("LC_MESSAGES", "C", 1);
   unsetenv ("LANG");
+#ifdef __MINGW32__
   setlocale (LC_ALL, "");
+  setlocale (LC_CTYPE, "C");
+#else
+  setenv ("LC_CTYPE", "C", 1);
+  setlocale (LC_ALL, "");
+#endif
   ASSERT (strcmp (gl_locale_name (LC_MESSAGES, "LC_MESSAGES"), "C") == 0);
 
   unsetenv ("LC_ALL");
@@ -151,11 +171,19 @@ test_locale_name (void)
   unsetenv ("LC_ALL");
   unsetenv ("LC_CTYPE");
   setenv ("LC_MESSAGES", "fr_FR.UTF-8", 1);
+#ifndef __MINGW32__
   setenv ("LANG", "de_DE.UTF-8", 1);
   if (setlocale (LC_ALL, "") != NULL)
+#else
+  if (setlocale (LC_ALL, "deu_DEU.1252") != NULL)
+#endif
     {
       name = gl_locale_name (LC_CTYPE, "LC_CTYPE");
+#ifdef __MINGW32__
+      ASSERT (strcmp (name, "de_DE") == 0);
+#else
       ASSERT (strcmp (name, "de_DE.UTF-8") == 0);
+#endif
       name = gl_locale_name (LC_MESSAGES, "LC_MESSAGES");
       ASSERT (strcmp (name, "fr_FR.UTF-8") == 0);
     }
@@ -224,7 +252,11 @@ static void
 test_locale_name_thread (void)
 {
   /* Get into a defined state,  */
+#ifdef __MINGW32__
+  setlocale (LC_ALL, "enu_USA.1252");
+#else
   setlocale (LC_ALL, "en_US.UTF-8");
+#endif
 
 #if HAVE_NEWLOCALE
   /* Check that gl_locale_name_thread returns NULL when no thread locale is
@@ -456,6 +488,9 @@ test_locale_name_thread (void)
             ASSERT (strcmp (unsaved_names[j][i], saved_names[j][i]) == 0);
         }
   }
+#elif defined __MINGW32__
+  ASSERT (strcmp (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE"), "en_US") == 0);
+  ASSERT (gl_locale_name_thread (LC_MESSAGES, "LC_MESSAGES") == NULL);
 #else
   /* Check that gl_locale_name_thread always returns NULL.  */
   ASSERT (gl_locale_name_thread (LC_CTYPE, "LC_CTYPE") == NULL);
--- tests/unicase/test-locale-language.c~0	2010-01-01 13:02:13 +0200
+++ tests/unicase/test-locale-language.c	2014-06-15 09:44:42 +0300
@@ -18,6 +18,8 @@
 
 #include <config.h>
 
+#include <stdlib.h>
+
 #include "unicase.h"
 
 #include <locale.h>
@@ -30,6 +32,28 @@ main (int argc, char *argv[])
 {
   const char *expected;
   const char *language;
+#ifdef __MINGW32__
+  char *lc_all = getenv ("LC_ALL");
+
+  /* Kludge alert: the below is fragile, and will break if
+     test-locale-language.sh is modified to use different locales.  */
+  if (lc_all)
+    {
+      if (strcmp (lc_all, "fr_FR") == 0)
+	lc_all = "fra_FRA";
+      else if (strncmp (lc_all, "fr_FR", 5) == 0)
+	lc_all = "fra_FRA.1252";
+      else if (strcmp (lc_all, "ja_JP") == 0)
+	lc_all = "jpn_JPN";
+      else if (strncmp (lc_all, "tr_TR", 5) == 0)
+	lc_all = "trk_TUR.1254";
+      else if (strncmp (lc_all, "zh_CN", 5) == 0)
+	lc_all = "chs_CHN.936";
+      if (setlocale (LC_ALL, lc_all) == NULL)
+	return 1;
+    }
+  else
+#endif
 
   /* configure should already have checked that the locale is supported.  */
   if (setlocale (LC_ALL, "") == NULL)
