From: Paul Gofman pgofman@codeweavers.com
--- dlls/msvcrt/locale.c | 39 ++++++++++++++++++++++++-------------- dlls/ucrtbase/tests/file.c | 19 +++++++++++++++++++ 2 files changed, 44 insertions(+), 14 deletions(-)
diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c index 6fc45b3bdbe..df1013aff95 100644 --- a/dlls/msvcrt/locale.c +++ b/dlls/msvcrt/locale.c @@ -1292,7 +1292,7 @@ static pthreadlocinfo create_locinfo(int category, char buf[256]; BOOL sname_match; wchar_t wbuf[256], map_buf[256]; - int i, ret; + int i, ret, count;
TRACE("(%d %s)\n", category, locale);
@@ -1491,8 +1491,10 @@ static pthreadlocinfo create_locinfo(int category, locinfo->ctype1[0] = 0; locinfo->pctype = locinfo->ctype1+1;
+ count = locinfo->lc_codepage == CP_UTF8 ? 128 : 256; + buf[1] = buf[2] = '\0'; - for(i=1; i<257; i++) { + for(i = 1; i < count + 1; i++) { buf[0] = i-1;
MultiByteToWideChar(locinfo->lc_codepage, 0, buf, 1, wbuf, 1); @@ -1500,27 +1502,36 @@ static pthreadlocinfo create_locinfo(int category, locinfo->ctype1[i] = 0; GetStringTypeW(CT_CTYPE1, wbuf, 1, &locinfo->ctype1[i]); } + if (locinfo->lc_codepage == CP_UTF8) + { + for (; i < 257; ++i) + locinfo->ctype1[i] = (i >= 0xc3 && i <= 0xf5) ? _LEADBYTE : 0; + } + else + { + for(i=0; cp_info.LeadByte[i+1]!=0; i+=2) + for(j=cp_info.LeadByte[i]; j<=cp_info.LeadByte[i+1]; j++) + locinfo->ctype1[j+1] |= _LEADBYTE; + }
- for(i=0; cp_info.LeadByte[i+1]!=0; i+=2) - for(j=cp_info.LeadByte[i]; j<=cp_info.LeadByte[i+1]; j++) - locinfo->ctype1[j+1] |= _LEADBYTE; - - for(i=0; i<256; i++) { + for(i = 0; i < count; i++) { if(locinfo->pctype[i] & _LEADBYTE) buf[i] = ' '; else buf[i] = i; }
- MultiByteToWideChar(locinfo->lc_codepage, 0, buf, 256, wbuf, 256); - LCMapStringW(LOCALE_INVARIANT, LCMAP_LOWERCASE, wbuf, 256, map_buf, 256); - if ((ret = WideCharToMultiByte(locinfo->lc_codepage, 0, map_buf, 256, - (char *)locinfo->pclmap, 256, NULL, NULL)) != 256) + MultiByteToWideChar(locinfo->lc_codepage, 0, buf, count, wbuf, count); + LCMapStringW(LOCALE_INVARIANT, LCMAP_LOWERCASE, wbuf, count, map_buf, count); + if ((ret = WideCharToMultiByte(locinfo->lc_codepage, 0, map_buf, count, + (char *)locinfo->pclmap, count, NULL, NULL)) != count) FIXME("WideCharToMultiByte failed, ret %d, error %lu.\n", ret, GetLastError()); - LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, wbuf, 256, map_buf, 256); - if ((ret = WideCharToMultiByte(locinfo->lc_codepage, 0, map_buf, 256, - (char *)locinfo->pcumap, 256, NULL, NULL)) != 256) + LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, wbuf, count, map_buf, count); + if ((ret = WideCharToMultiByte(locinfo->lc_codepage, 0, map_buf, count, + (char *)locinfo->pcumap, count, NULL, NULL)) != count) FIXME("WideCharToMultiByte failed, ret %d, error %lu.\n", ret, GetLastError()); + for (i = count; i < 256; ++i) + ((char *)locinfo->pclmap)[i] = ((char *)locinfo->pcumap)[i] = i; } else { locinfo->lc_clike = 1; locinfo->mb_cur_max = 1; diff --git a/dlls/ucrtbase/tests/file.c b/dlls/ucrtbase/tests/file.c index d5303a6020c..47971c76f95 100644 --- a/dlls/ucrtbase/tests/file.c +++ b/dlls/ucrtbase/tests/file.c @@ -232,6 +232,7 @@ static void test_utf8(const char *argv0) intptr_t hfind, hproc; WCHAR bufW[256], *pW; struct _stat64 stat; + unsigned int i; FILE *f; int ret;
@@ -241,6 +242,24 @@ static void test_utf8(const char *argv0) return; }
+ for (i = 128; i < 256; ++i) + { + unsigned int v; + + winetest_push_context("%#x", i); + v = tolower(i); + ok(i == v, "got %#x.\n", v); + v = toupper(i); + ok(i == v, "got %#x.\n", v); + + v = _isctype(i, ~0u); + if (i >= 0xc2 && i <= 0xf4) + ok(v == _LEADBYTE, "got %#x.\n", v); + else + ok(!v, "got %#x.\n", v); + winetest_pop_context(); + } + ret = _mkdir(dir); if (ret == -1 && errno == ENOENT) {