From 6ea8dfac788be4f02e8c6162b6e2d9cd6bd0b4aa Mon Sep 17 00:00:00 2001 From: Davinder Singh Date: Mon, 6 Apr 2020 16:31:54 +0530 Subject: [PATCH] PG compilation error with VS 2015/2017/2019 This fix is to resolve undefined struct/union error while accessing locale_name. --- src/backend/utils/adt/pg_locale.c | 66 ++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 2562eb5416..c00a3c9181 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -990,6 +990,7 @@ IsoLocaleName(const char *winlocname) #ifdef _MSC_VER static char iso_lc_messages[32]; _locale_t loct = NULL; + size_t rc; if (pg_strcasecmp("c", winlocname) == 0 || pg_strcasecmp("posix", winlocname) == 0) @@ -997,38 +998,55 @@ IsoLocaleName(const char *winlocname) strcpy(iso_lc_messages, "C"); return iso_lc_messages; } - +#if defined(_MSC_VER) && (_MSC_VER < 1900) loct = _create_locale(LC_CTYPE, winlocname); if (loct != NULL) { - size_t rc; - char *hyphen; - /* Locale names use only ASCII, any conversion locale suffices. */ rc = wchar2char(iso_lc_messages, loct->locinfo->locale_name[LC_CTYPE], - sizeof(iso_lc_messages), NULL); + sizeof(iso_lc_messages), NULL); _free_locale(loct); - if (rc == -1 || rc == sizeof(iso_lc_messages)) - return NULL; + } + else + return NULL; +#endif /*_MSC_VER && _MSC_VER < 1900*/ +#if defined(_MSC_VER) && (_MSC_VER >= 1900) + WCHAR wc_locale_name[LOCALE_NAME_MAX_LENGTH]; + WCHAR buffer[LOCALE_NAME_MAX_LENGTH]; - /* - * Since the message catalogs sit on a case-insensitive filesystem, we - * need not standardize letter case here. So long as we do not ship - * message catalogs for which it would matter, we also need not - * translate the script/variant portion, e.g. uz-Cyrl-UZ to - * uz_UZ@cyrillic. Simply replace the hyphen with an underscore. - * - * Note that the locale name can be less-specific than the value we - * would derive under earlier Visual Studio releases. For example, - * French_France.1252 yields just "fr". This does not affect any of - * the country-specific message catalogs available as of this writing - * (pt_BR, zh_CN, zh_TW). - */ - hyphen = strchr(iso_lc_messages, '-'); - if (hyphen) - *hyphen = '_'; - return iso_lc_messages; + memset(wc_locale_name, 0, sizeof(wc_locale_name)); + memset(buffer, 0, sizeof(buffer)); + + MultiByteToWideChar(CP_ACP, 0, winlocname, -1, wc_locale_name, LOCALE_NAME_MAX_LENGTH); + + if ((GetLocaleInfoEx(wc_locale_name, LOCALE_SNAME, + (LPWSTR)&buffer, LOCALE_NAME_MAX_LENGTH)) > 0) { + rc = wchar2char(iso_lc_messages, buffer, sizeof(iso_lc_messages), NULL); } + else + return NULL; +#endif /* _MSC_VER && _MSC_VER >= 1900 */ + char* hyphen; + if (rc == -1 || rc == sizeof(iso_lc_messages)) + return NULL; + + /* + * Since the message catalogs sit on a case-insensitive filesystem, we + * need not standardize letter case here. So long as we do not ship + * message catalogs for which it would matter, we also need not + * translate the script/variant portion, e.g. uz-Cyrl-UZ to + * uz_UZ@cyrillic. Simply replace the hyphen with an underscore. + * + * Note that the locale name can be less-specific than the value we + * would derive under earlier Visual Studio releases. For example, + * French_France.1252 yields just "fr". This does not affect any of + * the country-specific message catalogs available as of this writing + * (pt_BR, zh_CN, zh_TW). + */ + hyphen = strchr(iso_lc_messages, '-'); + if (hyphen) + *hyphen = '_'; + return iso_lc_messages; #endif /* _MSC_VER */ return NULL; /* Not supported on this version of msvc/mingw */ } -- 2.24.0.windows.2