diff options
author | Andrew Dunstan <andrew@dunslane.net> | 2013-02-06 14:52:29 -0500 |
---|---|---|
committer | Andrew Dunstan <andrew@dunslane.net> | 2013-02-06 14:52:29 -0500 |
commit | e1c1e2173248f39c1b15fca7b2a31ad7b5199ce7 (patch) | |
tree | db58fc5d34d7812a88b144ce4f573fe74406e402 /src/backend/utils/adt/pg_locale.c | |
parent | 5a1cd89f8f4a0bc13c85810de47d48bb6386ea89 (diff) | |
download | postgresql-e1c1e2173248f39c1b15fca7b2a31ad7b5199ce7.tar.gz postgresql-e1c1e2173248f39c1b15fca7b2a31ad7b5199ce7.zip |
Enable building with Microsoft Visual Studio 2012.
Backpatch to release 9.2
Brar Piening and Noah Misch, reviewed by Craig Ringer.
Diffstat (limited to 'src/backend/utils/adt/pg_locale.c')
-rw-r--r-- | src/backend/utils/adt/pg_locale.c | 68 |
1 files changed, 63 insertions, 5 deletions
diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 8fe824b426e..890aa198167 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -715,12 +715,41 @@ cache_locale_time(void) #if defined(WIN32) && defined(LC_MESSAGES) /* - * Convert Windows locale name to the ISO formatted one - * if possible. + * Convert a Windows setlocale() argument to a Unix-style one. * - * This function returns NULL if conversion is impossible, - * otherwise returns the pointer to a static area which - * contains the iso formatted locale name. + * Regardless of platform, we install message catalogs under a Unix-style + * LL[_CC][.ENCODING][@VARIANT] naming convention. Only LC_MESSAGES settings + * following that style will elicit localized interface strings. + * + * Before Visual Studio 2012 (msvcr110.dll), Windows setlocale() accepted "C" + * (but not "c") and strings of the form <Language>[_<Country>][.<CodePage>], + * case-insensitive. setlocale() returns the fully-qualified form; for + * example, setlocale("thaI") returns "Thai_Thailand.874". Internally, + * setlocale() and _create_locale() select a "locale identifier"[1] and store + * it in an undocumented _locale_t field. From that LCID, we can retrieve the + * ISO 639 language and the ISO 3166 country. Character encoding does not + * matter, because the server and client encodings govern that. + * + * Windows Vista introduced the "locale name" concept[2], closely following + * RFC 4646. Locale identifiers are now deprecated. Starting with Visual + * Studio 2012, setlocale() accepts locale names in addition to the strings it + * accepted historically. It does not standardize them; setlocale("Th-tH") + * returns "Th-tH". setlocale(category, "") still returns a traditional + * string. Furthermore, msvcr110.dll changed the undocumented _locale_t + * content to carry locale names instead of locale identifiers. + * + * MinGW headers declare _create_locale(), but msvcrt.dll lacks that symbol. + * IsoLocaleName() always fails in a MinGW-built postgres.exe, so only + * Unix-style values of the lc_messages GUC can elicit localized messages. In + * particular, every lc_messages setting that initdb can select automatically + * will yield only C-locale messages. XXX This could be fixed by running the + * fully-qualified locale name through a lookup table. + * + * This function returns a pointer to a static buffer bearing the converted + * name or NULL if conversion fails. + * + * [1] http://msdn.microsoft.com/en-us/library/windows/desktop/dd373763.aspx + * [2] http://msdn.microsoft.com/en-us/library/windows/desktop/dd373814.aspx */ static char * IsoLocaleName(const char *winlocname) @@ -739,6 +768,34 @@ IsoLocaleName(const char *winlocname) loct = _create_locale(LC_CTYPE, winlocname); if (loct != NULL) { +#if (_MSC_VER >= 1700) /* Visual Studio 2012 or later */ + 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); + _free_locale(loct); + 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 = '_'; +#else char isolang[32], isocrty[32]; LCID lcid; @@ -753,6 +810,7 @@ IsoLocaleName(const char *winlocname) if (!GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, isocrty, sizeof(isocrty))) return NULL; snprintf(iso_lc_messages, sizeof(iso_lc_messages) - 1, "%s_%s", isolang, isocrty); +#endif return iso_lc_messages; } return NULL; |