On Sat, Apr 18, 2020 at 6:07 AM Amit Kapila <[email protected]> wrote:
> On Sat, Apr 18, 2020 at 12:14 AM Juan José Santamaría Flecha > <[email protected]> wrote: > > > > We can get a match for those locales in non-ISO format by enumerating > available locales with EnumSystemLocalesEx(), and trying to find a match. > > I have not reviewed or tested the new patch but one thing I would like > to see is the impact of setting LC_MESAGGES with different locale > information. Basically, the error messages after setting the locale > with _create_locale and with the new method being discussed. This > will help us in ensuring that we didn't break anything which was > working with prior versions of MSVC. Can you or someone try to test > and share the results of the same? > I cannot find a single place where all supported locales are listed, but I have created a small test program (WindowsNLSLocales.c) based on: <language>[_<location>] format locales [1], additional supported language strings [2], and additional supported country and region strings [3]. Based on the results from this test program, it is possible to to do a good job with the <language>[_<location>] types using the proposed logic, but the two later cases are Windows specific, and there is no way arround a lookup-table. The attached results (WindowsNLSLocales.ods) come from Windows 10 (1903) and Visual C++ build 1924, 64-bit. On Sat, Apr 18, 2020 at 1:43 PM Ranier Vilela <[email protected]> wrote: > I have some observations about this patch, related to style, if you will > allow me. > Please find attached a revised version. [1] https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c [2] https://docs.microsoft.com/en-us/cpp/c-runtime-library/language-strings <https://docs.microsoft.com/en-us/cpp/c-runtime-library/language-strings?view=vs-2019> [3] https://docs.microsoft.com/en-us/cpp/c-runtime-library/country-region-strings <https://docs.microsoft.com/en-us/cpp/c-runtime-library/country-region-strings?view=vs-2019>
#include <windows.h>
#include <stdio.h>
#include <locale.h>
#if _MSC_VER >= 1800
/* From VS2012. */
typedef struct localerefcount
{
char* locale;
wchar_t* wlocale;
int* refcount;
int* wrefcount;
} locrefcount;
typedef struct __crt_locale_data
{
int refcount;
unsigned int lc_codepage;
unsigned int lc_collate_cp;
unsigned int lc_time_cp;
locrefcount lc_category[6];
int lc_clike;
int mb_cur_max;
int* lconv_intl_refcount;
int* lconv_num_refcount;
int* lconv_mon_refcount;
struct lconv* lconv;
int* ctype1_refcount;
unsigned short* ctype1;
const unsigned short* pctype;
const unsigned char* pclmap;
const unsigned char* pcumap;
struct __lc_time_data* lc_time_curr;
wchar_t* locale_name[6];
} threadlocinfo;
#endif
static const LPCWSTR AdditionalLocales[] =
{
/* Additional supported language strings */
L"american",
L"american english",
L"american-english",
L"australian",
L"belgian",
L"canadian",
L"chh",
L"chi",
L"chinese",
L"chinese-hongkong",
L"chinese-simplified",
L"chinese-singapore",
L"chinese-traditional",
L"dutch-belgian",
L"english-american",
L"english-aus",
L"english-belize",
L"english-can",
L"english-caribbean",
L"english-ire",
L"english-jamaica",
L"english-nz",
L"english-south africa",
L"english-trinidad y tobago",
L"english-uk",
L"english-us",
L"english-usa",
L"french-belgian",
L"french-canadian",
L"french-luxembourg",
L"french-swiss",
L"german-austrian",
L"german-lichtenstein",
L"german-luxembourg",
L"german-swiss",
L"irish-english",
L"italian-swiss",
L"norwegian",
L"norwegian-bokmal",
L"norwegian-nynorsk",
L"portuguese-brazilian",
L"spanish-argentina",
L"spanish-bolivia",
L"spanish-chile",
L"spanish-colombia",
L"spanish-costa rica",
L"spanish-dominican republic",
L"spanish-ecuador",
L"spanish-el salvador",
L"spanish-guatemala",
L"spanish-honduras",
L"spanish-mexican",
L"spanish-modern",
L"spanish-nicaragua",
L"spanish-panama",
L"spanish-paraguay",
L"spanish-peru",
L"spanish-puerto rico",
L"spanish-uruguay",
L"spanish-venezuela",
L"swedish-finland",
L"swiss",
L"uk",
L"us",
L"usa",
/* Additional supported country and region strings */
L"america",
L"britain",
L"china",
L"czech",
L"england",
L"great britain",
L"holland",
L"hong-kong",
L"new-zealand",
L"nz",
L"pr china",
L"pr-china",
L"puerto-rico",
L"slovak",
L"south africa",
L"south korea",
L"south-africa",
L"south-korea",
L"trinidad & tobago",
L"united-kingdom",
L"united-states",
L"GBR",
L"CHN",
L"CZE",
L"NLD",
L"HKG",
L"NZL",
L"PRI",
L"SVK",
L"ZAF",
L"KOR",
L"TTO"
};
/* Callback for EnumSystemLocalesEx() */
#define BUFFER_SIZE 512
BOOL CALLBACK FindLocale(LPWSTR pStr, DWORD dwFlags, LPARAM lparam)
{
wchar_t test_locale[BUFFER_SIZE];
(void)(dwFlags);
memset(test_locale, 0, sizeof(test_locale));
if (GetLocaleInfoEx(pStr, LOCALE_SENGLISHLANGUAGENAME,
test_locale, BUFFER_SIZE) > 0)
{
wchar_t* hyphen;
wchar_t* underscore;
wchar_t** argv;
argv = (wchar_t**)lparam;
hyphen = wcsrchr(pStr, '-');
underscore = wcsrchr(argv[0], '_');
if (hyphen == NULL || underscore == NULL)
{
if (_wcsicmp(argv[0], test_locale) == 0)
{
wcscpy(argv[1], pStr);
return FALSE;
}
}
else
{
size_t len;
wcscat(test_locale, L"_");
len = wcslen(test_locale);
if (GetLocaleInfoEx(pStr, LOCALE_SENGLISHCOUNTRYNAME,
test_locale + len, BUFFER_SIZE - len) > 0)
{
if (_wcsicmp(argv[0], test_locale) == 0)
{
wcscpy(argv[1], pStr);
return FALSE;
}
}
}
}
return TRUE;
}
/* Callback for EnumSystemLocalesEx() */
#define BUFFER_SIZE 512
BOOL CALLBACK GetLocale(LPWSTR pStr, DWORD dwFlags, LPARAM lparam)
{
wchar_t language[BUFFER_SIZE];
wchar_t country[BUFFER_SIZE];
wchar_t locale_name[BUFFER_SIZE];
wchar_t buffer[BUFFER_SIZE];
wchar_t* argv[2];
wchar_t* hyphen;
char locale[BUFFER_SIZE];
_locale_t loct;
size_t len;
(void)(dwFlags);
memset(language, 0, sizeof(language));
memset(country, 0, sizeof(country));
memset(locale_name, 0, sizeof(locale_name));
memset(buffer, 0, sizeof(buffer));
GetLocaleInfoEx(pStr, LOCALE_SENGLISHLANGUAGENAME, language,
BUFFER_SIZE);
GetLocaleInfoEx(pStr, LOCALE_SENGLISHCOUNTRYNAME, country, BUFFER_SIZE);
hyphen = wcsrchr(pStr, '-');
if (hyphen)
len = wcslen(hyphen);
else
len = 5;
if (len != 5)
swprintf(locale_name, BUFFER_SIZE, L"%s_%s", language, country);
else
wcscpy(locale_name, language);
argv[0] = locale_name;
argv[1] = buffer;
EnumSystemLocalesEx(FindLocale, LOCALE_ALL, (LPARAM) argv, NULL);
memset(locale, 0, sizeof(locale));
wcstombs(locale, locale_name, BUFFER_SIZE);
loct = _create_locale(LC_CTYPE, locale);
wprintf(L"%60s|%20s|", locale_name, buffer);
if (loct)
wprintf(L"%20s\n", loct->locinfo->locale_name[LC_CTYPE]);
else
wprintf(L"\n");
_free_locale(loct);
return TRUE;
}
int __cdecl wmain(void)
{
wchar_t buffer[BUFFER_SIZE];
wchar_t wc_locale_name[BUFFER_SIZE];
wchar_t* argv[2];
char locale_name[BUFFER_SIZE];
int i;
_locale_t loct;
EnumSystemLocalesEx(GetLocale, LOCALE_WINDOWS, (LPARAM)argv, NULL);
argv[0] = wc_locale_name;
argv[1] = buffer;
for (i = 0; i < sizeof(AdditionalLocales) /
sizeof(AdditionalLocales[0]); i++)
{
memset(buffer, 0, sizeof(buffer));
memset(wc_locale_name, 0, sizeof(wc_locale_name));
wcscpy(wc_locale_name, AdditionalLocales[i]);
EnumSystemLocalesEx(FindLocale, LOCALE_ALL, (LPARAM)argv, NULL);
wcstombs(locale_name, AdditionalLocales[i], BUFFER_SIZE);
loct = _create_locale(LC_CTYPE, locale_name);
wprintf(L"%60s|%20s|", wc_locale_name, buffer);
if (loct)
wprintf(L"%20s\n",
loct->locinfo->locale_name[LC_CTYPE]);
else
wprintf(L"\n");
_free_locale(loct);
}
}
WindowsNLSLocales.ods
Description: application/vnd.oasis.opendocument.spreadsheet
0001-PG-compilation-error-with-VS-2015-2017-2019_v07.patch
Description: Binary data
