From f734cf3139e79ffcbbe0553ea291b58ec4fee967 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@otacoo.com>
Date: Fri, 8 Apr 2016 23:08:56 +0900
Subject: [PATCH 2/2] Fix code page calculation for Visual Studio 2015

Visual Studio 2015 is missing the declaration of field lc_codepage in
_locale_t, causing the existing code, introduced with VS 2012 to become
incompatible and causing compilation failures. This patch changes the
code path a bit so as GetLocaleInfoEx is used to fetch a code page
where available when compiling the code with VS2015, note that this
is compatible only with Windows 2k8/Vista and newer versions but it is
unlikely that a version of Postgres compiled with VS2015 would run on
platforms older than that, Windows XP being already out of support.

_WIN32_WINNT needs to be bumped so as the minimum version of Windows
supported when compiling the code with Visual Studio is Vista, which
should be fine knowing that XP is already out of support.
---
 src/include/port/win32.h | 11 +++++++++--
 src/port/chklocale.c     | 32 +++++++++++++++++++++++++++++++-
 2 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/src/include/port/win32.h b/src/include/port/win32.h
index 69cd1c4..d939206 100644
--- a/src/include/port/win32.h
+++ b/src/include/port/win32.h
@@ -6,14 +6,21 @@
 
 /*
  * Make sure _WIN32_WINNT has the minimum required value.
- * Leave a higher value in place.
-*/
+ * Leave a higher value in place. When building with at least Visual
+ * Studio 2015 the minimum requirement is Windows Vista (0x0600) to
+ * get support for GetLocaleInfoEx() with locales.
+ */
 #if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0501
 #undef _WIN32_WINNT
 #endif
 #ifndef _WIN32_WINNT
+#if defined (_MSC_VER >= 1900)
+#define _WIN32_WINNT 0x0600
+#else
 #define _WIN32_WINNT 0x0501
 #endif
+#endif /* _WIN32_WINNT */
+
 /*
  * Always build with SSPI support. Keep it as a #define in case
  * we want a switch to disable it sometime in the future.
diff --git a/src/port/chklocale.c b/src/port/chklocale.c
index a551fdc..4a7a265 100644
--- a/src/port/chklocale.c
+++ b/src/port/chklocale.c
@@ -19,6 +19,10 @@
 #include "postgres_fe.h"
 #endif
 
+#if defined(WIN32) && (_MSC_VER >= 1900)
+#include <windows.h>
+#endif
+
 #include <locale.h>
 #ifdef HAVE_LANGINFO_H
 #include <langinfo.h>
@@ -196,6 +200,12 @@ static const struct encoding_match encoding_match_list[] = {
  * locale machinery determine the code page.  See comments at IsoLocaleName().
  * For other compilers, follow the locale's predictable format.
  *
+ * Visual Studio 2015 should still be able to do the same, but the declaration
+ * of lc_codepage is missing in _locale_t, causing this code compilation to
+ * fail, hence this falls back instead on GetLocaleInfoEx. VS 2015 may be an
+ * exception and post-VS2015 versions should be able to handle properly the
+ * codepage number using _create_locale().
+ *
  * Returns a malloc()'d string for the caller to free.
  */
 static char *
@@ -203,7 +213,7 @@ win32_langinfo(const char *ctype)
 {
 	char	   *r = NULL;
 
-#if (_MSC_VER >= 1700)
+#if (_MSC_VER >= 1700) && (_MSC_VER < 1900)
 	_locale_t	loct = NULL;
 
 	loct = _create_locale(LC_CTYPE, ctype);
@@ -215,8 +225,24 @@ win32_langinfo(const char *ctype)
 		_free_locale(loct);
 	}
 #else
+
 	char	   *codepage;
 
+#if (_MSC_VER >= 1900)
+	uint32	cp;
+
+	if (GetLocaleInfoEx(ctype,
+			LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
+			(LPWSTR) &cp, sizeof(cp) / sizeof(WCHAR)) > 0)
+	{
+		r = malloc(16);			/* excess */
+		if (r != NULL)
+			sprintf(r, "CP%u", cp);
+	}
+	else
+	{
+#endif
+
 	/*
 	 * Locale format on Win32 is <Language>_<Country>.<CodePage> . For
 	 * example, English_United States.1252.
@@ -232,6 +258,10 @@ win32_langinfo(const char *ctype)
 		if (r != NULL)
 			sprintf(r, "CP%s", codepage);
 	}
+
+#if (_MSC_VER >= 1900)
+	}
+#endif
 #endif
 
 	return r;
-- 
2.8.1

