diff options
Diffstat (limited to 'src/port/chklocale.c')
-rw-r--r-- | src/port/chklocale.c | 61 |
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 |