Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
c5eb9cb2
Commit
c5eb9cb2
authored
Jun 09, 2022
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Share a few more locale functions with the Unix side.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
ab88f34d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
105 additions
and
127 deletions
+105
-127
locale.c
dlls/ntdll/locale.c
+20
-93
locale_private.h
dlls/ntdll/locale_private.h
+78
-0
env.c
dlls/ntdll/unix/env.c
+7
-34
No files found.
dlls/ntdll/locale.c
View file @
c5eb9cb2
...
...
@@ -39,11 +39,8 @@ UINT NlsAnsiCodePage = 0;
BYTE
NlsMbCodePageTag
=
0
;
BYTE
NlsMbOemCodePageTag
=
0
;
static
const
WCHAR
*
locale_strings
;
static
NLSTABLEINFO
nls_info
=
{
{
CP_UTF8
},
{
CP_UTF8
}
};
static
struct
norm_table
*
norm_tables
[
16
];
static
const
NLS_LOCALE_LCID_INDEX
*
lcids_index
;
static
const
NLS_LOCALE_LCNAME_INDEX
*
lcnames_index
;
static
const
NLS_LOCALE_HEADER
*
locale_table
;
...
...
@@ -53,13 +50,6 @@ static WCHAR casemap( USHORT *table, WCHAR ch )
}
static
WCHAR
casemap_ascii
(
WCHAR
ch
)
{
if
(
ch
>=
'a'
&&
ch
<=
'z'
)
ch
-=
'a'
-
'A'
;
return
ch
;
}
static
NTSTATUS
load_norm_table
(
ULONG
form
,
const
struct
norm_table
**
info
)
{
unsigned
int
i
;
...
...
@@ -98,59 +88,6 @@ invalid:
}
static
int
compare_locale_names
(
const
WCHAR
*
n1
,
const
WCHAR
*
n2
)
{
for
(;;)
{
WCHAR
ch1
=
casemap_ascii
(
*
n1
++
);
WCHAR
ch2
=
casemap_ascii
(
*
n2
++
);
if
(
ch1
==
'_'
)
ch1
=
'-'
;
if
(
ch2
==
'_'
)
ch2
=
'-'
;
if
(
!
ch1
||
ch1
!=
ch2
)
return
ch1
-
ch2
;
}
}
static
const
NLS_LOCALE_LCNAME_INDEX
*
find_lcname_entry
(
const
WCHAR
*
name
)
{
int
min
=
0
,
max
=
locale_table
->
nb_lcnames
-
1
;
if
(
!
name
)
return
NULL
;
while
(
min
<=
max
)
{
int
res
,
pos
=
(
min
+
max
)
/
2
;
const
WCHAR
*
str
=
locale_strings
+
lcnames_index
[
pos
].
name
;
res
=
compare_locale_names
(
name
,
str
+
1
);
if
(
res
<
0
)
max
=
pos
-
1
;
else
if
(
res
>
0
)
min
=
pos
+
1
;
else
return
&
lcnames_index
[
pos
];
}
return
NULL
;
}
static
const
NLS_LOCALE_LCID_INDEX
*
find_lcid_entry
(
LCID
lcid
)
{
int
min
=
0
,
max
=
locale_table
->
nb_lcids
-
1
;
while
(
min
<=
max
)
{
int
pos
=
(
min
+
max
)
/
2
;
if
(
lcid
<
lcids_index
[
pos
].
id
)
max
=
pos
-
1
;
else
if
(
lcid
>
lcids_index
[
pos
].
id
)
min
=
pos
+
1
;
else
return
&
lcids_index
[
pos
];
}
return
NULL
;
}
static
const
NLS_LOCALE_DATA
*
get_locale_data
(
UINT
idx
)
{
ULONG
offset
=
locale_table
->
locales_offset
+
idx
*
locale_table
->
locale_size
;
return
(
const
NLS_LOCALE_DATA
*
)((
const
char
*
)
locale_table
+
offset
);
}
void
locale_init
(
void
)
{
USHORT
utf8
[
2
]
=
{
0
,
CP_UTF8
};
...
...
@@ -162,17 +99,7 @@ void locale_init(void)
UINT
ansi_cp
=
1252
,
oem_cp
=
437
;
void
*
ansi_ptr
=
utf8
,
*
oem_ptr
=
utf8
,
*
case_ptr
;
NTSTATUS
status
;
struct
{
UINT
ctypes
;
UINT
unknown1
;
UINT
unknown2
;
UINT
unknown3
;
UINT
locales
;
UINT
charmaps
;
UINT
geoids
;
UINT
scripts
;
}
*
header
;
const
struct
locale_nls_header
*
header
;
status
=
RtlGetLocaleFileMappingAddress
(
(
void
**
)
&
header
,
&
system_lcid
,
&
unused
);
if
(
status
)
...
...
@@ -181,17 +108,14 @@ void locale_init(void)
return
;
}
locale_table
=
(
const
NLS_LOCALE_HEADER
*
)((
char
*
)
header
+
header
->
locales
);
lcids_index
=
(
const
NLS_LOCALE_LCID_INDEX
*
)((
char
*
)
locale_table
+
locale_table
->
lcids_offset
);
lcnames_index
=
(
const
NLS_LOCALE_LCNAME_INDEX
*
)((
char
*
)
locale_table
+
locale_table
->
lcnames_offset
);
locale_strings
=
(
const
WCHAR
*
)((
char
*
)
locale_table
+
locale_table
->
strings_offset
);
value
.
Buffer
=
locale
;
value
.
MaximumLength
=
sizeof
(
locale
);
RtlInitUnicodeString
(
&
name
,
L"WINEUSERLOCALE"
);
if
(
!
RtlQueryEnvironmentVariable_U
(
NULL
,
&
name
,
&
value
))
{
const
NLS_LOCALE_LCNAME_INDEX
*
entry
=
find_lcname_entry
(
locale
);
if
(
entry
)
user_lcid
=
get_locale_data
(
entry
->
idx
)
->
idefaultlanguage
;
const
NLS_LOCALE_LCNAME_INDEX
*
entry
=
find_lcname_entry
(
locale
_table
,
locale
);
if
(
entry
)
user_lcid
=
get_locale_data
(
locale_table
,
entry
->
idx
)
->
idefaultlanguage
;
}
if
(
!
user_lcid
)
user_lcid
=
system_lcid
;
NtSetDefaultUILanguage
(
user_lcid
);
...
...
@@ -204,15 +128,15 @@ void locale_init(void)
}
else
{
const
NLS_LOCALE_LCID_INDEX
*
entry
=
find_lcid_entry
(
system_lcid
);
ansi_cp
=
get_locale_data
(
entry
->
idx
)
->
idefaultansicodepage
;
oem_cp
=
get_locale_data
(
entry
->
idx
)
->
idefaultcodepage
;
const
NLS_LOCALE_LCID_INDEX
*
entry
=
find_lcid_entry
(
locale_table
,
system_lcid
);
ansi_cp
=
get_locale_data
(
locale_table
,
entry
->
idx
)
->
idefaultansicodepage
;
oem_cp
=
get_locale_data
(
locale_table
,
entry
->
idx
)
->
idefaultcodepage
;
}
if
(
!
RtlQueryActivationContextApplicationSettings
(
0
,
NULL
,
L"http://schemas.microsoft.com/SMI/2019/WindowsSettings"
,
L"activeCodePage"
,
locale
,
ARRAY_SIZE
(
locale
),
NULL
))
{
const
NLS_LOCALE_LCNAME_INDEX
*
entry
=
find_lcname_entry
(
locale
);
const
NLS_LOCALE_LCNAME_INDEX
*
entry
=
find_lcname_entry
(
locale
_table
,
locale
);
if
(
!
wcsicmp
(
locale
,
L"utf-8"
))
{
...
...
@@ -223,10 +147,10 @@ void locale_init(void)
if
(
ansi_cp
==
CP_UTF8
)
ansi_cp
=
1252
;
if
(
oem_cp
==
CP_UTF8
)
oem_cp
=
437
;
}
else
if
((
entry
=
find_lcname_entry
(
locale
)))
else
if
((
entry
=
find_lcname_entry
(
locale
_table
,
locale
)))
{
ansi_cp
=
get_locale_data
(
entry
->
idx
)
->
idefaultansicodepage
;
oem_cp
=
get_locale_data
(
entry
->
idx
)
->
idefaultcodepage
;
ansi_cp
=
get_locale_data
(
locale_table
,
entry
->
idx
)
->
idefaultansicodepage
;
oem_cp
=
get_locale_data
(
locale_table
,
entry
->
idx
)
->
idefaultcodepage
;
}
}
...
...
@@ -917,11 +841,11 @@ WCHAR __cdecl towupper( WCHAR ch )
*/
BOOLEAN
WINAPI
RtlIsValidLocaleName
(
const
WCHAR
*
name
,
ULONG
flags
)
{
const
NLS_LOCALE_LCNAME_INDEX
*
entry
=
find_lcname_entry
(
name
);
const
NLS_LOCALE_LCNAME_INDEX
*
entry
=
find_lcname_entry
(
locale_table
,
name
);
if
(
!
entry
)
return
FALSE
;
/* reject neutral locale unless flag 2 is set */
if
(
!
(
flags
&
2
)
&&
!
get_locale_data
(
entry
->
idx
)
->
inotneutral
)
return
FALSE
;
if
(
!
(
flags
&
2
)
&&
!
get_locale_data
(
locale_table
,
entry
->
idx
)
->
inotneutral
)
return
FALSE
;
return
TRUE
;
}
...
...
@@ -931,6 +855,7 @@ BOOLEAN WINAPI RtlIsValidLocaleName( const WCHAR *name, ULONG flags )
*/
NTSTATUS
WINAPI
RtlLcidToLocaleName
(
LCID
lcid
,
UNICODE_STRING
*
str
,
ULONG
flags
,
BOOLEAN
alloc
)
{
const
WCHAR
*
strings
=
(
const
WCHAR
*
)((
char
*
)
locale_table
+
locale_table
->
strings_offset
);
const
NLS_LOCALE_LCID_INDEX
*
entry
;
const
WCHAR
*
name
;
ULONG
len
;
...
...
@@ -952,11 +877,12 @@ NTSTATUS WINAPI RtlLcidToLocaleName( LCID lcid, UNICODE_STRING *str, ULONG flags
return
STATUS_INVALID_PARAMETER_1
;
}
if
(
!
(
entry
=
find_lcid_entry
(
lcid
)))
return
STATUS_INVALID_PARAMETER_1
;
if
(
!
(
entry
=
find_lcid_entry
(
l
ocale_table
,
l
cid
)))
return
STATUS_INVALID_PARAMETER_1
;
/* reject neutral locale unless flag 2 is set */
if
(
!
(
flags
&
2
)
&&
!
get_locale_data
(
entry
->
idx
)
->
inotneutral
)
return
STATUS_INVALID_PARAMETER_1
;
if
(
!
(
flags
&
2
)
&&
!
get_locale_data
(
locale_table
,
entry
->
idx
)
->
inotneutral
)
return
STATUS_INVALID_PARAMETER_1
;
name
=
locale_
strings
+
entry
->
name
;
name
=
strings
+
entry
->
name
;
len
=
*
name
++
;
if
(
alloc
)
...
...
@@ -979,11 +905,12 @@ NTSTATUS WINAPI RtlLcidToLocaleName( LCID lcid, UNICODE_STRING *str, ULONG flags
*/
NTSTATUS
WINAPI
RtlLocaleNameToLcid
(
const
WCHAR
*
name
,
LCID
*
lcid
,
ULONG
flags
)
{
const
NLS_LOCALE_LCNAME_INDEX
*
entry
=
find_lcname_entry
(
name
);
const
NLS_LOCALE_LCNAME_INDEX
*
entry
=
find_lcname_entry
(
locale_table
,
name
);
if
(
!
entry
)
return
STATUS_INVALID_PARAMETER_1
;
/* reject neutral locale unless flag 2 is set */
if
(
!
(
flags
&
2
)
&&
!
get_locale_data
(
entry
->
idx
)
->
inotneutral
)
return
STATUS_INVALID_PARAMETER_1
;
if
(
!
(
flags
&
2
)
&&
!
get_locale_data
(
locale_table
,
entry
->
idx
)
->
inotneutral
)
return
STATUS_INVALID_PARAMETER_1
;
*
lcid
=
entry
->
id
;
TRACE
(
"%s -> %04x
\n
"
,
debugstr_w
(
name
),
*
lcid
);
return
STATUS_SUCCESS
;
...
...
dlls/ntdll/locale_private.h
View file @
c5eb9cb2
...
...
@@ -88,6 +88,27 @@ struct norm_table
};
/* locale.nls file */
struct
locale_nls_header
{
UINT
ctypes
;
UINT
unknown1
;
UINT
unknown2
;
UINT
unknown3
;
UINT
locales
;
UINT
charmaps
;
UINT
geoids
;
UINT
scripts
;
};
static
inline
WCHAR
casemap_ascii
(
WCHAR
ch
)
{
if
(
ch
>=
'a'
&&
ch
<=
'z'
)
ch
-=
'a'
-
'A'
;
return
ch
;
}
static
inline
int
get_utf16
(
const
WCHAR
*
src
,
unsigned
int
srclen
,
unsigned
int
*
ch
)
{
if
(
IS_HIGH_SURROGATE
(
src
[
0
]
))
...
...
@@ -198,6 +219,63 @@ static inline void init_codepage_table( USHORT *ptr, CPTABLEINFO *info )
}
static
inline
int
compare_locale_names
(
const
WCHAR
*
n1
,
const
WCHAR
*
n2
)
{
for
(;;)
{
WCHAR
ch1
=
casemap_ascii
(
*
n1
++
);
WCHAR
ch2
=
casemap_ascii
(
*
n2
++
);
if
(
ch1
==
'_'
)
ch1
=
'-'
;
if
(
ch2
==
'_'
)
ch2
=
'-'
;
if
(
!
ch1
||
ch1
!=
ch2
)
return
ch1
-
ch2
;
}
}
static
inline
const
NLS_LOCALE_LCNAME_INDEX
*
find_lcname_entry
(
const
NLS_LOCALE_HEADER
*
header
,
const
WCHAR
*
name
)
{
const
WCHAR
*
strings
=
(
const
WCHAR
*
)((
char
*
)
header
+
header
->
strings_offset
);
const
NLS_LOCALE_LCNAME_INDEX
*
index
=
(
const
NLS_LOCALE_LCNAME_INDEX
*
)((
char
*
)
header
+
header
->
lcnames_offset
);
int
min
=
0
,
max
=
header
->
nb_lcnames
-
1
;
if
(
!
name
)
return
NULL
;
while
(
min
<=
max
)
{
int
res
,
pos
=
(
min
+
max
)
/
2
;
const
WCHAR
*
str
=
strings
+
index
[
pos
].
name
;
res
=
compare_locale_names
(
name
,
str
+
1
);
if
(
res
<
0
)
max
=
pos
-
1
;
else
if
(
res
>
0
)
min
=
pos
+
1
;
else
return
&
index
[
pos
];
}
return
NULL
;
}
static
inline
const
NLS_LOCALE_LCID_INDEX
*
find_lcid_entry
(
const
NLS_LOCALE_HEADER
*
header
,
LCID
lcid
)
{
const
NLS_LOCALE_LCID_INDEX
*
index
=
(
const
NLS_LOCALE_LCID_INDEX
*
)((
char
*
)
header
+
header
->
lcids_offset
);
int
min
=
0
,
max
=
header
->
nb_lcids
-
1
;
while
(
min
<=
max
)
{
int
pos
=
(
min
+
max
)
/
2
;
if
(
lcid
<
index
[
pos
].
id
)
max
=
pos
-
1
;
else
if
(
lcid
>
index
[
pos
].
id
)
min
=
pos
+
1
;
else
return
&
index
[
pos
];
}
return
NULL
;
}
static
inline
const
NLS_LOCALE_DATA
*
get_locale_data
(
const
NLS_LOCALE_HEADER
*
header
,
UINT
idx
)
{
ULONG
offset
=
header
->
locales_offset
+
idx
*
header
->
locale_size
;
return
(
const
NLS_LOCALE_DATA
*
)((
const
char
*
)
header
+
offset
);
}
static
inline
unsigned
int
cp_mbstowcs_size
(
const
CPTABLEINFO
*
info
,
const
char
*
str
,
unsigned
int
len
)
{
unsigned
int
res
;
...
...
dlls/ntdll/unix/env.c
View file @
c5eb9cb2
...
...
@@ -761,43 +761,16 @@ static BOOL unix_to_win_locale( const char *unix_name, char *win_name )
}
static
LCID
init_system_lcid
(
void
*
locale_ptr
)
{
struct
{
UINT
ctypes
;
UINT
unknown1
;
UINT
unknown2
;
UINT
unknown3
;
UINT
locales
;
UINT
charmaps
;
UINT
geoids
;
UINT
scripts
;
}
*
header
=
locale_ptr
;
static
LCID
init_system_lcid
(
const
struct
locale_nls_header
*
header
)
{
WCHAR
name
[
LOCALE_NAME_MAX_LENGTH
];
const
NLS_LOCALE_LCNAME_INDEX
*
lcnames
;
const
NLS_LOCALE_HEADER
*
locale_table
;
const
WCHAR
*
locale_strings
;
int
min
,
max
;
const
NLS_LOCALE_HEADER
*
locale_table
=
(
const
NLS_LOCALE_HEADER
*
)((
char
*
)
header
+
header
->
locales
);
const
NLS_LOCALE_LCNAME_INDEX
*
entry
;
ascii_to_unicode
(
name
,
system_locale
,
strlen
(
system_locale
)
+
1
);
locale_table
=
(
const
NLS_LOCALE_HEADER
*
)((
char
*
)
header
+
header
->
locales
);
locale_strings
=
(
const
WCHAR
*
)((
char
*
)
locale_table
+
locale_table
->
strings_offset
);
lcnames
=
(
const
NLS_LOCALE_LCNAME_INDEX
*
)((
char
*
)
locale_table
+
locale_table
->
lcnames_offset
);
min
=
0
;
max
=
locale_table
->
nb_lcnames
-
1
;
while
(
min
<=
max
)
{
int
pos
=
(
min
+
max
)
/
2
;
int
res
=
wcsicmp
(
name
,
locale_strings
+
lcnames
[
pos
].
name
+
1
);
if
(
res
<
0
)
max
=
pos
-
1
;
else
if
(
res
>
0
)
min
=
pos
+
1
;
else
{
ULONG
offset
=
locale_table
->
locales_offset
+
lcnames
[
pos
].
idx
*
locale_table
->
locale_size
;
return
((
const
NLS_LOCALE_DATA
*
)((
const
char
*
)
locale_table
+
offset
))
->
idefaultlanguage
;
}
}
if
((
entry
=
find_lcname_entry
(
locale_table
,
name
)))
return
get_locale_data
(
locale_table
,
entry
->
idx
)
->
idefaultlanguage
;
return
MAKELANGID
(
LANG_ENGLISH
,
SUBLANG_DEFAULT
);
}
...
...
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