forked from Mirrors/wine-wine
ntdll: Move the locales initialization to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>feature/deterministic
parent
ee5c842e53
commit
b86dc3926b
|
@ -22,16 +22,10 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "wine/port.h"
|
#include "wine/port.h"
|
||||||
|
|
||||||
#include <locale.h>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
# include <CoreFoundation/CFLocale.h>
|
|
||||||
# include <CoreFoundation/CFString.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "ntstatus.h"
|
#include "ntstatus.h"
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
|
@ -697,80 +691,18 @@ void init_unix_codepage(void)
|
||||||
unix_funcs->get_unix_codepage( &unix_table );
|
unix_funcs->get_unix_codepage( &unix_table );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unix format is: lang[_country][.charset][@modifier]
|
|
||||||
* Windows format is: lang[-script][-country][_modifier] */
|
static LCID locale_to_lcid( WCHAR *win_name )
|
||||||
static LCID unix_locale_to_lcid( const char *unix_name )
|
|
||||||
{
|
{
|
||||||
static const WCHAR sepW[] = {'_','.','@',0};
|
WCHAR *p;
|
||||||
static const WCHAR posixW[] = {'P','O','S','I','X',0};
|
|
||||||
static const WCHAR cW[] = {'C',0};
|
|
||||||
static const WCHAR euroW[] = {'e','u','r','o',0};
|
|
||||||
static const WCHAR latinW[] = {'l','a','t','i','n',0};
|
|
||||||
static const WCHAR latnW[] = {'-','L','a','t','n',0};
|
|
||||||
WCHAR buffer[LOCALE_NAME_MAX_LENGTH], win_name[LOCALE_NAME_MAX_LENGTH];
|
|
||||||
WCHAR *p, *country = NULL, *modifier = NULL;
|
|
||||||
DWORD len;
|
|
||||||
LCID lcid;
|
LCID lcid;
|
||||||
|
|
||||||
if (!unix_name || !unix_name[0] || !strcmp( unix_name, "C" ))
|
|
||||||
{
|
|
||||||
unix_name = getenv( "LC_ALL" );
|
|
||||||
if (!unix_name || !unix_name[0]) return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
len = ntdll_umbstowcs( unix_name, strlen(unix_name), buffer, ARRAY_SIZE(buffer) );
|
|
||||||
if (len == ARRAY_SIZE(buffer)) return 0;
|
|
||||||
buffer[len] = 0;
|
|
||||||
|
|
||||||
if (!(p = wcspbrk( buffer, sepW )))
|
|
||||||
{
|
|
||||||
if (!wcscmp( buffer, posixW ) || !wcscmp( buffer, cW ))
|
|
||||||
return MAKELCID( MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), SORT_DEFAULT );
|
|
||||||
wcscpy( win_name, buffer );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (*p == '_')
|
|
||||||
{
|
|
||||||
*p++ = 0;
|
|
||||||
country = p;
|
|
||||||
p = wcspbrk( p, sepW + 1 );
|
|
||||||
}
|
|
||||||
if (p && *p == '.')
|
|
||||||
{
|
|
||||||
*p++ = 0;
|
|
||||||
/* charset, ignore */
|
|
||||||
p = wcschr( p, '@' );
|
|
||||||
}
|
|
||||||
if (p)
|
|
||||||
{
|
|
||||||
*p++ = 0;
|
|
||||||
modifier = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* rebuild a Windows name */
|
|
||||||
|
|
||||||
wcscpy( win_name, buffer );
|
|
||||||
if (modifier)
|
|
||||||
{
|
|
||||||
if (!wcscmp( modifier, latinW )) wcscat( win_name, latnW );
|
|
||||||
else if (!wcscmp( modifier, euroW )) {} /* ignore */
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
if (country)
|
|
||||||
{
|
|
||||||
p = win_name + wcslen(win_name);
|
|
||||||
*p++ = '-';
|
|
||||||
wcscpy( p, country );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!RtlLocaleNameToLcid( win_name, &lcid, 0 )) return lcid;
|
if (!RtlLocaleNameToLcid( win_name, &lcid, 0 )) return lcid;
|
||||||
|
|
||||||
/* try neutral name */
|
/* try neutral name */
|
||||||
if (country)
|
if ((p = wcsrchr( win_name, '-' )))
|
||||||
{
|
{
|
||||||
p[-1] = 0;
|
*p = 0;
|
||||||
if (!RtlLocaleNameToLcid( win_name, &lcid, 2 ))
|
if (!RtlLocaleNameToLcid( win_name, &lcid, 2 ))
|
||||||
{
|
{
|
||||||
if (SUBLANGID(lcid) == SUBLANG_NEUTRAL)
|
if (SUBLANGID(lcid) == SUBLANG_NEUTRAL)
|
||||||
|
@ -787,75 +719,20 @@ static LCID unix_locale_to_lcid( const char *unix_name )
|
||||||
*/
|
*/
|
||||||
void init_locale( HMODULE module )
|
void init_locale( HMODULE module )
|
||||||
{
|
{
|
||||||
|
WCHAR system_locale[LOCALE_NAME_MAX_LENGTH];
|
||||||
|
WCHAR user_locale[LOCALE_NAME_MAX_LENGTH];
|
||||||
LCID system_lcid, user_lcid;
|
LCID system_lcid, user_lcid;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
const struct norm_table *info;
|
||||||
|
load_norm_table( NormalizationC, &info );
|
||||||
|
#endif
|
||||||
|
|
||||||
kernel32_handle = module;
|
kernel32_handle = module;
|
||||||
|
|
||||||
setlocale( LC_ALL, "" );
|
unix_funcs->get_locales( system_locale, user_locale );
|
||||||
|
system_lcid = locale_to_lcid( system_locale );
|
||||||
system_lcid = unix_locale_to_lcid( setlocale( LC_CTYPE, NULL ));
|
user_lcid = locale_to_lcid( user_locale );
|
||||||
user_lcid = unix_locale_to_lcid( setlocale( LC_MESSAGES, NULL ));
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
{
|
|
||||||
const struct norm_table *info;
|
|
||||||
load_norm_table( NormalizationC, &info );
|
|
||||||
}
|
|
||||||
if (!system_lcid)
|
|
||||||
{
|
|
||||||
char buffer[LOCALE_NAME_MAX_LENGTH];
|
|
||||||
|
|
||||||
CFLocaleRef locale = CFLocaleCopyCurrent();
|
|
||||||
CFStringRef lang = CFLocaleGetValue( locale, kCFLocaleLanguageCode );
|
|
||||||
CFStringRef country = CFLocaleGetValue( locale, kCFLocaleCountryCode );
|
|
||||||
CFStringRef locale_string;
|
|
||||||
|
|
||||||
if (country)
|
|
||||||
locale_string = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@_%@"), lang, country);
|
|
||||||
else
|
|
||||||
locale_string = CFStringCreateCopy(NULL, lang);
|
|
||||||
|
|
||||||
CFStringGetCString(locale_string, buffer, sizeof(buffer), kCFStringEncodingUTF8);
|
|
||||||
system_lcid = unix_locale_to_lcid( buffer );
|
|
||||||
CFRelease(locale);
|
|
||||||
CFRelease(locale_string);
|
|
||||||
}
|
|
||||||
if (!user_lcid)
|
|
||||||
{
|
|
||||||
/* Retrieve the preferred language as chosen in System Preferences. */
|
|
||||||
char buffer[LOCALE_NAME_MAX_LENGTH];
|
|
||||||
CFArrayRef preferred_langs = CFLocaleCopyPreferredLanguages();
|
|
||||||
if (preferred_langs && CFArrayGetCount( preferred_langs ))
|
|
||||||
{
|
|
||||||
CFStringRef preferred_lang = CFArrayGetValueAtIndex( preferred_langs, 0 );
|
|
||||||
CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier( NULL, preferred_lang );
|
|
||||||
if (components)
|
|
||||||
{
|
|
||||||
CFStringRef lang = CFDictionaryGetValue( components, kCFLocaleLanguageCode );
|
|
||||||
CFStringRef country = CFDictionaryGetValue( components, kCFLocaleCountryCode );
|
|
||||||
CFLocaleRef locale = NULL;
|
|
||||||
CFStringRef locale_string;
|
|
||||||
|
|
||||||
if (!country)
|
|
||||||
{
|
|
||||||
locale = CFLocaleCopyCurrent();
|
|
||||||
country = CFLocaleGetValue( locale, kCFLocaleCountryCode );
|
|
||||||
}
|
|
||||||
if (country)
|
|
||||||
locale_string = CFStringCreateWithFormat( NULL, NULL, CFSTR("%@_%@"), lang, country );
|
|
||||||
else
|
|
||||||
locale_string = CFStringCreateCopy( NULL, lang );
|
|
||||||
CFStringGetCString( locale_string, buffer, sizeof(buffer), kCFStringEncodingUTF8 );
|
|
||||||
CFRelease( locale_string );
|
|
||||||
if (locale) CFRelease( locale );
|
|
||||||
CFRelease( components );
|
|
||||||
user_lcid = unix_locale_to_lcid( buffer );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (preferred_langs) CFRelease( preferred_langs );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!system_lcid) system_lcid = MAKELCID( MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), SORT_DEFAULT );
|
if (!system_lcid) system_lcid = MAKELCID( MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), SORT_DEFAULT );
|
||||||
if (!user_lcid) user_lcid = system_lcid;
|
if (!user_lcid) user_lcid = system_lcid;
|
||||||
|
|
||||||
|
@ -863,8 +740,6 @@ void init_locale( HMODULE module )
|
||||||
NtSetDefaultLocale( TRUE, user_lcid );
|
NtSetDefaultLocale( TRUE, user_lcid );
|
||||||
NtSetDefaultLocale( FALSE, system_lcid );
|
NtSetDefaultLocale( FALSE, system_lcid );
|
||||||
TRACE( "system=%04x user=%04x\n", system_lcid, user_lcid );
|
TRACE( "system=%04x user=%04x\n", system_lcid, user_lcid );
|
||||||
|
|
||||||
setlocale( LC_NUMERIC, "C" ); /* FIXME: oleaut32 depends on this */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,10 @@
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __APPLE__
|
||||||
|
# include <CoreFoundation/CFLocale.h>
|
||||||
|
# include <CoreFoundation/CFString.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "ntstatus.h"
|
#include "ntstatus.h"
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
|
@ -67,6 +71,8 @@ static char **main_envp;
|
||||||
static WCHAR **main_wargv;
|
static WCHAR **main_wargv;
|
||||||
|
|
||||||
static CPTABLEINFO unix_table;
|
static CPTABLEINFO unix_table;
|
||||||
|
static WCHAR system_locale[LOCALE_NAME_MAX_LENGTH];
|
||||||
|
static WCHAR user_locale[LOCALE_NAME_MAX_LENGTH];
|
||||||
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -529,12 +535,146 @@ static WCHAR **build_wargv( char **argv )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Unix format is: lang[_country][.charset][@modifier]
|
||||||
|
* Windows format is: lang[-script][-country][_modifier] */
|
||||||
|
static BOOL unix_to_win_locale( const char *unix_name, WCHAR *win_name )
|
||||||
|
{
|
||||||
|
static const WCHAR sepW[] = {'_','.','@',0};
|
||||||
|
static const WCHAR posixW[] = {'P','O','S','I','X',0};
|
||||||
|
static const WCHAR cW[] = {'C',0};
|
||||||
|
static const WCHAR euroW[] = {'e','u','r','o',0};
|
||||||
|
static const WCHAR latinW[] = {'l','a','t','i','n',0};
|
||||||
|
static const WCHAR latnW[] = {'-','L','a','t','n',0};
|
||||||
|
static const WCHAR enUSW[] = {'e','n','-','U','S',0};
|
||||||
|
WCHAR buffer[LOCALE_NAME_MAX_LENGTH];
|
||||||
|
WCHAR *p, *country = NULL, *modifier = NULL;
|
||||||
|
DWORD len;
|
||||||
|
|
||||||
|
if (!unix_name || !unix_name[0] || !strcmp( unix_name, "C" ))
|
||||||
|
{
|
||||||
|
unix_name = getenv( "LC_ALL" );
|
||||||
|
if (!unix_name || !unix_name[0]) return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ntdll_umbstowcs( unix_name, strlen(unix_name), buffer, ARRAY_SIZE(buffer) );
|
||||||
|
if (len == ARRAY_SIZE(buffer)) return FALSE;
|
||||||
|
buffer[len] = 0;
|
||||||
|
|
||||||
|
if (!(p = wcspbrk( buffer, sepW )))
|
||||||
|
{
|
||||||
|
if (!wcscmp( buffer, posixW ) || !wcscmp( buffer, cW ))
|
||||||
|
wcscpy( win_name, enUSW );
|
||||||
|
else
|
||||||
|
wcscpy( win_name, buffer );
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*p == '_')
|
||||||
|
{
|
||||||
|
*p++ = 0;
|
||||||
|
country = p;
|
||||||
|
p = wcspbrk( p, sepW + 1 );
|
||||||
|
}
|
||||||
|
if (p && *p == '.')
|
||||||
|
{
|
||||||
|
*p++ = 0;
|
||||||
|
/* charset, ignore */
|
||||||
|
p = wcschr( p, '@' );
|
||||||
|
}
|
||||||
|
if (p)
|
||||||
|
{
|
||||||
|
*p++ = 0;
|
||||||
|
modifier = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rebuild a Windows name */
|
||||||
|
|
||||||
|
wcscpy( win_name, buffer );
|
||||||
|
if (modifier)
|
||||||
|
{
|
||||||
|
if (!wcscmp( modifier, latinW )) wcscat( win_name, latnW );
|
||||||
|
else if (!wcscmp( modifier, euroW )) {} /* ignore */
|
||||||
|
else return FALSE;
|
||||||
|
}
|
||||||
|
if (country)
|
||||||
|
{
|
||||||
|
p = win_name + wcslen(win_name);
|
||||||
|
*p++ = '-';
|
||||||
|
wcscpy( p, country );
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* init_locale
|
||||||
|
*/
|
||||||
|
static void init_locale(void)
|
||||||
|
{
|
||||||
|
setlocale( LC_ALL, "" );
|
||||||
|
if (!unix_to_win_locale( setlocale( LC_CTYPE, NULL ), system_locale )) system_locale[0] = 0;
|
||||||
|
if (!unix_to_win_locale( setlocale( LC_MESSAGES, NULL ), user_locale )) user_locale[0] = 0;
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
if (!system_locale[0])
|
||||||
|
{
|
||||||
|
CFLocaleRef locale = CFLocaleCopyCurrent();
|
||||||
|
CFStringRef lang = CFLocaleGetValue( locale, kCFLocaleLanguageCode );
|
||||||
|
CFStringRef country = CFLocaleGetValue( locale, kCFLocaleCountryCode );
|
||||||
|
CFStringRef locale_string;
|
||||||
|
|
||||||
|
if (country)
|
||||||
|
locale_string = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@_%@"), lang, country);
|
||||||
|
else
|
||||||
|
locale_string = CFStringCreateCopy(NULL, lang);
|
||||||
|
|
||||||
|
CFStringGetCString(locale_string, system_locale, sizeof(system_locale), kCFStringEncodingUTF8);
|
||||||
|
CFRelease(locale);
|
||||||
|
CFRelease(locale_string);
|
||||||
|
}
|
||||||
|
if (!user_locale[0])
|
||||||
|
{
|
||||||
|
/* Retrieve the preferred language as chosen in System Preferences. */
|
||||||
|
CFArrayRef preferred_langs = CFLocaleCopyPreferredLanguages();
|
||||||
|
if (preferred_langs && CFArrayGetCount( preferred_langs ))
|
||||||
|
{
|
||||||
|
CFStringRef preferred_lang = CFArrayGetValueAtIndex( preferred_langs, 0 );
|
||||||
|
CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier( NULL, preferred_lang );
|
||||||
|
if (components)
|
||||||
|
{
|
||||||
|
CFStringRef lang = CFDictionaryGetValue( components, kCFLocaleLanguageCode );
|
||||||
|
CFStringRef country = CFDictionaryGetValue( components, kCFLocaleCountryCode );
|
||||||
|
CFLocaleRef locale = NULL;
|
||||||
|
CFStringRef locale_string;
|
||||||
|
|
||||||
|
if (!country)
|
||||||
|
{
|
||||||
|
locale = CFLocaleCopyCurrent();
|
||||||
|
country = CFLocaleGetValue( locale, kCFLocaleCountryCode );
|
||||||
|
}
|
||||||
|
if (country)
|
||||||
|
locale_string = CFStringCreateWithFormat( NULL, NULL, CFSTR("%@_%@"), lang, country );
|
||||||
|
else
|
||||||
|
locale_string = CFStringCreateCopy( NULL, lang );
|
||||||
|
CFStringGetCString( locale_string, user_locale, sizeof(user_locale), kCFStringEncodingUTF8 );
|
||||||
|
CFRelease( locale_string );
|
||||||
|
if (locale) CFRelease( locale );
|
||||||
|
CFRelease( components );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (preferred_langs) CFRelease( preferred_langs );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* init_environment
|
* init_environment
|
||||||
*/
|
*/
|
||||||
void init_environment( int argc, char *argv[], char *envp[] )
|
void init_environment( int argc, char *argv[], char *envp[] )
|
||||||
{
|
{
|
||||||
init_unix_codepage();
|
init_unix_codepage();
|
||||||
|
init_locale();
|
||||||
set_process_name( argc, argv );
|
set_process_name( argc, argv );
|
||||||
__wine_main_argc = main_argc = argc;
|
__wine_main_argc = main_argc = argc;
|
||||||
__wine_main_argv = main_argv = argv;
|
__wine_main_argv = main_argv = argv;
|
||||||
|
@ -604,3 +744,15 @@ void CDECL get_unix_codepage( CPTABLEINFO *table )
|
||||||
{
|
{
|
||||||
*table = unix_table;
|
*table = unix_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* get_locales
|
||||||
|
*
|
||||||
|
* Return the system and user locales. Buffers must be at least LOCALE_NAME_MAX_LENGTH chars long.
|
||||||
|
*/
|
||||||
|
void CDECL get_locales( WCHAR *sys, WCHAR *user )
|
||||||
|
{
|
||||||
|
wcscpy( sys, system_locale );
|
||||||
|
wcscpy( user, user_locale );
|
||||||
|
}
|
||||||
|
|
|
@ -902,6 +902,7 @@ static struct unix_funcs unix_funcs =
|
||||||
get_paths,
|
get_paths,
|
||||||
get_dll_path,
|
get_dll_path,
|
||||||
get_unix_codepage,
|
get_unix_codepage,
|
||||||
|
get_locales,
|
||||||
get_version,
|
get_version,
|
||||||
get_build_id,
|
get_build_id,
|
||||||
get_host_version,
|
get_host_version,
|
||||||
|
|
|
@ -81,6 +81,7 @@ int CDECL mmap_enum_reserved_areas( int (CDECL *enum_func)(void *base, SIZE_T s
|
||||||
extern void CDECL get_main_args( int *argc, char **argv[], char **envp[] ) DECLSPEC_HIDDEN;
|
extern void CDECL get_main_args( int *argc, char **argv[], char **envp[] ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *size ) DECLSPEC_HIDDEN;
|
extern NTSTATUS CDECL get_initial_environment( WCHAR **wargv[], WCHAR *env, SIZE_T *size ) DECLSPEC_HIDDEN;
|
||||||
extern void CDECL get_unix_codepage( CPTABLEINFO *table ) DECLSPEC_HIDDEN;
|
extern void CDECL get_unix_codepage( CPTABLEINFO *table ) DECLSPEC_HIDDEN;
|
||||||
|
extern void CDECL get_locales( WCHAR *sys, WCHAR *user ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS CDECL virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsigned short zero_bits_64, SIZE_T commit_size,
|
extern NTSTATUS CDECL virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsigned short zero_bits_64, SIZE_T commit_size,
|
||||||
const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr, ULONG alloc_type,
|
const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr, ULONG alloc_type,
|
||||||
ULONG protect, pe_image_info_t *image_info ) DECLSPEC_HIDDEN;
|
ULONG protect, pe_image_info_t *image_info ) DECLSPEC_HIDDEN;
|
||||||
|
@ -190,7 +191,35 @@ static inline WCHAR *ntdll_wcscpy( WCHAR *dst, const WCHAR *src )
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define wcslen(str) ntdll_wcslen(str)
|
static inline WCHAR *ntdll_wcscat( WCHAR *dst, const WCHAR *src )
|
||||||
|
{
|
||||||
|
ntdll_wcscpy( dst + ntdll_wcslen(dst), src );
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ntdll_wcscmp( const WCHAR *str1, const WCHAR *str2 )
|
||||||
|
{
|
||||||
|
while (*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++);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WCHAR *ntdll_wcspbrk( const WCHAR *str, const WCHAR *accept )
|
||||||
|
{
|
||||||
|
for ( ; *str; str++) if (ntdll_wcschr( accept, *str )) return (WCHAR *)(ULONG_PTR)str;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define wcslen(str) ntdll_wcslen(str)
|
||||||
#define wcscpy(dst,src) ntdll_wcscpy(dst,src)
|
#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)
|
||||||
|
|
||||||
#endif /* __NTDLL_UNIX_PRIVATE_H */
|
#endif /* __NTDLL_UNIX_PRIVATE_H */
|
||||||
|
|
|
@ -28,7 +28,7 @@ struct ldt_copy;
|
||||||
struct msghdr;
|
struct msghdr;
|
||||||
|
|
||||||
/* increment this when you change the function table */
|
/* increment this when you change the function table */
|
||||||
#define NTDLL_UNIXLIB_VERSION 39
|
#define NTDLL_UNIXLIB_VERSION 40
|
||||||
|
|
||||||
struct unix_funcs
|
struct unix_funcs
|
||||||
{
|
{
|
||||||
|
@ -175,6 +175,7 @@ struct unix_funcs
|
||||||
void (CDECL *get_paths)( const char **builddir, const char **datadir, const char **configdir );
|
void (CDECL *get_paths)( const char **builddir, const char **datadir, const char **configdir );
|
||||||
void (CDECL *get_dll_path)( const char ***paths, SIZE_T *maxlen );
|
void (CDECL *get_dll_path)( const char ***paths, SIZE_T *maxlen );
|
||||||
void (CDECL *get_unix_codepage)( CPTABLEINFO *table );
|
void (CDECL *get_unix_codepage)( CPTABLEINFO *table );
|
||||||
|
void (CDECL *get_locales)( WCHAR *sys, WCHAR *user );
|
||||||
const char * (CDECL *get_version)(void);
|
const char * (CDECL *get_version)(void);
|
||||||
const char * (CDECL *get_build_id)(void);
|
const char * (CDECL *get_build_id)(void);
|
||||||
void (CDECL *get_host_version)( const char **sysname, const char **release );
|
void (CDECL *get_host_version)( const char **sysname, const char **release );
|
||||||
|
|
Loading…
Reference in New Issue