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
b780e5f5
Commit
b780e5f5
authored
Mar 18, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernelbase: Use linguistic case table for LCMAP_LINGUISTIC_CASING.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7ad740cd
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
129 additions
and
34 deletions
+129
-34
locale.c
dlls/kernel32/tests/locale.c
+20
-22
locale.c
dlls/kernelbase/locale.c
+109
-12
No files found.
dlls/kernel32/tests/locale.c
View file @
b780e5f5
...
...
@@ -6471,7 +6471,6 @@ static void test_SpecialCasing(void)
WCHAR
ch
;
WCHAR
exp
;
/* 0 if self */
WCHAR
exp_ling
;
/* 0 if exp */
BOOL
todo
;
}
tests
[]
=
{
{
deDEW
,
LCMAP_UPPERCASE
,
0x00DF
},
/* LATIN SMALL LETTER SHARP S */
...
...
@@ -6580,29 +6579,29 @@ static void test_SpecialCasing(void)
{
enUSW
,
LCMAP_UPPERCASE
,
'i'
,
'I'
},
/* LATIN SMALL LETTER I */
{
ltLTW
,
LCMAP_UPPERCASE
,
'i'
,
'I'
},
/* LATIN SMALL LETTER I */
{
trTRW
,
LCMAP_UPPERCASE
,
'i'
,
'I'
,
0x0130
,
TRUE
},
/* LATIN SMALL LETTER I */
{
TRTRW
,
LCMAP_UPPERCASE
,
'i'
,
'I'
,
0x0130
,
TRUE
},
/* LATIN SMALL LETTER I */
{
azCyrlazW
,
LCMAP_UPPERCASE
,
'i'
,
'I'
,
0x0130
,
TRUE
},
/* LATIN SMALL LETTER I */
{
azLatnazW
,
LCMAP_UPPERCASE
,
'i'
,
'I'
,
0x0130
,
TRUE
},
/* LATIN SMALL LETTER I */
{
trTRW
,
LCMAP_UPPERCASE
,
'i'
,
'I'
,
0x0130
},
/* LATIN SMALL LETTER I */
{
TRTRW
,
LCMAP_UPPERCASE
,
'i'
,
'I'
,
0x0130
},
/* LATIN SMALL LETTER I */
{
azCyrlazW
,
LCMAP_UPPERCASE
,
'i'
,
'I'
,
0x0130
},
/* LATIN SMALL LETTER I */
{
azLatnazW
,
LCMAP_UPPERCASE
,
'i'
,
'I'
,
0x0130
},
/* LATIN SMALL LETTER I */
{
enUSW
,
LCMAP_LOWERCASE
,
'I'
,
'i'
},
/* LATIN CAPITAL LETTER I */
{
ltLTW
,
LCMAP_LOWERCASE
,
'I'
,
'i'
},
/* LATIN CAPITAL LETTER I */
{
trTRW
,
LCMAP_LOWERCASE
,
'I'
,
'i'
,
0x0131
,
TRUE
},
/* LATIN CAPITAL LETTER I */
{
TRTRW
,
LCMAP_LOWERCASE
,
'I'
,
'i'
,
0x0131
,
TRUE
},
/* LATIN CAPITAL LETTER I */
{
azCyrlazW
,
LCMAP_LOWERCASE
,
'I'
,
'i'
,
0x0131
,
TRUE
},
/* LATIN CAPITAL LETTER I */
{
azLatnazW
,
LCMAP_LOWERCASE
,
'I'
,
'i'
,
0x0131
,
TRUE
},
/* LATIN CAPITAL LETTER I */
{
enUSW
,
LCMAP_LOWERCASE
,
0x0130
,
0
,
'i'
,
TRUE
},
/* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{
trTRW
,
LCMAP_LOWERCASE
,
0x0130
,
0
,
'i'
,
TRUE
},
/* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{
TRTRW
,
LCMAP_LOWERCASE
,
0x0130
,
0
,
'i'
,
TRUE
},
/* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{
azCyrlazW
,
LCMAP_LOWERCASE
,
0x0130
,
0
,
'i'
,
TRUE
},
/* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{
azLatnazW
,
LCMAP_LOWERCASE
,
0x0130
,
0
,
'i'
,
TRUE
},
/* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{
enUSW
,
LCMAP_UPPERCASE
,
0x0131
,
0
,
'I'
,
TRUE
},
/* LATIN SMALL LETTER DOTLESS I */
{
trTRW
,
LCMAP_UPPERCASE
,
0x0131
,
0
,
'I'
,
TRUE
},
/* LATIN SMALL LETTER DOTLESS I */
{
TRTRW
,
LCMAP_UPPERCASE
,
0x0131
,
0
,
'I'
,
TRUE
},
/* LATIN SMALL LETTER DOTLESS I */
{
azCyrlazW
,
LCMAP_UPPERCASE
,
0x0131
,
0
,
'I'
,
TRUE
},
/* LATIN SMALL LETTER DOTLESS I */
{
azLatnazW
,
LCMAP_UPPERCASE
,
0x0131
,
0
,
'I'
,
TRUE
},
/* LATIN SMALL LETTER DOTLESS I */
{
trTRW
,
LCMAP_LOWERCASE
,
'I'
,
'i'
,
0x0131
},
/* LATIN CAPITAL LETTER I */
{
TRTRW
,
LCMAP_LOWERCASE
,
'I'
,
'i'
,
0x0131
},
/* LATIN CAPITAL LETTER I */
{
azCyrlazW
,
LCMAP_LOWERCASE
,
'I'
,
'i'
,
0x0131
},
/* LATIN CAPITAL LETTER I */
{
azLatnazW
,
LCMAP_LOWERCASE
,
'I'
,
'i'
,
0x0131
},
/* LATIN CAPITAL LETTER I */
{
enUSW
,
LCMAP_LOWERCASE
,
0x0130
,
0
,
'i'
},
/* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{
trTRW
,
LCMAP_LOWERCASE
,
0x0130
,
0
,
'i'
},
/* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{
TRTRW
,
LCMAP_LOWERCASE
,
0x0130
,
0
,
'i'
},
/* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{
azCyrlazW
,
LCMAP_LOWERCASE
,
0x0130
,
0
,
'i'
},
/* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{
azLatnazW
,
LCMAP_LOWERCASE
,
0x0130
,
0
,
'i'
},
/* LATIN CAPITAL LETTER I WITH DOT ABOVE */
{
enUSW
,
LCMAP_UPPERCASE
,
0x0131
,
0
,
'I'
},
/* LATIN SMALL LETTER DOTLESS I */
{
trTRW
,
LCMAP_UPPERCASE
,
0x0131
,
0
,
'I'
},
/* LATIN SMALL LETTER DOTLESS I */
{
TRTRW
,
LCMAP_UPPERCASE
,
0x0131
,
0
,
'I'
},
/* LATIN SMALL LETTER DOTLESS I */
{
azCyrlazW
,
LCMAP_UPPERCASE
,
0x0131
,
0
,
'I'
},
/* LATIN SMALL LETTER DOTLESS I */
{
azLatnazW
,
LCMAP_UPPERCASE
,
0x0131
,
0
,
'I'
},
/* LATIN SMALL LETTER DOTLESS I */
};
if
(
!
pLCMapStringEx
)
...
...
@@ -6628,7 +6627,6 @@ static void test_SpecialCasing(void)
ok
(
ret
==
1
,
"expected 1, got %d for %04x for %s
\n
"
,
ret
,
tests
[
i
].
ch
,
wine_dbgstr_w
(
tests
[
i
].
lang
));
exp
=
tests
[
i
].
exp_ling
?
tests
[
i
].
exp_ling
:
exp
;
todo_wine_if
(
tests
[
i
].
todo
)
ok
(
buffer
[
0
]
==
exp
||
broken
(
buffer
[
0
]
!=
exp
),
"expected %04x, got %04x for %04x for %s
\n
"
,
exp
,
buffer
[
0
],
tests
[
i
].
ch
,
wine_dbgstr_w
(
tests
[
i
].
lang
));
...
...
dlls/kernelbase/locale.c
View file @
b780e5f5
...
...
@@ -576,12 +576,34 @@ static unsigned int nb_codepages;
static
struct
norm_table
*
norm_info
;
struct
sortguid
{
GUID
id
;
/* sort GUID */
DWORD
flags
;
/* flags */
DWORD
compr
;
/* offset to compression table */
DWORD
except
;
/* exception table offset in sortkey table */
DWORD
ling_except
;
/* exception table offset for linguistic casing */
DWORD
casemap
;
/* linguistic casemap table offset */
};
#define FLAG_HAS_3_BYTE_WEIGHTS 0x01
#define FLAG_REVERSEDIACRITICS 0x10
#define FLAG_DOUBLECOMPRESSION 0x20
#define FLAG_INVERSECASING 0x40
static
const
struct
sortguid
*
current_locale_sort
;
static
const
GUID
default_sort_guid
=
{
0x00000001
,
0x57ee
,
0x1e5c
,
{
0x00
,
0xb4
,
0xd0
,
0x00
,
0x0b
,
0xb1
,
0xe1
,
0x1e
}};
static
struct
{
DWORD
*
keys
;
/* sortkey table, indexed by char */
USHORT
*
casemap
;
/* casemap table, in l_intl.nls format */
WORD
*
ctypes
;
/* CT_CTYPE1,2,3 values */
BYTE
*
ctype_idx
;
/* index to map char to ctypes array entry */
DWORD
*
keys
;
/* sortkey table, indexed by char */
USHORT
*
casemap
;
/* casemap table, in l_intl.nls format */
WORD
*
ctypes
;
/* CT_CTYPE1,2,3 values */
BYTE
*
ctype_idx
;
/* index to map char to ctypes array entry */
DWORD
version
;
/* NLS version */
DWORD
guid_count
;
/* number of sort GUIDs */
struct
sortguid
*
guids
;
/* table of sort GUIDs */
}
sort
;
static
CRITICAL_SECTION
locale_section
;
...
...
@@ -594,18 +616,82 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
static
CRITICAL_SECTION
locale_section
=
{
&
critsect_debug
,
-
1
,
0
,
0
,
0
,
0
};
/***********************************************************************
* init_sortkeys
*/
static
void
init_sortkeys
(
DWORD
*
ptr
)
{
WORD
*
ctype
;
DWORD
*
table
;
sort
.
keys
=
(
DWORD
*
)((
char
*
)
ptr
+
ptr
[
0
]);
sort
.
casemap
=
(
USHORT
*
)((
char
*
)
ptr
+
ptr
[
1
]);
sort
.
keys
=
(
DWORD
*
)((
char
*
)
ptr
+
ptr
[
0
]);
sort
.
casemap
=
(
USHORT
*
)((
char
*
)
ptr
+
ptr
[
1
]);
ctype
=
(
WORD
*
)((
char
*
)
ptr
+
ptr
[
2
]);
sort
.
ctypes
=
ctype
+
2
;
ctype
=
(
WORD
*
)((
char
*
)
ptr
+
ptr
[
2
]);
sort
.
ctypes
=
ctype
+
2
;
sort
.
ctype_idx
=
(
BYTE
*
)
ctype
+
ctype
[
1
]
+
2
;
table
=
(
DWORD
*
)((
char
*
)
ptr
+
ptr
[
3
]);
sort
.
version
=
table
[
0
];
sort
.
guid_count
=
table
[
1
];
sort
.
guids
=
(
struct
sortguid
*
)(
table
+
2
);
}
static
const
struct
sortguid
*
find_sortguid
(
const
GUID
*
guid
)
{
int
pos
,
ret
,
min
=
0
,
max
=
sort
.
guid_count
-
1
;
while
(
min
<=
max
)
{
pos
=
(
min
+
max
)
/
2
;
ret
=
memcmp
(
guid
,
&
sort
.
guids
[
pos
].
id
,
sizeof
(
*
guid
)
);
if
(
!
ret
)
return
&
sort
.
guids
[
pos
];
if
(
ret
>
0
)
min
=
pos
+
1
;
else
max
=
pos
-
1
;
}
ERR
(
"no sort found for %s
\n
"
,
debugstr_guid
(
guid
));
return
NULL
;
}
static
const
struct
sortguid
*
get_language_sort
(
const
WCHAR
*
locale
)
{
WCHAR
*
p
,
*
end
,
buffer
[
LOCALE_NAME_MAX_LENGTH
],
guidstr
[
39
];
const
struct
sortguid
*
ret
;
UNICODE_STRING
str
;
GUID
guid
;
HKEY
key
;
DWORD
size
,
type
;
if
(
locale
==
LOCALE_NAME_USER_DEFAULT
)
{
if
(
current_locale_sort
)
return
current_locale_sort
;
GetUserDefaultLocaleName
(
buffer
,
ARRAY_SIZE
(
buffer
));
}
else
lstrcpynW
(
buffer
,
locale
,
LOCALE_NAME_MAX_LENGTH
);
if
(
buffer
[
0
]
&&
!
RegOpenKeyExW
(
nls_key
,
L"Sorting
\\
Ids"
,
0
,
KEY_READ
,
&
key
))
{
for
(;;)
{
size
=
sizeof
(
guidstr
);
if
(
!
RegQueryValueExW
(
key
,
buffer
,
NULL
,
&
type
,
(
BYTE
*
)
guidstr
,
&
size
)
&&
type
==
REG_SZ
)
{
RtlInitUnicodeString
(
&
str
,
guidstr
);
if
(
!
RtlGUIDFromString
(
&
str
,
&
guid
))
{
ret
=
find_sortguid
(
&
guid
);
goto
done
;
}
break
;
}
for
(
p
=
end
=
buffer
;
*
p
;
p
++
)
if
(
*
p
==
'-'
||
*
p
==
'_'
)
end
=
p
;
if
(
end
==
buffer
)
break
;
*
end
=
0
;
}
}
ret
=
find_sortguid
(
&
default_sort_guid
);
done:
RegCloseKey
(
key
);
return
ret
;
}
...
...
@@ -648,6 +734,8 @@ void init_locale(void)
RtlInitNlsTables
(
ansi_ptr
,
oem_ptr
,
sort
.
casemap
,
&
nls_info
);
RtlResetRtlTranslations
(
&
nls_info
);
current_locale_sort
=
get_language_sort
(
LOCALE_NAME_USER_DEFAULT
);
RegCreateKeyExW
(
HKEY_LOCAL_MACHINE
,
L"System
\\
CurrentControlSet
\\
Control
\\
Nls"
,
0
,
NULL
,
REG_OPTION_NON_VOLATILE
,
KEY_ALL_ACCESS
,
NULL
,
&
nls_key
,
NULL
);
RegCreateKeyExW
(
HKEY_LOCAL_MACHINE
,
L"Software
\\
Microsoft
\\
Windows NT
\\
CurrentVersion
\\
Time Zones"
,
...
...
@@ -4737,6 +4825,7 @@ INT WINAPI DECLSPEC_HOTPATCH LCMapStringEx( const WCHAR *locale, DWORD flags, co
WCHAR
*
dst
,
int
dstlen
,
NLSVERSIONINFO
*
version
,
void
*
reserved
,
LPARAM
handle
)
{
const
struct
sortguid
*
sortid
;
LPWSTR
dst_ptr
;
INT
len
;
...
...
@@ -4767,6 +4856,13 @@ INT WINAPI DECLSPEC_HOTPATCH LCMapStringEx( const WCHAR *locale, DWORD flags, co
if
(
!
dstlen
)
dst
=
NULL
;
if
(
!
(
sortid
=
get_language_sort
(
locale
)))
{
FIXME
(
"unknown locale %s
\n
"
,
debugstr_w
(
locale
)
);
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
if
(
flags
&
LCMAP_SORTKEY
)
{
INT
ret
;
...
...
@@ -4910,7 +5006,8 @@ INT WINAPI DECLSPEC_HOTPATCH LCMapStringEx( const WCHAR *locale, DWORD flags, co
if
(
flags
&
(
LCMAP_UPPERCASE
|
LCMAP_LOWERCASE
))
{
USHORT
*
table
=
(
flags
&
LCMAP_LOWERCASE
)
?
nls_info
.
LowerCaseTable
:
nls_info
.
UpperCaseTable
;
const
USHORT
*
table
=
sort
.
casemap
+
(
flags
&
LCMAP_LINGUISTIC_CASING
?
sortid
->
casemap
:
0
);
table
=
table
+
2
+
(
flags
&
LCMAP_LOWERCASE
?
table
[
1
]
:
0
);
for
(
len
=
dstlen
,
dst_ptr
=
dst
;
srclen
&&
len
;
src
++
,
srclen
--
,
len
--
)
*
dst_ptr
++
=
casemap
(
table
,
*
src
);
}
...
...
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