Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
bc874585
Commit
bc874585
authored
Jun 29, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Reimplement the ctype functions to avoid depending on libc.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
716cf7d3
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
130 additions
and
22 deletions
+130
-22
string.c
dlls/ntdll/string.c
+56
-22
string.c
dlls/ntdll/tests/string.c
+74
-0
No files found.
dlls/ntdll/string.c
View file @
bc874585
...
...
@@ -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
)
{
...
...
dlls/ntdll/tests/string.c
View file @
bc874585
...
...
@@ -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
();
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment