aboutsummaryrefslogtreecommitdiff
path: root/src/port/chklocale.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/port/chklocale.c')
-rw-r--r--src/port/chklocale.c61
1 files changed, 48 insertions, 13 deletions
diff --git a/src/port/chklocale.c b/src/port/chklocale.c
index 6d716c19110..7a3e3af74d1 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,16 @@ 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(). So, instead of the same logic as
+ * VS 2012 and VS 2013, this routine uses GetLocaleInfoEx to parse short
+ * locale names like "de-DE", "fr-FR", etc. If those cannot be parsed correctly
+ * process falls back to the pre-VS-2010 manual parsing done with
+ * using <Language>_<Country>.<CodePage> as a base.
+ *
* Returns a malloc()'d string for the caller to free.
*/
static char *
@@ -203,7 +217,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);
@@ -217,20 +231,41 @@ win32_langinfo(const char *ctype)
#else
char *codepage;
- /*
- * Locale format on Win32 is <Language>_<Country>.<CodePage> . For
- * example, English_United States.1252.
- */
- codepage = strrchr(ctype, '.');
- if (codepage != NULL)
- {
- int ln;
+#if (_MSC_VER >= 1900)
+ uint32 cp;
+ WCHAR wctype[LOCALE_NAME_MAX_LENGTH];
+
+ memset(wctype, 0, sizeof(wctype));
+ MultiByteToWideChar(CP_ACP, 0, ctype, -1, wctype, LOCALE_NAME_MAX_LENGTH);
- codepage++;
- ln = strlen(codepage);
- r = malloc(ln + 3);
+ if (GetLocaleInfoEx(wctype,
+ LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
+ (LPWSTR) &cp, sizeof(cp) / sizeof(WCHAR)) > 0)
+ {
+ r = malloc(16); /* excess */
if (r != NULL)
- sprintf(r, "CP%s", codepage);
+ sprintf(r, "CP%u", cp);
+ }
+ else
+#endif
+ {
+
+ /*
+ * Locale format on Win32 is <Language>_<Country>.<CodePage> . For
+ * example, English_United States.1252.
+ */
+ codepage = strrchr(ctype, '.');
+ if (codepage != NULL)
+ {
+ int ln;
+
+ codepage++;
+ ln = strlen(codepage);
+ r = malloc(ln + 3);
+ if (r != NULL)
+ sprintf(r, "CP%s", codepage);
+ }
+
}
#endif