Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit98171e5

Browse files
author
Amit Kapila
committed
Fix the MSVC build for versions 2015 and later.
Visual Studio 2015 and later versions should still be able to do the sameas Visual Studio 2012, but the declaration of locale_name is missing in_locale_t, causing the code compilation to fail, hence this falls backinstead on to enumerating all system locales by using EnumSystemLocalesExto find the required locale name.  If the input argument is in Unix-stylethen we can get ISO Locale name directly by using GetLocaleInfoEx() withLCType as LOCALE_SNAME.In passing, change the documentation references of the now obsolete links.Note that this problem occurs only with NLS enabled builds.Author: Juan José Santamaría Flecha, Davinder Singh and Amit KapilaReviewed-by: Ranier Vilela and Amit KapilaBackpatch-through: 9.5Discussion:https://postgr.es/m/CAHzhFSFoJEWezR96um4-rg5W6m2Rj9Ud2CNZvV4NWc9tXV7aXQ@mail.gmail.com
1 parent73a5c0d commit98171e5

File tree

1 file changed

+175
-8
lines changed

1 file changed

+175
-8
lines changed

‎src/backend/utils/adt/pg_locale.c

Lines changed: 175 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ pg_perm_setlocale(int category, const char *locale)
224224
result=IsoLocaleName(locale);
225225
if (result==NULL)
226226
result= (char*)locale;
227+
elog(DEBUG3,"IsoLocaleName() executed; locale: \"%s\"",result);
227228
#endif/* WIN32 */
228229
break;
229230
#endif/* LC_MESSAGES */
@@ -957,19 +958,181 @@ cache_locale_time(void)
957958
* string. Furthermore, msvcr110.dll changed the undocumented _locale_t
958959
* content to carry locale names instead of locale identifiers.
959960
*
960-
* MinGW headers declare _create_locale(), but msvcrt.dll lacks that symbol.
961-
* IsoLocaleName() always fails in a MinGW-built postgres.exe, so only
962-
* Unix-style values of the lc_messages GUC can elicit localized messages. In
963-
* particular, every lc_messages setting that initdb can select automatically
964-
* will yield only C-locale messages. XXX This could be fixed by running the
965-
* fully-qualified locale name through a lookup table.
961+
* Visual Studio 2015 should still be able to do the same as Visual Studio
962+
* 2012, but the declaration of locale_name is missing in _locale_t, causing
963+
* this code compilation to fail, hence this falls back instead on to
964+
* enumerating all system locales by using EnumSystemLocalesEx to find the
965+
* required locale name. If the input argument is in Unix-style then we can
966+
* get ISO Locale name directly by using GetLocaleInfoEx() with LCType as
967+
* LOCALE_SNAME.
968+
*
969+
* MinGW headers declare _create_locale(), but msvcrt.dll lacks that symbol in
970+
* releases before Windows 8. IsoLocaleName() always fails in a MinGW-built
971+
* postgres.exe, so only Unix-style values of the lc_messages GUC can elicit
972+
* localized messages. In particular, every lc_messages setting that initdb
973+
* can select automatically will yield only C-locale messages. XXX This could
974+
* be fixed by running the fully-qualified locale name through a lookup table.
966975
*
967976
* This function returns a pointer to a static buffer bearing the converted
968977
* name or NULL if conversion fails.
969978
*
970-
* [1] http://msdn.microsoft.com/en-us/library/windows/desktop/dd373763.aspx
971-
* [2] http://msdn.microsoft.com/en-us/library/windows/desktop/dd373814.aspx
979+
* [1] https://docs.microsoft.com/en-us/windows/win32/intl/locale-identifiers
980+
* [2] https://docs.microsoft.com/en-us/windows/win32/intl/locale-names
981+
*/
982+
983+
#if_MSC_VER >=1900
984+
/*
985+
* Callback function for EnumSystemLocalesEx() in get_iso_localename().
986+
*
987+
* This function enumerates all system locales, searching for one that matches
988+
* an input with the format: <Language>[_<Country>], e.g.
989+
* English[_United States]
990+
*
991+
* The input is a three wchar_t array as an LPARAM. The first element is the
992+
* locale_name we want to match, the second element is an allocated buffer
993+
* where the Unix-style locale is copied if a match is found, and the third
994+
* element is the search status, 1 if a match was found, 0 otherwise.
995+
*/
996+
staticBOOLCALLBACK
997+
search_locale_enum(LPWSTRpStr,DWORDdwFlags,LPARAMlparam)
998+
{
999+
wchar_ttest_locale[LOCALE_NAME_MAX_LENGTH];
1000+
wchar_t**argv;
1001+
1002+
(void) (dwFlags);
1003+
1004+
argv= (wchar_t**)lparam;
1005+
*argv[2]= (wchar_t)0;
1006+
1007+
memset(test_locale,0,sizeof(test_locale));
1008+
1009+
/* Get the name of the <Language> in English */
1010+
if (GetLocaleInfoEx(pStr,LOCALE_SENGLISHLANGUAGENAME,
1011+
test_locale,LOCALE_NAME_MAX_LENGTH))
1012+
{
1013+
/*
1014+
* If the enumerated locale does not have a hyphen ("en") OR the
1015+
* lc_message input does not have an underscore ("English"), we only
1016+
* need to compare the <Language> tags.
1017+
*/
1018+
if (wcsrchr(pStr,'-')==NULL||wcsrchr(argv[0],'_')==NULL)
1019+
{
1020+
if (_wcsicmp(argv[0],test_locale)==0)
1021+
{
1022+
wcscpy(argv[1],pStr);
1023+
*argv[2]= (wchar_t)1;
1024+
return FALSE;
1025+
}
1026+
}
1027+
1028+
/*
1029+
* We have to compare a full <Language>_<Country> tag, so we append
1030+
* the underscore and name of the country/region in English, e.g.
1031+
* "English_United States".
1032+
*/
1033+
else
1034+
{
1035+
size_tlen;
1036+
1037+
wcscat(test_locale,L"_");
1038+
len=wcslen(test_locale);
1039+
if (GetLocaleInfoEx(pStr,LOCALE_SENGLISHCOUNTRYNAME,
1040+
test_locale+len,
1041+
LOCALE_NAME_MAX_LENGTH-len))
1042+
{
1043+
if (_wcsicmp(argv[0],test_locale)==0)
1044+
{
1045+
wcscpy(argv[1],pStr);
1046+
*argv[2]= (wchar_t)1;
1047+
return FALSE;
1048+
}
1049+
}
1050+
}
1051+
}
1052+
1053+
return TRUE;
1054+
}
1055+
1056+
/*
1057+
* This function converts a Windows locale name to an ISO formatted version
1058+
* for Visual Studio 2015 or greater.
1059+
*
1060+
* Returns NULL, if no valid conversion was found.
9721061
*/
1062+
staticchar*
1063+
get_iso_localename(constchar*winlocname)
1064+
{
1065+
wchar_twc_locale_name[LOCALE_NAME_MAX_LENGTH];
1066+
wchar_tbuffer[LOCALE_NAME_MAX_LENGTH];
1067+
staticchariso_lc_messages[LOCALE_NAME_MAX_LENGTH];
1068+
char*period;
1069+
intlen;
1070+
intret_val;
1071+
1072+
/*
1073+
* Valid locales have the following syntax:
1074+
* <Language>[_<Country>[.<CodePage>]]
1075+
*
1076+
* GetLocaleInfoEx can only take locale name without code-page and for the
1077+
* purpose of this API the code-page doesn't matter.
1078+
*/
1079+
period=strchr(winlocname,'.');
1080+
if (period!=NULL)
1081+
len=period-winlocname;
1082+
else
1083+
len=pg_mbstrlen(winlocname);
1084+
1085+
memset(wc_locale_name,0,sizeof(wc_locale_name));
1086+
memset(buffer,0,sizeof(buffer));
1087+
MultiByteToWideChar(CP_ACP,0,winlocname,len,wc_locale_name,
1088+
LOCALE_NAME_MAX_LENGTH);
1089+
1090+
/*
1091+
* If the lc_messages is already an Unix-style string, we have a direct
1092+
* match with LOCALE_SNAME, e.g. en-US, en_US.
1093+
*/
1094+
ret_val=GetLocaleInfoEx(wc_locale_name,LOCALE_SNAME, (LPWSTR)&buffer,
1095+
LOCALE_NAME_MAX_LENGTH);
1096+
if (!ret_val)
1097+
{
1098+
/*
1099+
* Search for a locale in the system that matches language and country
1100+
* name.
1101+
*/
1102+
wchar_t*argv[3];
1103+
1104+
argv[0]=wc_locale_name;
1105+
argv[1]=buffer;
1106+
argv[2]= (wchar_t*)&ret_val;
1107+
EnumSystemLocalesEx(search_locale_enum,LOCALE_WINDOWS, (LPARAM)argv,
1108+
NULL);
1109+
}
1110+
1111+
if (ret_val)
1112+
{
1113+
size_trc;
1114+
char*hyphen;
1115+
1116+
/* Locale names use only ASCII, any conversion locale suffices. */
1117+
rc=wchar2char(iso_lc_messages,buffer,sizeof(iso_lc_messages),NULL);
1118+
if (rc==-1||rc==sizeof(iso_lc_messages))
1119+
returnNULL;
1120+
1121+
/*
1122+
* Simply replace the hyphen with an underscore. See comments in
1123+
* IsoLocaleName.
1124+
*/
1125+
hyphen=strchr(iso_lc_messages,'-');
1126+
if (hyphen)
1127+
*hyphen='_';
1128+
1129+
returniso_lc_messages;
1130+
}
1131+
1132+
returnNULL;
1133+
}
1134+
#endif/* _MSC_VER >= 1900 */
1135+
9731136
staticchar*
9741137
IsoLocaleName(constchar*winlocname)
9751138
{
@@ -984,6 +1147,9 @@ IsoLocaleName(const char *winlocname)
9841147
returniso_lc_messages;
9851148
}
9861149

1150+
#if (_MSC_VER >=1900)/* Visual Studio 2015 or later */
1151+
returnget_iso_localename(winlocname);
1152+
#else
9871153
loct=_create_locale(LC_CTYPE,winlocname);
9881154
if (loct!=NULL)
9891155
{
@@ -1033,6 +1199,7 @@ IsoLocaleName(const char *winlocname)
10331199
returniso_lc_messages;
10341200
}
10351201
returnNULL;
1202+
#endif/* Visual Studio 2015 or later */
10361203
#else
10371204
returnNULL;/* Not supported on this version of msvc/mingw */
10381205
#endif/* _MSC_VER >= 1400 */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp