On Sat, Apr 18, 2020 at 6:07 AM Amit Kapila <amit.kapil...@gmail.com> wrote:
> On Sat, Apr 18, 2020 at 12:14 AM Juan José Santamaría Flecha > <juanjo.santama...@gmail.com> 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 <ranier...@gmail.com> 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