Alexandre Julliard : ntdll: Load the case mapping table in the Unix library.
Alexandre Julliard
julliard at winehq.org
Fri Jun 12 16:01:16 CDT 2020
Module: wine
Branch: master
Commit: 573be7e6023e73d736c341bdca1ee49594f56ee4
URL: https://source.winehq.org/git/wine.git/?a=commit;h=573be7e6023e73d736c341bdca1ee49594f56ee4
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Jun 12 10:55:21 2020 +0200
ntdll: Load the case mapping table in the Unix library.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/unix/env.c | 103 ++++++++++++++++++++---------------------
dlls/ntdll/unix/unix_private.h | 63 ++++++++++++++++++++++---
2 files changed, 106 insertions(+), 60 deletions(-)
diff --git a/dlls/ntdll/unix/env.c b/dlls/ntdll/unix/env.c
index c2674be2c6..8b37d3dcca 100644
--- a/dlls/ntdll/unix/env.c
+++ b/dlls/ntdll/unix/env.c
@@ -65,6 +65,8 @@ extern char **__wine_main_argv;
extern char **__wine_main_environ;
extern WCHAR **__wine_main_wargv;
+USHORT *uctable = NULL, *lctable = NULL;
+
static int main_argc;
static char **main_argv;
static char **main_envp;
@@ -74,6 +76,36 @@ static CPTABLEINFO unix_table;
static WCHAR system_locale[LOCALE_NAME_MAX_LENGTH];
static WCHAR user_locale[LOCALE_NAME_MAX_LENGTH];
+static void *read_nls_file( const char *name )
+{
+ const char *dir = build_dir ? build_dir : data_dir;
+ struct stat st;
+ char *path;
+ void *data, *ret = NULL;
+ int fd;
+
+ if (!(path = malloc( strlen(dir) + 22 ))) return NULL;
+ sprintf( path, "%s/nls/%s.nls", dir, name );
+ if ((fd = open( path, O_RDONLY )) != -1)
+ {
+ fstat( fd, &st );
+ if ((data = malloc( st.st_size )) && st.st_size > 0x1000 &&
+ read( fd, data, st.st_size ) == st.st_size)
+ {
+ ret = data;
+ }
+ else
+ {
+ free( data );
+ data = NULL;
+ }
+ close( fd );
+ }
+ else ERR( "failed to load %s\n", path );
+ free( path );
+ return ret;
+}
+
#ifdef __APPLE__
@@ -112,31 +144,7 @@ static struct norm_table *nfc_table;
static void init_unix_codepage(void)
{
- const char *dir = build_dir ? build_dir : data_dir;
- struct stat st;
- char *name;
- void *data;
- int fd;
-
- if (!(name = malloc( strlen(dir) + 17 ))) return;
- sprintf( name, "%s/nls/normnfc.nls", dir );
- if ((fd = open( name, O_RDONLY )) != -1)
- {
- fstat( fd, &st );
- if ((data = malloc( st.st_size )) &&
- st.st_size > 0x4000 &&
- read( fd, data, st.st_size ) == st.st_size)
- {
- nfc_table = data;
- }
- else
- {
- free( data );
- }
- close( fd );
- }
- else ERR( "failed to load %s\n", name );
- free( name );
+ nfc_table = read_nls_file( "normnfc" );
}
static int get_utf16( const WCHAR *src, unsigned int srclen, unsigned int *ch )
@@ -343,34 +351,6 @@ static const struct { const char *name; UINT cp; } charset_names[] =
{ "UTF8", CP_UTF8 }
};
-static void load_unix_cptable( unsigned int cp )
-{
- const char *dir = build_dir ? build_dir : data_dir;
- struct stat st;
- char *name;
- void *data;
- int fd;
-
- if (!(name = malloc( strlen(dir) + 22 ))) return;
- sprintf( name, "%s/nls/c_%03u.nls", dir, cp );
- if ((fd = open( name, O_RDONLY )) != -1)
- {
- fstat( fd, &st );
- if ((data = malloc( st.st_size )) && st.st_size > 0x10000 &&
- read( fd, data, st.st_size ) == st.st_size)
- {
- RtlInitCodePageTable( data, &unix_table );
- }
- else
- {
- free( data );
- }
- close( fd );
- }
- else ERR( "failed to load %s\n", name );
- free( name );
-}
-
static void init_unix_codepage(void)
{
char charset_name[16];
@@ -396,7 +376,14 @@ static void init_unix_codepage(void)
int res = strcmp( charset_names[pos].name, charset_name );
if (!res)
{
- if (charset_names[pos].cp != CP_UTF8) load_unix_cptable( charset_names[pos].cp );
+ if (charset_names[pos].cp != CP_UTF8)
+ {
+ char name[16];
+ void *data;
+
+ sprintf( name, "c_%03u", charset_names[pos].cp );
+ if ((data = read_nls_file( name ))) RtlInitCodePageTable( data, &unix_table );
+ }
return;
}
if (res > 0) max = pos - 1;
@@ -797,9 +784,17 @@ static void init_locale(void)
*/
void init_environment( int argc, char *argv[], char *envp[] )
{
+ USHORT *case_table;
+
init_unix_codepage();
init_locale();
set_process_name( argc, argv );
+
+ if ((case_table = read_nls_file( "l_intl" )))
+ {
+ uctable = case_table + 2;
+ lctable = case_table + case_table[1] + 2;
+ }
__wine_main_argc = main_argc = argc;
__wine_main_argv = main_argv = argv;
__wine_main_wargv = main_wargv = build_wargv( argv );
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 1ef2111da1..b672321440 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -123,6 +123,8 @@ extern NTSTATUS CDECL fork_and_exec( const char *unix_name, const char *unix_dir
extern const char *data_dir DECLSPEC_HIDDEN;
extern const char *build_dir DECLSPEC_HIDDEN;
extern const char *config_dir DECLSPEC_HIDDEN;
+extern USHORT *uctable DECLSPEC_HIDDEN;
+extern USHORT *lctable DECLSPEC_HIDDEN;
extern unsigned int server_cpus DECLSPEC_HIDDEN;
extern BOOL is_wow64 DECLSPEC_HIDDEN;
extern HANDLE keyed_event DECLSPEC_HIDDEN;
@@ -212,6 +214,13 @@ static inline int ntdll_wcscmp( const WCHAR *str1, const WCHAR *str2 )
return *str1 - *str2;
}
+static inline int ntdll_wcsncmp( const WCHAR *str1, const WCHAR *str2, int n )
+{
+ if (n <= 0) return 0;
+ while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
+ return *str1 - *str2;
+}
+
static inline WCHAR *ntdll_wcschr( const WCHAR *str, WCHAR ch )
{
do { if (*str == ch) return (WCHAR *)(ULONG_PTR)str; } while (*str++);
@@ -224,11 +233,53 @@ static inline WCHAR *ntdll_wcspbrk( const WCHAR *str, const WCHAR *accept )
return NULL;
}
-#define wcslen(str) ntdll_wcslen(str)
-#define wcscpy(dst,src) ntdll_wcscpy(dst,src)
-#define wcscat(dst,src) ntdll_wcscat(dst,src)
-#define wcscmp(s1,s2) ntdll_wcscmp(s1,s2)
-#define wcschr(str,ch) ntdll_wcschr(str,ch)
-#define wcspbrk(str,ac) ntdll_wcspbrk(str,ac)
+static inline WCHAR ntdll_towupper( WCHAR ch )
+{
+ return ch + uctable[uctable[uctable[ch >> 8] + ((ch >> 4) & 0x0f)] + (ch & 0x0f)];
+}
+
+static inline WCHAR ntdll_towlower( WCHAR ch )
+{
+ return ch + lctable[lctable[lctable[ch >> 8] + ((ch >> 4) & 0x0f)] + (ch & 0x0f)];
+}
+
+static inline WCHAR *ntdll_wcsupr( WCHAR *str )
+{
+ WCHAR *ret;
+ for (ret = str; *str; str++) *str = ntdll_towupper(*str);
+ return ret;
+}
+
+static inline int ntdll_wcsicmp( const WCHAR *str1, const WCHAR *str2 )
+{
+ int ret;
+ for (;;)
+ {
+ if ((ret = ntdll_towupper( *str1 ) - ntdll_towupper( *str2 )) || !*str1) return ret;
+ str1++;
+ str2++;
+ }
+}
+
+static inline int ntdll_wcsnicmp( const WCHAR *str1, const WCHAR *str2, int n )
+{
+ int ret;
+ for (ret = 0; n > 0; n--, str1++, str2++)
+ if ((ret = ntdll_towupper(*str1) - ntdll_towupper(*str2)) || !*str1) break;
+ return ret;
+}
+
+#define wcslen(str) ntdll_wcslen(str)
+#define wcscpy(dst,src) ntdll_wcscpy(dst,src)
+#define wcscat(dst,src) ntdll_wcscat(dst,src)
+#define wcscmp(s1,s2) ntdll_wcscmp(s1,s2)
+#define wcsncmp(s1,s2,n) ntdll_wcsncmp(s1,s2,n)
+#define wcschr(str,ch) ntdll_wcschr(str,ch)
+#define wcspbrk(str,ac) ntdll_wcspbrk(str,ac)
+#define wcsicmp(s1, s2) ntdll_wcsicmp(s1,s2)
+#define wcsnicmp(s1, s2,n) ntdll_wcsnicmp(s1,s2,n)
+#define wcsupr(str) ntdll_wcsupr(str)
+#define towupper(c) ntdll_towupper(c)
+#define towlower(c) ntdll_towlower(c)
#endif /* __NTDLL_UNIX_PRIVATE_H */
More information about the wine-cvs
mailing list