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);
        }
}

Attachment: WindowsNLSLocales.ods
Description: application/vnd.oasis.opendocument.spreadsheet

Attachment: 0001-PG-compilation-error-with-VS-2015-2017-2019_v07.patch
Description: Binary data

Reply via email to