ntdll: Reimplement the ctype functions to avoid depending on libc.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
716cf7d342
commit
bc8745851e
|
@ -23,7 +23,6 @@
|
|||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -31,9 +30,43 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winnls.h"
|
||||
#include "winternl.h"
|
||||
|
||||
|
||||
/* same as wctypes except for TAB, which doesn't have C1_BLANK for some reason... */
|
||||
static const unsigned short ctypes[257] =
|
||||
{
|
||||
/* -1 */
|
||||
0x0000,
|
||||
/* 00 */
|
||||
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
|
||||
0x0020, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0020, 0x0020,
|
||||
/* 10 */
|
||||
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
|
||||
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
|
||||
/* 20 */
|
||||
0x0048, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
|
||||
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
|
||||
/* 30 */
|
||||
0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084,
|
||||
0x0084, 0x0084, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
|
||||
/* 40 */
|
||||
0x0010, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0101,
|
||||
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
|
||||
/* 50 */
|
||||
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
|
||||
0x0101, 0x0101, 0x0101, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
|
||||
/* 60 */
|
||||
0x0010, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0102,
|
||||
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
|
||||
/* 70 */
|
||||
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
|
||||
0x0102, 0x0102, 0x0102, 0x0010, 0x0010, 0x0010, 0x0010, 0x0020
|
||||
};
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* memchr (NTDLL.@)
|
||||
*/
|
||||
|
@ -157,6 +190,7 @@ int __cdecl NTDLL_strncmp( const char *str1, const char *str2, size_t len )
|
|||
/*********************************************************************
|
||||
* strncpy (NTDLL.@)
|
||||
*/
|
||||
#undef strncpy
|
||||
char * __cdecl NTDLL_strncpy( char *dst, const char *src, size_t len )
|
||||
{
|
||||
return strncpy( dst, src, len );
|
||||
|
@ -355,7 +389,7 @@ int __cdecl NTDLL_toupper( int c )
|
|||
*/
|
||||
int __cdecl NTDLL_isalnum( int c )
|
||||
{
|
||||
return isalnum( c );
|
||||
return ctypes[c + 1] & (C1_LOWER | C1_UPPER | C1_DIGIT);
|
||||
}
|
||||
|
||||
|
||||
|
@ -364,7 +398,7 @@ int __cdecl NTDLL_isalnum( int c )
|
|||
*/
|
||||
int __cdecl NTDLL_isalpha( int c )
|
||||
{
|
||||
return isalpha( c );
|
||||
return ctypes[c + 1] & (C1_LOWER | C1_UPPER);
|
||||
}
|
||||
|
||||
|
||||
|
@ -373,7 +407,7 @@ int __cdecl NTDLL_isalpha( int c )
|
|||
*/
|
||||
int __cdecl NTDLL_iscntrl( int c )
|
||||
{
|
||||
return iscntrl( c );
|
||||
return ctypes[c + 1] & C1_CNTRL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -382,7 +416,7 @@ int __cdecl NTDLL_iscntrl( int c )
|
|||
*/
|
||||
int __cdecl NTDLL_isdigit( int c )
|
||||
{
|
||||
return isdigit( c );
|
||||
return ctypes[c + 1] & C1_DIGIT;
|
||||
}
|
||||
|
||||
|
||||
|
@ -391,7 +425,7 @@ int __cdecl NTDLL_isdigit( int c )
|
|||
*/
|
||||
int __cdecl NTDLL_isgraph( int c )
|
||||
{
|
||||
return isgraph( c );
|
||||
return ctypes[c + 1] & (C1_LOWER | C1_UPPER | C1_DIGIT | C1_PUNCT);
|
||||
}
|
||||
|
||||
|
||||
|
@ -400,7 +434,7 @@ int __cdecl NTDLL_isgraph( int c )
|
|||
*/
|
||||
int __cdecl NTDLL_islower( int c )
|
||||
{
|
||||
return islower( c );
|
||||
return ctypes[c + 1] & C1_LOWER;
|
||||
}
|
||||
|
||||
|
||||
|
@ -409,7 +443,7 @@ int __cdecl NTDLL_islower( int c )
|
|||
*/
|
||||
int __cdecl NTDLL_isprint( int c )
|
||||
{
|
||||
return isprint( c );
|
||||
return ctypes[c + 1] & (C1_LOWER | C1_UPPER | C1_DIGIT | C1_PUNCT | C1_BLANK);
|
||||
}
|
||||
|
||||
|
||||
|
@ -418,7 +452,7 @@ int __cdecl NTDLL_isprint( int c )
|
|||
*/
|
||||
int __cdecl NTDLL_ispunct( int c )
|
||||
{
|
||||
return ispunct( c );
|
||||
return ctypes[c + 1] & C1_PUNCT;
|
||||
}
|
||||
|
||||
|
||||
|
@ -427,7 +461,7 @@ int __cdecl NTDLL_ispunct( int c )
|
|||
*/
|
||||
int __cdecl NTDLL_isspace( int c )
|
||||
{
|
||||
return isspace( c );
|
||||
return ctypes[c + 1] & C1_SPACE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -436,7 +470,7 @@ int __cdecl NTDLL_isspace( int c )
|
|||
*/
|
||||
int __cdecl NTDLL_isupper( int c )
|
||||
{
|
||||
return isupper( c );
|
||||
return ctypes[c + 1] & C1_UPPER;
|
||||
}
|
||||
|
||||
|
||||
|
@ -445,7 +479,7 @@ int __cdecl NTDLL_isupper( int c )
|
|||
*/
|
||||
int __cdecl NTDLL_isxdigit( int c )
|
||||
{
|
||||
return isxdigit( c );
|
||||
return ctypes[c + 1] & C1_XDIGIT;
|
||||
}
|
||||
|
||||
|
||||
|
@ -472,7 +506,7 @@ int CDECL NTDLL___toascii(int c)
|
|||
*/
|
||||
int CDECL NTDLL___iscsym(int c)
|
||||
{
|
||||
return (c < 127 && (isalnum(c) || c == '_'));
|
||||
return (c < 127 && (NTDLL_isalnum(c) || c == '_'));
|
||||
}
|
||||
|
||||
|
||||
|
@ -481,7 +515,7 @@ int CDECL NTDLL___iscsym(int c)
|
|||
*/
|
||||
int CDECL NTDLL___iscsymf(int c)
|
||||
{
|
||||
return (c < 127 && (isalpha(c) || c == '_'));
|
||||
return (c < 127 && (NTDLL_isalpha(c) || c == '_'));
|
||||
}
|
||||
|
||||
|
||||
|
@ -834,10 +868,10 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
|
|||
|
||||
while (*format)
|
||||
{
|
||||
if (isspace( *format ))
|
||||
if (NTDLL_isspace( *format ))
|
||||
{
|
||||
/* skip whitespace */
|
||||
while ((nch != '\0') && isspace( nch ))
|
||||
while ((nch != '\0') && NTDLL_isspace( nch ))
|
||||
nch = (consumed++, *str++);
|
||||
}
|
||||
else if (*format == '%')
|
||||
|
@ -922,7 +956,7 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
|
|||
BOOLEAN negative = FALSE;
|
||||
BOOLEAN seendigit = FALSE;
|
||||
/* skip initial whitespace */
|
||||
while ((nch != '\0') && isspace( nch ))
|
||||
while ((nch != '\0') && NTDLL_isspace( nch ))
|
||||
nch = (consumed++, *str++);
|
||||
/* get sign */
|
||||
if (nch == '-' || nch == '+')
|
||||
|
@ -1008,10 +1042,10 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
|
|||
char *sptr_beg = sptr;
|
||||
unsigned size = UINT_MAX;
|
||||
/* skip initial whitespace */
|
||||
while (nch != '\0' && isspace( nch ))
|
||||
while (nch != '\0' && NTDLL_isspace( nch ))
|
||||
nch = (consumed++, *str++);
|
||||
/* read until whitespace */
|
||||
while (width != 0 && nch != '\0' && !isspace( nch ))
|
||||
while (width != 0 && nch != '\0' && !NTDLL_isspace( nch ))
|
||||
{
|
||||
if (!suppress)
|
||||
{
|
||||
|
@ -1037,10 +1071,10 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
|
|||
WCHAR *sptr_beg = sptr;
|
||||
unsigned size = UINT_MAX;
|
||||
/* skip initial whitespace */
|
||||
while (nch != '\0' && isspace( nch ))
|
||||
while (nch != '\0' && NTDLL_isspace( nch ))
|
||||
nch = (consumed++, *str++);
|
||||
/* read until whitespace */
|
||||
while (width != 0 && nch != '\0' && !isspace( nch ))
|
||||
while (width != 0 && nch != '\0' && !NTDLL_isspace( nch ))
|
||||
{
|
||||
if (!suppress)
|
||||
{
|
||||
|
@ -1222,7 +1256,7 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
|
|||
* of characters that must match the input. For example,
|
||||
* to specify that a percent-sign character is to be input,
|
||||
* use %%." */
|
||||
while (nch != '\0' && isspace( nch ))
|
||||
while (nch != '\0' && NTDLL_isspace( nch ))
|
||||
nch = (consumed++, *str++);
|
||||
if (nch == *format)
|
||||
{
|
||||
|
|
|
@ -86,6 +86,18 @@ static int (__cdecl *piswlower)(WCHAR);
|
|||
static int (__cdecl *piswspace)(WCHAR);
|
||||
static int (__cdecl *piswxdigit)(WCHAR);
|
||||
|
||||
static int (__cdecl *pisalnum)(int);
|
||||
static int (__cdecl *pisalpha)(int);
|
||||
static int (__cdecl *piscntrl)(int);
|
||||
static int (__cdecl *pisdigit)(int);
|
||||
static int (__cdecl *pisgraph)(int);
|
||||
static int (__cdecl *pislower)(int);
|
||||
static int (__cdecl *pisprint)(int);
|
||||
static int (__cdecl *pispunct)(int);
|
||||
static int (__cdecl *pisspace)(int);
|
||||
static int (__cdecl *pisupper)(int);
|
||||
static int (__cdecl *pisxdigit)(int);
|
||||
|
||||
static void InitFunctionPtrs(void)
|
||||
{
|
||||
hntdll = LoadLibraryA("ntdll.dll");
|
||||
|
@ -138,6 +150,17 @@ static void InitFunctionPtrs(void)
|
|||
X(iswlower);
|
||||
X(iswspace);
|
||||
X(iswxdigit);
|
||||
X(isalnum);
|
||||
X(isalpha);
|
||||
X(iscntrl);
|
||||
X(isdigit);
|
||||
X(isgraph);
|
||||
X(islower);
|
||||
X(isprint);
|
||||
X(ispunct);
|
||||
X(isspace);
|
||||
X(isupper);
|
||||
X(isxdigit);
|
||||
#undef X
|
||||
}
|
||||
|
||||
|
@ -1954,6 +1977,56 @@ static void test_wctype(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* we could reuse wctypes except for TAB, which doesn't have C1_BLANK for some reason... */
|
||||
static const unsigned short ctypes[256] =
|
||||
{
|
||||
/* 00 */
|
||||
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
|
||||
0x0020, 0x0028, 0x0028, 0x0028, 0x0028, 0x0028, 0x0020, 0x0020,
|
||||
/* 10 */
|
||||
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
|
||||
0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
|
||||
/* 20 */
|
||||
0x0048, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
|
||||
0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
|
||||
/* 30 */
|
||||
0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084, 0x0084,
|
||||
0x0084, 0x0084, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
|
||||
/* 40 */
|
||||
0x0010, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0181, 0x0101,
|
||||
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
|
||||
/* 50 */
|
||||
0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101,
|
||||
0x0101, 0x0101, 0x0101, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
|
||||
/* 60 */
|
||||
0x0010, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0182, 0x0102,
|
||||
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
|
||||
/* 70 */
|
||||
0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102, 0x0102,
|
||||
0x0102, 0x0102, 0x0102, 0x0010, 0x0010, 0x0010, 0x0010, 0x0020
|
||||
};
|
||||
|
||||
static void test_ctype(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = -1; i < 256; i++)
|
||||
{
|
||||
unsigned short type = (i >= 0 ? ctypes[i] : 0);
|
||||
ok( pisalnum( i ) == (type & (C1_DIGIT|C1_LOWER|C1_UPPER)), "%u: wrong isalnum %x / %x\n", i, pisalnum(i), type );
|
||||
ok( pisalpha( i ) == (type & (C1_LOWER|C1_UPPER)), "%u: wrong isalpha %x / %x\n", i, pisalpha(i), type );
|
||||
ok( piscntrl( i ) == (type & C1_CNTRL), "%u: wrong iscntrl %x / %x\n", i, piscntrl( i ), type );
|
||||
ok( pisdigit( i ) == (type & C1_DIGIT), "%u: wrong isdigit %x / %x\n", i, pisdigit( i ), type );
|
||||
ok( pisgraph( i ) == (type & (C1_DIGIT|C1_PUNCT|C1_LOWER|C1_UPPER)), "%u: wrong isgraph %x / %x\n", i, pisgraph( i ), type );
|
||||
ok( pislower( i ) == (type & C1_LOWER), "%u: wrong islower %x / %x\n", i, pislower( i ), type );
|
||||
ok( pisprint( i ) == (type & (C1_DIGIT|C1_BLANK|C1_PUNCT|C1_LOWER|C1_UPPER)), "%u: wrong isprint %x / %x\n", i, pisprint( i ), type );
|
||||
ok( pispunct( i ) == (type & C1_PUNCT), "%u: wrong ispunct %x / %x\n", i, pispunct( i ), type );
|
||||
ok( pisspace( i ) == (type & C1_SPACE), "%u: wrong isspace %x / %x\n", i, pisspace( i ), type );
|
||||
ok( pisupper( i ) == (type & C1_UPPER), "%u: wrong isupper %x / %x\n", i, pisupper( i ), type );
|
||||
ok( pisxdigit( i ) == (type & C1_XDIGIT), "%u: wrong isxdigit %x / %x\n", i, pisxdigit( i ), type );
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(string)
|
||||
{
|
||||
InitFunctionPtrs();
|
||||
|
@ -1984,4 +2057,5 @@ START_TEST(string)
|
|||
test_wcsicmp();
|
||||
test_sscanf();
|
||||
test_wctype();
|
||||
test_ctype();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue