Module: wine Branch: master Commit: ba5cade700a0f1ad18b9c8b9824fd8ac91c7493b URL: http://source.winehq.org/git/wine.git/?a=commit;h=ba5cade700a0f1ad18b9c8b982...
Author: Christian Costa titan.costa@gmail.com Date: Wed Oct 31 09:56:39 2012 +0100
kernel32: Implement CompareStringOrdinal.
---
dlls/kernel32/kernel32.spec | 1 + dlls/kernel32/locale.c | 33 ++++++++++++++++++ dlls/kernel32/tests/locale.c | 76 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 109 insertions(+), 1 deletions(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index b7efa0f..0bd1adc 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -201,6 +201,7 @@ @ stdcall CompareStringA(long long str long str long) @ stdcall CompareStringW(long long wstr long wstr long) @ stdcall CompareStringEx(wstr long wstr long wstr long ptr ptr long) +@ stdcall CompareStringOrdinal(wstr long wstr long long) @ stdcall ConnectNamedPipe(long ptr) @ stub ConsoleMenuControl @ stub ConsoleSubst diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index c41442c..57daab1 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -3047,6 +3047,39 @@ INT WINAPI CompareStringA(LCID lcid, DWORD flags, return ret; }
+/****************************************************************************** + * CompareStringOrdinal (KERNEL32.@) + */ +INT WINAPI CompareStringOrdinal(const WCHAR *str1, INT len1, const WCHAR *str2, INT len2, BOOL ignore_case) +{ + int ret, len; + + if (!str1 || !str2) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + if (len1 < 0) len1 = strlenW(str1); + if (len2 < 0) len2 = strlenW(str2); + + len = min(len1, len2); + if (ignore_case) + { + ret = memicmpW(str1, str2, len); + } + else + { + ret = 0; + for (; len > 0; len--) + if ((ret = (*str1++ - *str2++))) break; + } + if (!ret) ret = len1 - len2; + + if (ret < 0) return CSTR_LESS_THAN; + if (ret > 0) return CSTR_GREATER_THAN; + return CSTR_EQUAL; +} + /************************************************************************* * lstrcmp (KERNEL32.@) * lstrcmpA (KERNEL32.@) diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index 0225c2b..197f562 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -87,6 +87,7 @@ static INT (WINAPI *pIdnToAscii)(DWORD, LPCWSTR, INT, LPWSTR, INT); static INT (WINAPI *pIdnToUnicode)(DWORD, LPCWSTR, INT, LPWSTR, INT); static INT (WINAPI *pGetLocaleInfoEx)(LPCWSTR, LCTYPE, LPWSTR, INT); static BOOL (WINAPI *pIsValidLocaleName)(LPCWSTR); +static INT (WINAPI *pCompareStringOrdinal)(const WCHAR *, INT, const WCHAR *, INT, BOOL);
static void InitFunctionPointers(void) { @@ -106,6 +107,7 @@ static void InitFunctionPointers(void) pIdnToUnicode = (void*)GetProcAddress(hKernel32, "IdnToUnicode"); pGetLocaleInfoEx = (void*)GetProcAddress(hKernel32, "GetLocaleInfoEx"); pIsValidLocaleName = (void*)GetProcAddress(hKernel32, "IsValidLocaleName"); + pCompareStringOrdinal = (void*)GetProcAddress(hKernel32, "CompareStringOrdinal"); }
#define eq(received, expected, label, type) \ @@ -3478,11 +3480,82 @@ static void test_IsValidLocaleName(void) ok(!ret, "IsValidLocaleName should have failed\n"); }
+void test_CompareStringOrdinal(void) +{ + INT ret; + WCHAR test1[] = { 't','e','s','t',0 }; + WCHAR test2[] = { 'T','e','S','t',0 }; + WCHAR test3[] = { 't','e','s','t','3',0 }; + WCHAR null1[] = { 'a',0,'a',0 }; + WCHAR null2[] = { 'a',0,'b',0 }; + WCHAR bills1[] = { 'b','i','l','l',''','s',0 }; + WCHAR bills2[] = { 'b','i','l','l','s',0 }; + WCHAR coop1[] = { 'c','o','-','o','p',0 }; + WCHAR coop2[] = { 'c','o','o','p',0 }; + WCHAR nonascii1[] = { 0x0102,0 }; + WCHAR nonascii2[] = { 0x0201,0 }; + + if (!pCompareStringOrdinal) + { + win_skip("CompareStringOrdinal not supported\n"); + return; + } + + /* Check errors */ + SetLastError(0xdeadbeef); + ret = pCompareStringOrdinal(NULL, 0, NULL, 0, FALSE); + ok(!ret, "Got %u, expected 0\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got %x, expected %x\n", GetLastError(), ERROR_INVALID_PARAMETER); + SetLastError(0xdeadbeef); + ret = pCompareStringOrdinal(test1, -1, NULL, 0, FALSE); + ok(!ret, "Got %u, expected 0\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got %x, expected %x\n", GetLastError(), ERROR_INVALID_PARAMETER); + SetLastError(0xdeadbeef); + ret = pCompareStringOrdinal(NULL, 0, test1, -1, FALSE); + ok(!ret, "Got %u, expected 0\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Got %x, expected %x\n", GetLastError(), ERROR_INVALID_PARAMETER); + + /* Check case */ + ret = pCompareStringOrdinal(test1, -1, test1, -1, FALSE); + ok(ret == CSTR_EQUAL, "Got %u, expected %u\n", ret, CSTR_EQUAL); + ret = pCompareStringOrdinal(test1, -1, test2, -1, FALSE); + ok(ret == CSTR_GREATER_THAN, "Got %u, expected %u\n", ret, CSTR_GREATER_THAN); + ret = pCompareStringOrdinal(test2, -1, test1, -1, FALSE); + ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN); + ret = pCompareStringOrdinal(test1, -1, test2, -1, TRUE); + ok(ret == CSTR_EQUAL, "Got %u, expected %u\n", ret, CSTR_EQUAL); + + /* Check different sizes */ + ret = pCompareStringOrdinal(test1, 3, test2, -1, TRUE); + ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN); + ret = pCompareStringOrdinal(test1, -1, test2, 3, TRUE); + ok(ret == CSTR_GREATER_THAN, "Got %u, expected %u\n", ret, CSTR_GREATER_THAN); + + /* Check null character */ + ret = pCompareStringOrdinal(null1, 3, null2, 3, FALSE); + ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN); + ret = pCompareStringOrdinal(null1, 3, null2, 3, TRUE); + ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN); + ret = pCompareStringOrdinal(test1, 5, test3, 5, FALSE); + ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN); + ret = pCompareStringOrdinal(test1, 4, test1, 5, FALSE); + ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN); + + /* Check ordinal behaviour */ + ret = pCompareStringOrdinal(bills1, -1, bills2, -1, FALSE); + ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN); + ret = pCompareStringOrdinal(coop2, -1, coop1, -1, FALSE); + ok(ret == CSTR_GREATER_THAN, "Got %u, expected %u\n", ret, CSTR_GREATER_THAN); + ret = pCompareStringOrdinal(nonascii1, -1, nonascii2, -1, FALSE); + ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN); + ret = pCompareStringOrdinal(nonascii1, -1, nonascii2, -1, TRUE); + ok(ret == CSTR_LESS_THAN, "Got %u, expected %u\n", ret, CSTR_LESS_THAN); +} + START_TEST(locale) { InitFunctionPointers();
- test_EnumTimeFormatsA(); test_EnumDateFormatsA(); test_GetLocaleInfoA(); @@ -3512,6 +3585,7 @@ START_TEST(locale) test_IdnToAscii(); test_IdnToUnicode(); test_IsValidLocaleName(); + test_CompareStringOrdinal(); /* this requires collation table patch to make it MS compatible */ if (0) test_sorting(); }