Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
33f9dcb1
Commit
33f9dcb1
authored
Nov 22, 2003
by
Dmitry Timoshkov
Committed by
Alexandre Julliard
Nov 22, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move CompareString implementation to libwine_unicode, add a bunch of
CompareString tests.
parent
1bcbd546
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
610 additions
and
68 deletions
+610
-68
locale.c
dlls/kernel/locale.c
+30
-16
locale.c
dlls/kernel/tests/locale.c
+317
-6
string.c
dlls/shlwapi/string.c
+2
-2
string.c
dlls/shlwapi/tests/string.c
+49
-31
unicode.h
include/wine/unicode.h
+1
-0
sortkey.c
libs/unicode/sortkey.c
+208
-11
string.c
libs/unicode/string.c
+2
-2
wine_unicode.def
libs/unicode/wine_unicode.def
+1
-0
No files found.
dlls/kernel/locale.c
View file @
33f9dcb1
...
...
@@ -1971,6 +1971,12 @@ INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen,
}
}
if
(
srclen
)
{
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
return
0
;
}
return
dst_ptr
-
dst
;
}
...
...
@@ -1994,7 +2000,7 @@ INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen,
INT
WINAPI
LCMapStringA
(
LCID
lcid
,
DWORD
flags
,
LPCSTR
src
,
INT
srclen
,
LPSTR
dst
,
INT
dstlen
)
{
WCHAR
bufW
[
128
]
;
WCHAR
*
bufW
=
NtCurrentTeb
()
->
StaticUnicodeBuffer
;
LPWSTR
srcW
,
dstW
;
INT
ret
=
0
,
srclenW
,
dstlenW
;
UINT
locale_cp
;
...
...
@@ -2007,7 +2013,7 @@ INT WINAPI LCMapStringA(LCID lcid, DWORD flags, LPCSTR src, INT srclen,
locale_cp
=
get_lcid_codepage
(
lcid
);
srclenW
=
MultiByteToWideChar
(
locale_cp
,
0
,
src
,
srclen
,
bufW
,
128
);
srclenW
=
MultiByteToWideChar
(
locale_cp
,
0
,
src
,
srclen
,
bufW
,
260
);
if
(
srclenW
)
srcW
=
bufW
;
else
...
...
@@ -2040,6 +2046,9 @@ INT WINAPI LCMapStringA(LCID lcid, DWORD flags, LPCSTR src, INT srclen,
}
dstlenW
=
LCMapStringW
(
lcid
,
flags
,
srcW
,
srclenW
,
NULL
,
0
);
if
(
!
dstlenW
)
goto
map_string_exit
;
dstW
=
HeapAlloc
(
GetProcessHeap
(),
0
,
dstlenW
*
sizeof
(
WCHAR
));
if
(
!
dstW
)
{
...
...
@@ -2172,7 +2181,7 @@ INT WINAPI FoldStringW(DWORD dwFlags, LPCWSTR src, INT srclen,
INT
WINAPI
CompareStringW
(
LCID
lcid
,
DWORD
style
,
LPCWSTR
str1
,
INT
len1
,
LPCWSTR
str2
,
INT
len2
)
{
INT
ret
,
len
;
INT
ret
;
if
(
!
str1
||
!
str2
)
{
...
...
@@ -2180,19 +2189,24 @@ INT WINAPI CompareStringW(LCID lcid, DWORD style,
return
0
;
}
if
(
len1
<
0
)
len1
=
lstrlenW
(
str1
);
if
(
len2
<
0
)
len2
=
lstrlenW
(
str2
);
if
(
style
&
~
(
NORM_IGNORECASE
|
NORM_IGNORENONSPACE
|
NORM_IGNORESYMBOLS
|
SORT_STRINGSORT
|
NORM_IGNOREKANATYPE
|
NORM_IGNOREWIDTH
|
0x10000000
)
)
{
SetLastError
(
ERROR_INVALID_FLAGS
);
return
0
;
}
len
=
(
len1
<
len2
)
?
len1
:
len2
;
ret
=
(
style
&
NORM_IGNORECASE
)
?
strncmpiW
(
str1
,
str2
,
len
)
:
strncmpW
(
str1
,
str2
,
len
);
if
(
style
&
0x10000000
)
FIXME
(
"Ignoring unknown style 0x10000000
\n
"
);
if
(
len1
<
0
)
len1
=
strlenW
(
str1
);
if
(
len2
<
0
)
len2
=
strlenW
(
str2
);
ret
=
wine_compare_string
(
style
,
str1
,
len1
,
str2
,
len2
);
if
(
ret
)
/* need to translate result */
return
(
ret
<
0
)
?
CSTR_LESS_THAN
:
CSTR_GREATER_THAN
;
if
(
len1
==
len2
)
return
CSTR_EQUAL
;
/* the longer one is lexically greater */
return
(
len1
<
len2
)
?
CSTR_LESS_THAN
:
CSTR_GREATER_THAN
;
return
CSTR_EQUAL
;
}
/******************************************************************************
...
...
@@ -2216,7 +2230,8 @@ INT WINAPI CompareStringW(LCID lcid, DWORD style,
INT
WINAPI
CompareStringA
(
LCID
lcid
,
DWORD
style
,
LPCSTR
str1
,
INT
len1
,
LPCSTR
str2
,
INT
len2
)
{
WCHAR
buf1W
[
128
],
buf2W
[
128
];
WCHAR
*
buf1W
=
NtCurrentTeb
()
->
StaticUnicodeBuffer
;
WCHAR
*
buf2W
=
buf1W
+
130
;
LPWSTR
str1W
,
str2W
;
INT
len1W
,
len2W
,
ret
;
UINT
locale_cp
;
...
...
@@ -2226,13 +2241,12 @@ INT WINAPI CompareStringA(LCID lcid, DWORD style,
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
if
(
len1
<
0
)
len1
=
strlen
(
str1
);
if
(
len2
<
0
)
len2
=
strlen
(
str2
);
locale_cp
=
get_lcid_codepage
(
lcid
);
len1W
=
MultiByteToWideChar
(
locale_cp
,
0
,
str1
,
len1
,
buf1W
,
1
28
);
len1W
=
MultiByteToWideChar
(
locale_cp
,
0
,
str1
,
len1
,
buf1W
,
1
30
);
if
(
len1W
)
str1W
=
buf1W
;
else
...
...
@@ -2246,7 +2260,7 @@ INT WINAPI CompareStringA(LCID lcid, DWORD style,
}
MultiByteToWideChar
(
locale_cp
,
0
,
str1
,
len1
,
str1W
,
len1W
);
}
len2W
=
MultiByteToWideChar
(
locale_cp
,
0
,
str2
,
len2
,
buf2W
,
1
28
);
len2W
=
MultiByteToWideChar
(
locale_cp
,
0
,
str2
,
len2
,
buf2W
,
1
30
);
if
(
len2W
)
str2W
=
buf2W
;
else
...
...
dlls/kernel/tests/locale.c
View file @
33f9dcb1
...
...
@@ -24,6 +24,9 @@
* even when the user has overridden their default i8n settings (e.g. in
* the control panel i8n page), we will still get the expected results.
*/
#include <assert.h>
#include <stdlib.h>
#include <stdarg.h>
#include "wine/test.h"
...
...
@@ -774,8 +777,151 @@ static void test_CompareStringA()
ret
=
CompareStringA
(
lcid
,
NORM_IGNORECASE
,
"haha"
,
-
1
,
"hoho"
,
0
);
ok
(
ret
==
3
,
"(haha/hoho) Expected 3, got %d
\n
"
,
ret
);
ret
=
CompareStringA
(
lcid
,
NORM_IGNORECASE
,
"Salut"
,
5
,
"SaLuT"
,
-
1
);
ok
(
ret
==
2
,
"(Salut/SaLuT) Expected 2, got %d
\n
"
,
ret
);
ret
=
CompareStringA
(
lcid
,
NORM_IGNORECASE
,
"Salut"
,
5
,
"saLuT"
,
-
1
);
ok
(
ret
==
2
,
"(Salut/saLuT) Expected 2, got %d
\n
"
,
ret
);
SetLastError
(
0xdeadbeef
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0x10
,
"NULL"
,
-
1
,
"NULL"
,
-
1
);
ok
(
GetLastError
()
==
ERROR_INVALID_FLAGS
,
"unexpected error code %ld
\n
"
,
GetLastError
());
ok
(
!
ret
,
"CompareStringA must fail with invalid flag
\n
"
);
ret
=
lstrcmpA
(
""
,
""
);
ok
(
!
ret
,
"lstrcmpA(
\"\"
,
\"\"
) should return 0, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"EndDialog"
,
-
1
,
"_Property"
,
-
1
);
ok
(
ret
==
3
,
"EndDialog vs _Property ... expected 3, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"osp_vba.sreg0070"
,
-
1
,
"_IEWWBrowserComp"
,
-
1
);
ok
(
ret
==
3
,
"osp_vba.sreg0070 vs _IEWWBrowserComp ... expected 3, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"r"
,
-
1
,
"
\\
"
,
-
1
);
ok
(
ret
==
3
,
"r vs
\\
... expected 3, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"osp_vba.sreg0031"
,
-
1
,
"OriginalDatabase"
,
-
1
);
ok
(
ret
==
3
,
"osp_vba.sreg0031 vs OriginalDatabase ... expected 3, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"AAA"
,
-
1
,
"aaa"
,
-
1
);
ok
(
ret
==
3
,
"AAA vs aaa expected 3, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"AAA"
,
-
1
,
"aab"
,
-
1
);
ok
(
ret
==
1
,
"AAA vs aab expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"AAA"
,
-
1
,
"Aab"
,
-
1
);
ok
(
ret
==
1
,
"AAA vs Aab expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
".AAA"
,
-
1
,
"Aab"
,
-
1
);
ok
(
ret
==
1
,
".AAA vs Aab expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
".AAA"
,
-
1
,
"A.ab"
,
-
1
);
ok
(
ret
==
1
,
".AAA vs A.ab expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"aa"
,
-
1
,
"AB"
,
-
1
);
ok
(
ret
==
1
,
"aa vs AB expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"aa"
,
-
1
,
"Aab"
,
-
1
);
ok
(
ret
==
1
,
"aa vs Aab expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"aB"
,
-
1
,
"Aab"
,
-
1
);
ok
(
ret
==
3
,
"aB vs Aab expected 3, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"Ba"
,
-
1
,
"bab"
,
-
1
);
ok
(
ret
==
1
,
"Ba vs bab expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"{100}{83}{71}{71}{71}"
,
-
1
,
"Global_DataAccess_JRO"
,
-
1
);
ok
(
ret
==
1
,
"{100}{83}{71}{71}{71} vs Global_DataAccess_JRO expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"a"
,
-
1
,
"{"
,
-
1
);
ok
(
ret
==
3
,
"a vs { expected 3, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"A"
,
-
1
,
"{"
,
-
1
);
ok
(
ret
==
3
,
"A vs { expected 3, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"3.5"
,
0
,
"4.0"
,
-
1
);
ok
(
ret
==
1
,
"3.5/0 vs 4.0/-1 expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"3.5"
,
-
1
,
"4.0"
,
-
1
);
ok
(
ret
==
1
,
"3.5 vs 4.0 expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"3.520.4403.2"
,
-
1
,
"4.0.2927.10"
,
-
1
);
ok
(
ret
==
1
,
"3.520.4403.2 vs 4.0.2927.10 expected 1, got %d"
,
ret
);
/* hyphen and apostrophe are treated differently depending on
* whether SORT_STRINGSORT specified or not
*/
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"-o"
,
-
1
,
"/m"
,
-
1
);
ok
(
ret
==
3
,
"-o vs /m expected 3, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"/m"
,
-
1
,
"-o"
,
-
1
);
ok
(
ret
==
1
,
"/m vs -o expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
SORT_STRINGSORT
,
"-o"
,
-
1
,
"/m"
,
-
1
);
ok
(
ret
==
1
,
"-o vs /m expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
SORT_STRINGSORT
,
"/m"
,
-
1
,
"-o"
,
-
1
);
ok
(
ret
==
3
,
"/m vs -o expected 3, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"'o"
,
-
1
,
"/m"
,
-
1
);
ok
(
ret
==
3
,
"'o vs /m expected 3, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
0
,
"/m"
,
-
1
,
"'o"
,
-
1
);
ok
(
ret
==
1
,
"/m vs 'o expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
SORT_STRINGSORT
,
"'o"
,
-
1
,
"/m"
,
-
1
);
ok
(
ret
==
1
,
"'o vs /m expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_SYSTEM_DEFAULT
,
SORT_STRINGSORT
,
"/m"
,
-
1
,
"'o"
,
-
1
);
ok
(
ret
==
3
,
"/m vs 'o expected 3, got %d"
,
ret
);
#if 0 /* this requires collation table patch to make it MS compatible */
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "'o", -1, "-o", -1 );
ok(ret == 1, "'o vs -o expected 1, got %d", ret);
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "'o", -1, "-o", -1 );
ok(ret == 1, "'o vs -o expected 1, got %d", ret);
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "'", -1, "-", -1 );
ok(ret == 1, "' vs - expected 1, got %d", ret);
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "'", -1, "-", -1 );
ok(ret == 1, "' vs - expected 1, got %d", ret);
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "`o", -1, "/m", -1 );
ok(ret == 3, "`o vs /m expected 3, got %d", ret);
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "/m", -1, "`o", -1 );
ok(ret == 1, "/m vs `o expected 1, got %d", ret);
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "`o", -1, "/m", -1 );
ok(ret == 3, "`o vs /m expected 3, got %d", ret);
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "/m", -1, "`o", -1 );
ok(ret == 1, "/m vs `o expected 1, got %d", ret);
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "`o", -1, "-m", -1 );
ok(ret == 1, "`o vs -m expected 1, got %d", ret);
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, "-m", -1, "`o", -1 );
ok(ret == 3, "-m vs `o expected 3, got %d", ret);
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "`o", -1, "-m", -1 );
ok(ret == 3, "`o vs -m expected 3, got %d", ret);
ret = CompareStringA(LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "-m", -1, "`o", -1 );
ok(ret == 1, "-m vs `o expected 1, got %d", ret);
#endif
ret
=
CompareStringA
(
LOCALE_USER_DEFAULT
,
0
,
"aLuZkUtZ"
,
8
,
"aLuZkUtZ"
,
9
);
ok
(
ret
==
2
,
"aLuZkUtZ vs aLuZkUtZ
\\
0 expected 2, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_USER_DEFAULT
,
0
,
"aLuZkUtZ"
,
7
,
"aLuZkUtZ
\0
A"
,
10
);
ok
(
ret
==
1
,
"aLuZkUtZ vs aLuZkUtZ
\\
0A expected 1, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_USER_DEFAULT
,
0
,
"aLuZkUtZ"
,
8
,
"aLuZkUtZ
\0
A"
,
10
);
ok
(
ret
==
2
,
"aLuZkUtZ vs aLuZkUtZ
\\
0A expected 2, got %d"
,
ret
);
ret
=
CompareStringA
(
LOCALE_USER_DEFAULT
,
0
,
"aLu
\0
ZkUtZ"
,
8
,
"aLu
\0
ZkUtZ
\0
A"
,
10
);
ok
(
ret
==
2
,
"aLu
\\
0ZkUtZ vs aLu
\\
0ZkUtZ
\\
0A expected 2, got %d"
,
ret
);
}
void
test_LCMapStringA
(
void
)
...
...
@@ -834,6 +980,13 @@ void test_LCMapStringA(void)
ret
,
GetLastError
(),
lstrlenA
(
lower_case
)
+
1
);
ok
(
!
lstrcmpA
(
buf
,
upper_case
),
"LCMapStringA should return %s, but not %s
\n
"
,
upper_case
,
buf
);
/* test buffer overflow */
SetLastError
(
0xdeadbeef
);
ret
=
LCMapStringA
(
LOCALE_USER_DEFAULT
,
LCMAP_UPPERCASE
,
lower_case
,
-
1
,
buf
,
4
);
ok
(
!
ret
&&
GetLastError
()
==
ERROR_INSUFFICIENT_BUFFER
,
"should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d
\n
"
,
ret
);
/* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
lstrcpyA
(
buf
,
lower_case
);
ret
=
LCMapStringA
(
LOCALE_USER_DEFAULT
,
LCMAP_UPPERCASE
,
...
...
@@ -924,6 +1077,13 @@ void test_LCMapStringA(void)
ok
(
ret
==
lstrlenA
(
symbols_stripped
)
+
1
,
"LCMapStringA should return %d, ret = %d
\n
"
,
lstrlenA
(
symbols_stripped
)
+
1
,
ret
);
ok
(
!
lstrcmpA
(
buf
,
symbols_stripped
),
"LCMapStringA should return %s, but not %s
\n
"
,
lower_case
,
buf
);
/* test srclen = 0 */
SetLastError
(
0xdeadbeef
);
ret
=
LCMapStringA
(
LOCALE_USER_DEFAULT
,
0
,
upper_case
,
0
,
buf
,
sizeof
(
buf
));
ok
(
!
ret
,
"LCMapStringA should fail with srclen = 0"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"unexpected error code %ld
\n
"
,
GetLastError
());
}
void
test_LCMapStringW
(
void
)
...
...
@@ -988,6 +1148,13 @@ void test_LCMapStringW(void)
ret
,
GetLastError
(),
lstrlenW
(
lower_case
)
+
1
);
ok
(
!
lstrcmpW
(
buf
,
upper_case
),
"string compare mismatch
\n
"
);
/* test buffer overflow */
SetLastError
(
0xdeadbeef
);
ret
=
LCMapStringW
(
LOCALE_USER_DEFAULT
,
LCMAP_UPPERCASE
,
lower_case
,
-
1
,
buf
,
4
);
ok
(
!
ret
&&
GetLastError
()
==
ERROR_INSUFFICIENT_BUFFER
,
"should return 0 and ERROR_INSUFFICIENT_BUFFER, got %d
\n
"
,
ret
);
/* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
lstrcpyW
(
buf
,
lower_case
);
ret
=
LCMapStringW
(
LOCALE_USER_DEFAULT
,
LCMAP_UPPERCASE
,
...
...
@@ -1069,9 +1236,143 @@ void test_LCMapStringW(void)
ok
(
ret
==
lstrlenW
(
symbols_stripped
)
+
1
,
"LCMapStringW should return %d, ret = %d
\n
"
,
lstrlenW
(
symbols_stripped
)
+
1
,
ret
);
ok
(
!
lstrcmpW
(
buf
,
symbols_stripped
),
"string comparison mismatch
\n
"
);
/* test srclen = 0 */
SetLastError
(
0xdeadbeef
);
ret
=
LCMapStringW
(
LOCALE_USER_DEFAULT
,
0
,
upper_case
,
0
,
buf
,
sizeof
(
buf
));
ok
(
!
ret
,
"LCMapStringW should fail with srclen = 0"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"unexpected error code %ld
\n
"
,
GetLastError
());
}
#if 0 /* this requires collation table patch to make it MS compatible */
const char *strings_sorted[] =
{
"'",
"-",
"!",
"\"",
".",
":",
"\\",
"_",
"`",
"{",
"}",
"+",
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"a",
"A",
"b",
"B",
"c",
"C"
};
const char *strings[] =
{
"C",
"\"",
"9",
"'",
"}",
"-",
"7",
"+",
"`",
"1",
"a",
"5",
"\\",
"8",
"B",
"3",
"_",
"6",
"{",
"2",
"c",
"4",
"!",
"0",
"A",
":",
"b",
"."
};
static int compare_string1(const void *e1, const void *e2)
{
const char *s1 = *(const char **)e1;
const char *s2 = *(const char **)e2;
return lstrcmpA(s1, s2);
}
static int compare_string2(const void *e1, const void *e2)
{
const char *s1 = *(const char **)e1;
const char *s2 = *(const char **)e2;
return CompareStringA(0, 0, s1, -1, s2, -1) - 2;
}
static int compare_string3(const void *e1, const void *e2)
{
const char *s1 = *(const char **)e1;
const char *s2 = *(const char **)e2;
char key1[256], key2[256];
LCMapStringA(0, LCMAP_SORTKEY, s1, -1, key1, sizeof(key1));
LCMapStringA(0, LCMAP_SORTKEY, s2, -1, key2, sizeof(key2));
return strcmp(key1, key2);
}
void
test_FoldStringA
(
void
)
static void test_sorting(void)
{
char buf[256];
char **str_buf = (char **)buf;
int i;
assert(sizeof(buf) >= sizeof(strings));
/* 1. sort using lstrcmpA */
memcpy(buf, strings, sizeof(strings));
qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string1);
for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
{
ok(!strcmp(strings_sorted[i], str_buf[i]),
"qsort using lstrcmpA failed for element %d\n", i);
}
/* 2. sort using CompareStringA */
memcpy(buf, strings, sizeof(strings));
qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string2);
for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
{
ok(!strcmp(strings_sorted[i], str_buf[i]),
"qsort using CompareStringA failed for element %d\n", i);
}
/* 3. sort using sort keys */
memcpy(buf, strings, sizeof(strings));
qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string3);
for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
{
ok(!strcmp(strings_sorted[i], str_buf[i]),
"qsort using sort keys failed for element %d\n", i);
}
}
#endif
static
void
test_FoldStringA
(
void
)
{
int
ret
,
i
;
char
src
[
256
],
dst
[
256
];
...
...
@@ -1118,6 +1419,13 @@ void test_FoldStringA(void)
if
(
!
pFoldStringA
)
return
;
/* FoldString is present in NT v3.1+, but not 95/98/Me */
/* these tests are locale specific */
if
(
GetACP
()
!=
1252
)
{
trace
(
"Skipping FoldStringA tests for a not Latin 1 locale
\n
"
);
return
;
}
/* MAP_FOLDDIGITS */
SetLastError
(
0
);
ret
=
pFoldStringA
(
MAP_FOLDDIGITS
,
digits_src
,
-
1
,
dst
,
256
);
...
...
@@ -1212,7 +1520,7 @@ void test_FoldStringA(void)
}
}
void
test_FoldStringW
(
void
)
static
void
test_FoldStringW
(
void
)
{
int
ret
;
size_t
i
,
j
;
...
...
@@ -1596,8 +1904,8 @@ static BOOL CALLBACK langgrp_procA(LGRPID lgrpid, LPSTR lpszNum, LPSTR lpszName,
"Enumerated grp %ld not valid (flags %ld)
\n
"
,
lgrpid
,
dwFlags
);
/* If lParam is one, we are calling with flags defaulted from 0 */
ok
(
!
lParam
||
dwFlags
==
LGRPID_INSTALLED
,
"Expected dwFlags == LGRPID_INSTALLED, got %ld
\n
"
,
dwFlags
);
ok
(
!
lParam
||
(
dwFlags
==
LGRPID_INSTALLED
||
dwFlags
==
LGRPID_SUPPORTED
)
,
"Expected dwFlags == LGRPID_INSTALLED
|| dwFlags == LGRPID_SUPPORTED
, got %ld
\n
"
,
dwFlags
);
return
TRUE
;
}
...
...
@@ -1710,4 +2018,7 @@ START_TEST(locale)
test_EnumSystemLanguageGroupsA
();
test_EnumLanguageGroupLocalesA
();
test_SetLocaleInfoA
();
#if 0 /* this requires collation table patch to make it MS compatible */
test_sorting();
#endif
}
dlls/shlwapi/string.c
View file @
33f9dcb1
...
...
@@ -64,7 +64,7 @@ static BOOL WINAPI SHLWAPI_ChrCmpHelperA(WORD ch1, WORD ch2, DWORD dwFlags)
char
str1
[
3
],
str2
[
3
];
str1
[
0
]
=
LOBYTE
(
ch1
);
if
(
IsDBCSLeadByte
(
ch1
))
if
(
IsDBCSLeadByte
(
str1
[
0
]
))
{
str1
[
1
]
=
HIBYTE
(
ch1
);
str1
[
2
]
=
'\0'
;
...
...
@@ -73,7 +73,7 @@ static BOOL WINAPI SHLWAPI_ChrCmpHelperA(WORD ch1, WORD ch2, DWORD dwFlags)
str1
[
1
]
=
'\0'
;
str2
[
0
]
=
LOBYTE
(
ch2
);
if
(
IsDBCSLeadByte
(
ch2
))
if
(
IsDBCSLeadByte
(
str2
[
0
]
))
{
str2
[
1
]
=
HIBYTE
(
ch2
);
str2
[
2
]
=
'\0'
;
...
...
dlls/shlwapi/tests/string.c
View file @
33f9dcb1
...
...
@@ -156,33 +156,37 @@ static const StrFromTimeIntervalResult StrFromTimeInterval_results[] = {
static
void
test_StrChrA
(
void
)
{
char
string
[
129
];
int
count
;
WORD
count
;
ok
(
!
StrChrA
(
NULL
,
'\0'
),
"found a character in a NULL string!"
);
/* this test crashes on win2k SP4 */
/*ok(!StrChrA(NULL,'\0'), "found a character in a NULL string!");*/
for
(
count
=
32
;
count
<
128
;
count
++
)
string
[
count
]
=
count
;
string
[
count
]
=
(
char
)
count
;
string
[
128
]
=
'\0'
;
for
(
count
=
32
;
count
<
128
;
count
++
)
{
LPSTR
result
=
StrChrA
(
string
+
32
,
count
);
ok
(
result
-
string
==
count
,
"found char %d in wrong place"
,
count
);
ok
(
result
-
string
==
count
,
"found char '%c' in wrong place: got %d, expected %d
\n
"
,
count
,
result
-
string
,
count
);
}
for
(
count
=
32
;
count
<
128
;
count
++
)
{
LPSTR
result
=
StrChrA
(
string
+
count
+
1
,
count
);
ok
(
!
result
,
"found char
not in the string"
);
ok
(
!
result
,
"found char
'%c' not in the string
\n
"
,
count
);
}
}
static
void
test_StrChrW
(
void
)
{
WCHAR
string
[
16385
];
int
count
;
WORD
count
;
ok
(
!
StrChrW
(
NULL
,
'\0'
),
"found a character in a NULL string!"
);
/* this test crashes on win2k SP4 */
/*ok(!StrChrW(NULL,'\0'), "found a character in a NULL string!");*/
for
(
count
=
32
;
count
<
16384
;
count
++
)
string
[
count
]
=
count
;
...
...
@@ -204,12 +208,13 @@ static void test_StrChrW(void)
static
void
test_StrChrIA
(
void
)
{
char
string
[
129
];
int
count
;
WORD
count
;
ok
(
!
StrChrIA
(
NULL
,
'\0'
),
"found a character in a NULL string!"
);
/* this test crashes on win2k SP4 */
/*ok(!StrChrIA(NULL,'\0'), "found a character in a NULL string!");*/
for
(
count
=
32
;
count
<
128
;
count
++
)
string
[
count
]
=
count
;
string
[
count
]
=
(
char
)
count
;
string
[
128
]
=
'\0'
;
for
(
count
=
'A'
;
count
<=
'X'
;
count
++
)
...
...
@@ -230,9 +235,10 @@ static void test_StrChrIA(void)
static
void
test_StrChrIW
(
void
)
{
WCHAR
string
[
129
];
int
count
;
WORD
count
;
ok
(
!
StrChrIA
(
NULL
,
'\0'
),
"found a character in a NULL string!"
);
/* this test crashes on win2k SP4 */
/*ok(!StrChrIA(NULL,'\0'), "found a character in a NULL string!");*/
for
(
count
=
32
;
count
<
128
;
count
++
)
string
[
count
]
=
count
;
...
...
@@ -256,12 +262,13 @@ static void test_StrChrIW(void)
static
void
test_StrRChrA
(
void
)
{
char
string
[
129
];
int
count
;
WORD
count
;
ok
(
!
StrRChrA
(
NULL
,
NULL
,
'\0'
),
"found a character in a NULL string!"
);
/* this test crashes on win2k SP4 */
/*ok(!StrRChrA(NULL, NULL,'\0'), "found a character in a NULL string!");*/
for
(
count
=
32
;
count
<
128
;
count
++
)
string
[
count
]
=
count
;
string
[
count
]
=
(
char
)
count
;
string
[
128
]
=
'\0'
;
for
(
count
=
32
;
count
<
128
;
count
++
)
...
...
@@ -285,31 +292,34 @@ static void test_StrRChrA(void)
static
void
test_StrRChrW
(
void
)
{
WCHAR
string
[
1
6385
];
int
count
;
WCHAR
string
[
1
29
];
WORD
count
;
ok
(
!
StrRChrW
(
NULL
,
NULL
,
'\0'
),
"found a character in a NULL string!"
);
/* this test crashes on win2k SP4 */
/*ok(!StrRChrW(NULL, NULL,'\0'), "found a character in a NULL string!");*/
for
(
count
=
32
;
count
<
1
6384
;
count
++
)
for
(
count
=
32
;
count
<
1
28
;
count
++
)
string
[
count
]
=
count
;
string
[
1
6384
]
=
'\0'
;
string
[
1
28
]
=
'\0'
;
for
(
count
=
32
;
count
<
1
6384
;
count
++
)
for
(
count
=
32
;
count
<
1
28
;
count
++
)
{
LPWSTR
result
=
StrRChrW
(
string
+
32
,
NULL
,
count
);
ok
(
result
-
string
==
count
,
"found char %d in wrong place"
,
count
);
ok
(
result
-
string
==
count
,
"found char %d in wrong place: got %d, expected %d
\n
"
,
count
,
result
-
string
,
count
);
}
for
(
count
=
32
;
count
<
1
6384
;
count
++
)
for
(
count
=
32
;
count
<
1
28
;
count
++
)
{
LPWSTR
result
=
StrRChrW
(
string
+
count
+
1
,
NULL
,
count
);
ok
(
!
result
,
"found char
not in the string"
);
ok
(
!
result
,
"found char
%d not in the string
\n
"
,
count
);
}
for
(
count
=
32
;
count
<
1
6384
;
count
++
)
for
(
count
=
32
;
count
<
1
28
;
count
++
)
{
LPWSTR
result
=
StrRChrW
(
string
+
count
+
1
,
string
+
127
,
count
);
ok
(
!
result
,
"found char
not in the string"
);
ok
(
!
result
,
"found char
%d not in the string
\n
"
,
count
);
}
}
...
...
@@ -455,6 +465,8 @@ static void test_StrDupA()
static
void
test_StrFormatByteSize64A
(
void
)
{
/* this test fails on locales which do not use '.' as a decimal separator */
#if 0
char szBuff[256];
const StrFormatSizeResult* result = StrFormatSize_results;
...
...
@@ -462,10 +474,13 @@ static void test_StrFormatByteSize64A(void)
{
StrFormatByteSize64A(result->value, szBuff, 256);
ok
(
!
strcmp
(
result
->
byte_size_64
,
szBuff
),
"Formatted %lld wrong"
,
result
->
value
);
ok(!strcmp(result->byte_size_64, szBuff),
"Formatted %lx%08lx wrong: got %s, expected %s\n",
(LONG)(result->value >> 32), (LONG)result->value, szBuff, result->byte_size_64);
result++;
}
#endif
}
static
void
test_StrFormatKBSizeW
(
void
)
...
...
@@ -480,8 +495,9 @@ static void test_StrFormatKBSizeW(void)
{
StrFormatKBSizeW(result->value, szBuffW, 256);
WideCharToMultiByte(0,0,szBuffW,-1,szBuff,sizeof(szBuff)/sizeof(WCHAR),0,0);
ok(!strcmp(result->kb_size, szBuff), "Formatted %lld wrong",
result->value);
ok(!strcmp(result->kb_size, szBuff),
"Formatted %lx%08lx wrong: got %s, expected %s\n",
(LONG)(result->value >> 32), (LONG)result->value, szBuff, result->kb_size);
result++;
}
#endif
...
...
@@ -489,6 +505,7 @@ static void test_StrFormatKBSizeW(void)
static
void
test_StrFormatKBSizeA
(
void
)
{
/* this test fails on locales which do not use '.' as a decimal separator */
#if 0
char szBuff[256];
const StrFormatSizeResult* result = StrFormatSize_results;
...
...
@@ -497,8 +514,9 @@ static void test_StrFormatKBSizeA(void)
{
StrFormatKBSizeA(result->value, szBuff, 256);
ok(!strcmp(result->kb_size, szBuff), "Formatted %lld wrong",
result->value);
ok(!strcmp(result->kb_size, szBuff),
"Formatted %lx%08lx wrong: got %s, expected %s\n",
(LONG)(result->value >> 32), (LONG)result->value, szBuff, result->kb_size);
result++;
}
#endif
...
...
include/wine/unicode.h
View file @
33f9dcb1
...
...
@@ -74,6 +74,7 @@ extern int wine_cp_wcstombs( const union cptable *table, int flags,
extern
int
wine_utf8_wcstombs
(
const
WCHAR
*
src
,
int
srclen
,
char
*
dst
,
int
dstlen
);
extern
int
wine_utf8_mbstowcs
(
int
flags
,
const
char
*
src
,
int
srclen
,
WCHAR
*
dst
,
int
dstlen
);
extern
int
wine_compare_string
(
int
flags
,
const
WCHAR
*
str1
,
int
len1
,
const
WCHAR
*
str2
,
int
len2
);
extern
int
wine_get_sortkey
(
int
flags
,
const
WCHAR
*
src
,
int
srclen
,
char
*
dst
,
int
dstlen
);
extern
int
wine_fold_string
(
int
flags
,
const
WCHAR
*
src
,
int
srclen
,
WCHAR
*
dst
,
int
dstlen
);
...
...
libs/unicode/sortkey.c
View file @
33f9dcb1
...
...
@@ -20,6 +20,7 @@
#include "wine/unicode.h"
extern
int
get_decomposition
(
WCHAR
src
,
WCHAR
*
dst
,
unsigned
int
dstlen
);
extern
const
unsigned
int
collation_table
[];
/*
* flags - normalization NORM_* flags
...
...
@@ -28,7 +29,6 @@ extern int get_decomposition(WCHAR src, WCHAR *dst, unsigned int dstlen);
*/
int
wine_get_sortkey
(
int
flags
,
const
WCHAR
*
src
,
int
srclen
,
char
*
dst
,
int
dstlen
)
{
extern
const
unsigned
int
collation_table
[];
WCHAR
dummy
[
4
];
/* no decomposition is larger than 4 chars */
int
key_len
[
4
];
char
*
key_ptr
[
4
];
...
...
@@ -38,7 +38,8 @@ int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dst
key_len
[
0
]
=
key_len
[
1
]
=
key_len
[
2
]
=
key_len
[
3
]
=
0
;
for
(;
srclen
;
srclen
--
,
src
++
)
{
int
decomposed_len
=
get_decomposition
(
*
src
,
dummy
,
4
);
int
decomposed_len
=
1
;
/*get_decomposition(*src, dummy, 4);*/
dummy
[
0
]
=
*
src
;
if
(
decomposed_len
)
{
int
i
;
...
...
@@ -62,18 +63,18 @@ int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dst
if
(
ce
>>
16
)
key_len
[
0
]
+=
2
;
if
((
ce
>>
8
)
&
0xff
)
key_len
[
1
]
++
;
if
((
ce
>>
4
)
&
0x0f
)
key_len
[
2
]
++
;
/*
if (ce & 1)
if
(
ce
&
1
)
{
if
(
wch
>>
8
)
key_len
[
3
]
++
;
key_len
[
3
]
++
;
}
*/
}
}
/*
else
else
{
key_len
[
0
]
+=
2
;
if
(
wch
>>
8
)
key_len
[
0
]
++
;
if
(
wch
&
0xff
)
key_len
[
0
]
++
;
}
*/
}
}
}
}
...
...
@@ -95,7 +96,8 @@ int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dst
for
(;
srclen
;
srclen
--
,
src
++
)
{
int
decomposed_len
=
get_decomposition
(
*
src
,
dummy
,
4
);
int
decomposed_len
=
1
;
/*get_decomposition(*src, dummy, 4);*/
dummy
[
0
]
=
*
src
;
if
(
decomposed_len
)
{
int
i
;
...
...
@@ -127,19 +129,19 @@ int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dst
/* make key 2 start from 2 */
if
((
key
=
(
ce
>>
4
)
&
0x0f
))
*
key_ptr
[
2
]
++
=
key
+
1
;
/* key 3 is always a character code */
/*
if (ce & 1)
if
(
ce
&
1
)
{
if
(
wch
>>
8
)
*
key_ptr
[
3
]
++
=
wch
>>
8
;
if
(
wch
&
0xff
)
*
key_ptr
[
3
]
++
=
wch
&
0xff
;
}
*/
}
}
/*
else
else
{
*
key_ptr
[
0
]
++
=
0xff
;
*
key_ptr
[
0
]
++
=
0xfe
;
if
(
wch
>>
8
)
*
key_ptr
[
0
]
++
=
wch
>>
8
;
if
(
wch
&
0xff
)
*
key_ptr
[
0
]
++
=
wch
&
0xff
;
}
*/
}
}
}
}
...
...
@@ -152,3 +154,198 @@ int wine_get_sortkey(int flags, const WCHAR *src, int srclen, char *dst, int dst
return
key_ptr
[
3
]
-
dst
;
}
static
inline
int
compare_unicode_weights
(
int
flags
,
const
WCHAR
*
str1
,
int
len1
,
const
WCHAR
*
str2
,
int
len2
)
{
unsigned
int
ce1
,
ce2
;
int
ret
;
/* 32-bit collation element table format:
* unicode weight - high 16 bit, diacritic weight - high 8 bit of low 16 bit,
* case weight - high 4 bit of low 8 bit.
*/
while
(
len1
>
0
&&
len2
>
0
)
{
if
(
flags
&
NORM_IGNORESYMBOLS
)
{
int
skip
=
0
;
/* FIXME: not tested */
if
(
get_char_typeW
(
*
str1
)
&
(
C1_PUNCT
|
C1_SPACE
))
{
str1
++
;
len1
--
;
skip
=
1
;
}
if
(
get_char_typeW
(
*
str2
)
&
(
C1_PUNCT
|
C1_SPACE
))
{
str2
++
;
len2
--
;
skip
=
1
;
}
if
(
skip
)
continue
;
}
/* hyphen and apostrophe are treated differently depending on
* whether SORT_STRINGSORT specified or not
*/
if
(
!
(
flags
&
SORT_STRINGSORT
))
{
if
(
*
str1
==
'-'
||
*
str1
==
'\''
)
{
if
(
*
str2
!=
'-'
&&
*
str2
!=
'\''
)
{
str1
++
;
len1
--
;
continue
;
}
}
else
if
(
*
str2
==
'-'
||
*
str2
==
'\''
)
{
str2
++
;
len2
--
;
continue
;
}
}
ce1
=
collation_table
[
collation_table
[
*
str1
>>
8
]
+
(
*
str1
&
0xff
)];
ce2
=
collation_table
[
collation_table
[
*
str2
>>
8
]
+
(
*
str2
&
0xff
)];
if
(
ce1
!=
(
unsigned
int
)
-
1
&&
ce2
!=
(
unsigned
int
)
-
1
)
ret
=
(
ce1
>>
16
)
-
(
ce2
>>
16
);
else
ret
=
*
str1
-
*
str2
;
if
(
ret
)
return
ret
;
str1
++
;
str2
++
;
len1
--
;
len2
--
;
}
return
len1
-
len2
;
}
static
inline
int
compare_diacritic_weights
(
int
flags
,
const
WCHAR
*
str1
,
int
len1
,
const
WCHAR
*
str2
,
int
len2
)
{
unsigned
int
ce1
,
ce2
;
int
ret
;
/* 32-bit collation element table format:
* unicode weight - high 16 bit, diacritic weight - high 8 bit of low 16 bit,
* case weight - high 4 bit of low 8 bit.
*/
while
(
len1
>
0
&&
len2
>
0
)
{
if
(
flags
&
NORM_IGNORESYMBOLS
)
{
int
skip
=
0
;
/* FIXME: not tested */
if
(
get_char_typeW
(
*
str1
)
&
(
C1_PUNCT
|
C1_SPACE
))
{
str1
++
;
len1
--
;
skip
=
1
;
}
if
(
get_char_typeW
(
*
str2
)
&
(
C1_PUNCT
|
C1_SPACE
))
{
str2
++
;
len2
--
;
skip
=
1
;
}
if
(
skip
)
continue
;
}
ce1
=
collation_table
[
collation_table
[
*
str1
>>
8
]
+
(
*
str1
&
0xff
)];
ce2
=
collation_table
[
collation_table
[
*
str2
>>
8
]
+
(
*
str2
&
0xff
)];
if
(
ce1
!=
(
unsigned
int
)
-
1
&&
ce2
!=
(
unsigned
int
)
-
1
)
ret
=
((
ce1
>>
8
)
&
0xff
)
-
((
ce2
>>
8
)
&
0xff
);
else
ret
=
*
str1
-
*
str2
;
if
(
ret
)
return
ret
;
str1
++
;
str2
++
;
len1
--
;
len2
--
;
}
return
len1
-
len2
;
}
static
inline
int
compare_case_weights
(
int
flags
,
const
WCHAR
*
str1
,
int
len1
,
const
WCHAR
*
str2
,
int
len2
)
{
unsigned
int
ce1
,
ce2
;
int
ret
;
/* 32-bit collation element table format:
* unicode weight - high 16 bit, diacritic weight - high 8 bit of low 16 bit,
* case weight - high 4 bit of low 8 bit.
*/
while
(
len1
>
0
&&
len2
>
0
)
{
if
(
flags
&
NORM_IGNORESYMBOLS
)
{
int
skip
=
0
;
/* FIXME: not tested */
if
(
get_char_typeW
(
*
str1
)
&
(
C1_PUNCT
|
C1_SPACE
))
{
str1
++
;
len1
--
;
skip
=
1
;
}
if
(
get_char_typeW
(
*
str2
)
&
(
C1_PUNCT
|
C1_SPACE
))
{
str2
++
;
len2
--
;
skip
=
1
;
}
if
(
skip
)
continue
;
}
ce1
=
collation_table
[
collation_table
[
*
str1
>>
8
]
+
(
*
str1
&
0xff
)];
ce2
=
collation_table
[
collation_table
[
*
str2
>>
8
]
+
(
*
str2
&
0xff
)];
if
(
ce1
!=
(
unsigned
int
)
-
1
&&
ce2
!=
(
unsigned
int
)
-
1
)
ret
=
((
ce1
>>
4
)
&
0x0f
)
-
((
ce2
>>
4
)
&
0x0f
);
else
ret
=
*
str1
-
*
str2
;
if
(
ret
)
return
ret
;
str1
++
;
str2
++
;
len1
--
;
len2
--
;
}
return
len1
-
len2
;
}
static
inline
int
real_length
(
const
WCHAR
*
str
,
int
len
)
{
int
real_len
=
0
;
while
(
len
--
&&
*
str
++
)
real_len
++
;
return
real_len
;
}
int
wine_compare_string
(
int
flags
,
const
WCHAR
*
str1
,
int
len1
,
const
WCHAR
*
str2
,
int
len2
)
{
int
ret
;
len1
=
real_length
(
str1
,
len1
);
len2
=
real_length
(
str2
,
len2
);
ret
=
compare_unicode_weights
(
flags
,
str1
,
len1
,
str2
,
len2
);
if
(
!
ret
)
{
if
(
!
(
flags
&
NORM_IGNORENONSPACE
))
ret
=
compare_diacritic_weights
(
flags
,
str1
,
len1
,
str2
,
len2
);
if
(
!
ret
&&
!
(
flags
&
NORM_IGNORECASE
))
ret
=
compare_case_weights
(
flags
,
str1
,
len1
,
str2
,
len2
);
}
return
ret
;
}
libs/unicode/string.c
View file @
33f9dcb1
...
...
@@ -27,7 +27,7 @@ int strcmpiW( const WCHAR *str1, const WCHAR *str2 )
{
for
(;;)
{
int
ret
=
to
upperW
(
*
str1
)
-
toupp
erW
(
*
str2
);
int
ret
=
to
lowerW
(
*
str1
)
-
tolow
erW
(
*
str2
);
if
(
ret
||
!*
str1
)
return
ret
;
str1
++
;
str2
++
;
...
...
@@ -38,7 +38,7 @@ int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n )
{
int
ret
=
0
;
for
(
;
n
>
0
;
n
--
,
str1
++
,
str2
++
)
if
((
ret
=
to
upperW
(
*
str1
)
-
toupp
erW
(
*
str2
))
||
!*
str1
)
break
;
if
((
ret
=
to
lowerW
(
*
str1
)
-
tolow
erW
(
*
str2
))
||
!*
str1
)
break
;
return
ret
;
}
...
...
libs/unicode/wine_unicode.def
View file @
33f9dcb1
...
...
@@ -12,6 +12,7 @@ EXPORTS
vsprintfW
wine_casemap_lower
wine_casemap_upper
wine_compare_string
wine_cp_enum_table
wine_cp_get_table
wine_cp_mbstowcs
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment