ntdll: Load the case mapping table in the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
412555e0cd
commit
573be7e602
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
|
Loading…
Reference in New Issue