Commit bc874585 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Reimplement the ctype functions to avoid depending on libc.

parent 716cf7d3
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include "config.h" #include "config.h"
#include "wine/port.h" #include "wine/port.h"
#include <ctype.h>
#include <limits.h> #include <limits.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
...@@ -31,9 +30,43 @@ ...@@ -31,9 +30,43 @@
#include <string.h> #include <string.h>
#include "windef.h" #include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winternl.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.@) * memchr (NTDLL.@)
*/ */
...@@ -157,6 +190,7 @@ int __cdecl NTDLL_strncmp( const char *str1, const char *str2, size_t len ) ...@@ -157,6 +190,7 @@ int __cdecl NTDLL_strncmp( const char *str1, const char *str2, size_t len )
/********************************************************************* /*********************************************************************
* strncpy (NTDLL.@) * strncpy (NTDLL.@)
*/ */
#undef strncpy
char * __cdecl NTDLL_strncpy( char *dst, const char *src, size_t len ) char * __cdecl NTDLL_strncpy( char *dst, const char *src, size_t len )
{ {
return strncpy( dst, src, len ); return strncpy( dst, src, len );
...@@ -355,7 +389,7 @@ int __cdecl NTDLL_toupper( int c ) ...@@ -355,7 +389,7 @@ int __cdecl NTDLL_toupper( int c )
*/ */
int __cdecl NTDLL_isalnum( 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 ) ...@@ -364,7 +398,7 @@ int __cdecl NTDLL_isalnum( int c )
*/ */
int __cdecl NTDLL_isalpha( 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 ) ...@@ -373,7 +407,7 @@ int __cdecl NTDLL_isalpha( int c )
*/ */
int __cdecl NTDLL_iscntrl( 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 ) ...@@ -382,7 +416,7 @@ int __cdecl NTDLL_iscntrl( int c )
*/ */
int __cdecl NTDLL_isdigit( 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 ) ...@@ -391,7 +425,7 @@ int __cdecl NTDLL_isdigit( int c )
*/ */
int __cdecl NTDLL_isgraph( 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 ) ...@@ -400,7 +434,7 @@ int __cdecl NTDLL_isgraph( int c )
*/ */
int __cdecl NTDLL_islower( 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 ) ...@@ -409,7 +443,7 @@ int __cdecl NTDLL_islower( int c )
*/ */
int __cdecl NTDLL_isprint( 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 ) ...@@ -418,7 +452,7 @@ int __cdecl NTDLL_isprint( int c )
*/ */
int __cdecl NTDLL_ispunct( 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 ) ...@@ -427,7 +461,7 @@ int __cdecl NTDLL_ispunct( int c )
*/ */
int __cdecl NTDLL_isspace( 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 ) ...@@ -436,7 +470,7 @@ int __cdecl NTDLL_isspace( int c )
*/ */
int __cdecl NTDLL_isupper( 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 ) ...@@ -445,7 +479,7 @@ int __cdecl NTDLL_isupper( int c )
*/ */
int __cdecl NTDLL_isxdigit( 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) ...@@ -472,7 +506,7 @@ int CDECL NTDLL___toascii(int c)
*/ */
int CDECL NTDLL___iscsym(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) ...@@ -481,7 +515,7 @@ int CDECL NTDLL___iscsym(int c)
*/ */
int CDECL NTDLL___iscsymf(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) ...@@ -834,10 +868,10 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
while (*format) while (*format)
{ {
if (isspace( *format )) if (NTDLL_isspace( *format ))
{ {
/* skip whitespace */ /* skip whitespace */
while ((nch != '\0') && isspace( nch )) while ((nch != '\0') && NTDLL_isspace( nch ))
nch = (consumed++, *str++); nch = (consumed++, *str++);
} }
else if (*format == '%') else if (*format == '%')
...@@ -922,7 +956,7 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap) ...@@ -922,7 +956,7 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
BOOLEAN negative = FALSE; BOOLEAN negative = FALSE;
BOOLEAN seendigit = FALSE; BOOLEAN seendigit = FALSE;
/* skip initial whitespace */ /* skip initial whitespace */
while ((nch != '\0') && isspace( nch )) while ((nch != '\0') && NTDLL_isspace( nch ))
nch = (consumed++, *str++); nch = (consumed++, *str++);
/* get sign */ /* get sign */
if (nch == '-' || nch == '+') if (nch == '-' || nch == '+')
...@@ -1008,10 +1042,10 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap) ...@@ -1008,10 +1042,10 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
char *sptr_beg = sptr; char *sptr_beg = sptr;
unsigned size = UINT_MAX; unsigned size = UINT_MAX;
/* skip initial whitespace */ /* skip initial whitespace */
while (nch != '\0' && isspace( nch )) while (nch != '\0' && NTDLL_isspace( nch ))
nch = (consumed++, *str++); nch = (consumed++, *str++);
/* read until whitespace */ /* read until whitespace */
while (width != 0 && nch != '\0' && !isspace( nch )) while (width != 0 && nch != '\0' && !NTDLL_isspace( nch ))
{ {
if (!suppress) if (!suppress)
{ {
...@@ -1037,10 +1071,10 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap) ...@@ -1037,10 +1071,10 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap)
WCHAR *sptr_beg = sptr; WCHAR *sptr_beg = sptr;
unsigned size = UINT_MAX; unsigned size = UINT_MAX;
/* skip initial whitespace */ /* skip initial whitespace */
while (nch != '\0' && isspace( nch )) while (nch != '\0' && NTDLL_isspace( nch ))
nch = (consumed++, *str++); nch = (consumed++, *str++);
/* read until whitespace */ /* read until whitespace */
while (width != 0 && nch != '\0' && !isspace( nch )) while (width != 0 && nch != '\0' && !NTDLL_isspace( nch ))
{ {
if (!suppress) if (!suppress)
{ {
...@@ -1222,7 +1256,7 @@ static int NTDLL_vsscanf( const char *str, const char *format, __ms_va_list ap) ...@@ -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, * of characters that must match the input. For example,
* to specify that a percent-sign character is to be input, * to specify that a percent-sign character is to be input,
* use %%." */ * use %%." */
while (nch != '\0' && isspace( nch )) while (nch != '\0' && NTDLL_isspace( nch ))
nch = (consumed++, *str++); nch = (consumed++, *str++);
if (nch == *format) if (nch == *format)
{ {
......
...@@ -86,6 +86,18 @@ static int (__cdecl *piswlower)(WCHAR); ...@@ -86,6 +86,18 @@ static int (__cdecl *piswlower)(WCHAR);
static int (__cdecl *piswspace)(WCHAR); static int (__cdecl *piswspace)(WCHAR);
static int (__cdecl *piswxdigit)(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) static void InitFunctionPtrs(void)
{ {
hntdll = LoadLibraryA("ntdll.dll"); hntdll = LoadLibraryA("ntdll.dll");
...@@ -138,6 +150,17 @@ static void InitFunctionPtrs(void) ...@@ -138,6 +150,17 @@ static void InitFunctionPtrs(void)
X(iswlower); X(iswlower);
X(iswspace); X(iswspace);
X(iswxdigit); 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 #undef X
} }
...@@ -1954,6 +1977,56 @@ static void test_wctype(void) ...@@ -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) START_TEST(string)
{ {
InitFunctionPtrs(); InitFunctionPtrs();
...@@ -1984,4 +2057,5 @@ START_TEST(string) ...@@ -1984,4 +2057,5 @@ START_TEST(string)
test_wcsicmp(); test_wcsicmp();
test_sscanf(); test_sscanf();
test_wctype(); test_wctype();
test_ctype();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment