diff --git a/dlls/ntdll/string.c b/dlls/ntdll/string.c index 709f0ebdbd4..96dda5ffeed 100644 --- a/dlls/ntdll/string.c +++ b/dlls/ntdll/string.c @@ -23,7 +23,6 @@ #include "config.h" #include "wine/port.h" -#include #include #include #include @@ -31,9 +30,43 @@ #include #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) { diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c index 21d2b4511e4..cade4e45339 100644 --- a/dlls/ntdll/tests/string.c +++ b/dlls/ntdll/tests/string.c @@ -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(); }