msvcrt: Implement __strncnt().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a2d76cb43f
commit
60c06980cf
|
@ -3,7 +3,7 @@
|
|||
@ cdecl __iscsymf(long) ucrtbase.__iscsymf
|
||||
@ stub __iswcsym
|
||||
@ stub __iswcsymf
|
||||
@ stub __strncnt
|
||||
@ cdecl __strncnt(str long) ucrtbase.__strncnt
|
||||
@ stub __wcsncnt
|
||||
@ cdecl _isalnum_l(long ptr) ucrtbase._isalnum_l
|
||||
@ cdecl _isalpha_l(long ptr) ucrtbase._isalpha_l
|
||||
|
|
|
@ -656,7 +656,7 @@
|
|||
@ stub __set_flsgetvalue
|
||||
@ extern __setlc_active MSVCRT___setlc_active
|
||||
@ cdecl __setusermatherr(ptr) MSVCRT___setusermatherr
|
||||
@ stub __strncnt
|
||||
@ cdecl __strncnt(str long) MSVCRT___strncnt
|
||||
@ varargs __swprintf_l(ptr wstr ptr) MSVCRT___swprintf_l
|
||||
@ cdecl __sys_errlist()
|
||||
@ cdecl __sys_nerr()
|
||||
|
|
|
@ -235,6 +235,7 @@ static int (__cdecl *p__memicmp)(const char*, const char*, size_t);
|
|||
static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t,_locale_t);
|
||||
|
||||
static char* (__cdecl *p_setlocale)(int, const char*);
|
||||
static size_t (__cdecl *p___strncnt)(const char*, size_t);
|
||||
|
||||
/* make sure we use the correct errno */
|
||||
#undef errno
|
||||
|
@ -270,6 +271,7 @@ static BOOL init(void)
|
|||
SET(p__memicmp, "_memicmp");
|
||||
SET(p__memicmp_l, "_memicmp_l");
|
||||
SET(p_setlocale, "setlocale");
|
||||
SET(p___strncnt, "__strncnt");
|
||||
|
||||
SET(p_Context_Id, "?Id@Context@Concurrency@@SAIXZ");
|
||||
SET(p_CurrentScheduler_Detach, "?Detach@CurrentScheduler@Concurrency@@SAXXZ");
|
||||
|
@ -1075,6 +1077,35 @@ static void test_setlocale(void)
|
|||
ok(!ret, "got %p\n", ret);
|
||||
}
|
||||
|
||||
static void test___strncnt(void)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
const char *str;
|
||||
size_t size;
|
||||
size_t ret;
|
||||
}
|
||||
strncnt_tests[] =
|
||||
{
|
||||
{ NULL, 0, 0 },
|
||||
{ "a", 0, 0 },
|
||||
{ "a", 1, 1 },
|
||||
{ "a", 10, 1 },
|
||||
{ "abc", 1, 1 },
|
||||
};
|
||||
unsigned int i;
|
||||
size_t ret;
|
||||
|
||||
if (0) /* crashes */
|
||||
ret = p___strncnt(NULL, 1);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(strncnt_tests); ++i)
|
||||
{
|
||||
ret = p___strncnt(strncnt_tests[i].str, strncnt_tests[i].size);
|
||||
ok(ret == strncnt_tests[i].ret, "%u: unexpected return value %u.\n", i, (int)ret);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(msvcr100)
|
||||
{
|
||||
if (!init())
|
||||
|
@ -1094,4 +1125,5 @@ START_TEST(msvcr100)
|
|||
test__memicmp();
|
||||
test__memicmp_l();
|
||||
test_setlocale();
|
||||
test___strncnt();
|
||||
}
|
||||
|
|
|
@ -1004,7 +1004,7 @@
|
|||
@ cdecl __set_app_type(long) MSVCRT___set_app_type
|
||||
@ extern __setlc_active MSVCRT___setlc_active
|
||||
@ cdecl __setusermatherr(ptr) MSVCRT___setusermatherr
|
||||
@ stub __strncnt
|
||||
@ cdecl __strncnt(str long) MSVCRT___strncnt
|
||||
@ varargs __swprintf_l(ptr wstr ptr) MSVCRT___swprintf_l
|
||||
@ cdecl __sys_errlist()
|
||||
@ cdecl __sys_nerr()
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <locale.h>
|
||||
|
||||
static char* (CDECL *p_setlocale)(int category, const char* locale);
|
||||
static size_t (CDECL *p___strncnt)(const char *str, size_t count);
|
||||
|
||||
static unsigned int (CDECL *p_CurrentScheduler_GetNumberOfVirtualProcessors)(void);
|
||||
static unsigned int (CDECL *p__CurrentScheduler__GetNumberOfVirtualProcessors)(void);
|
||||
|
@ -50,6 +51,7 @@ static BOOL init(void)
|
|||
}
|
||||
|
||||
p_setlocale = (void*)GetProcAddress(module, "setlocale");
|
||||
p___strncnt = (void*)GetProcAddress(module, "__strncnt");
|
||||
p_CurrentScheduler_GetNumberOfVirtualProcessors = (void*)GetProcAddress(module, "?GetNumberOfVirtualProcessors@CurrentScheduler@Concurrency@@SAIXZ");
|
||||
p__CurrentScheduler__GetNumberOfVirtualProcessors = (void*)GetProcAddress(module, "?_GetNumberOfVirtualProcessors@_CurrentScheduler@details@Concurrency@@SAIXZ");
|
||||
p_CurrentScheduler_Id = (void*)GetProcAddress(module, "?Id@CurrentScheduler@Concurrency@@SAIXZ");
|
||||
|
@ -112,9 +114,39 @@ static void test_setlocale(void)
|
|||
p_setlocale(LC_ALL, "C");
|
||||
}
|
||||
|
||||
static void test___strncnt(void)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
const char *str;
|
||||
size_t size;
|
||||
size_t ret;
|
||||
}
|
||||
strncnt_tests[] =
|
||||
{
|
||||
{ NULL, 0, 0 },
|
||||
{ "a", 0, 0 },
|
||||
{ "a", 1, 1 },
|
||||
{ "a", 10, 1 },
|
||||
{ "abc", 1, 1 },
|
||||
};
|
||||
unsigned int i;
|
||||
size_t ret;
|
||||
|
||||
if (0) /* crashes */
|
||||
ret = p___strncnt(NULL, 1);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(strncnt_tests); ++i)
|
||||
{
|
||||
ret = p___strncnt(strncnt_tests[i].str, strncnt_tests[i].size);
|
||||
ok(ret == strncnt_tests[i].ret, "%u: unexpected return value %u.\n", i, (int)ret);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(msvcr110)
|
||||
{
|
||||
if (!init()) return;
|
||||
test_CurrentScheduler(); /* MUST be first (at least among Concurrency tests) */
|
||||
test_setlocale();
|
||||
test___strncnt();
|
||||
}
|
||||
|
|
|
@ -994,7 +994,7 @@
|
|||
@ cdecl __set_app_type(long) MSVCRT___set_app_type
|
||||
@ extern __setlc_active MSVCRT___setlc_active
|
||||
@ cdecl __setusermatherr(ptr) MSVCRT___setusermatherr
|
||||
@ stub __strncnt
|
||||
@ cdecl __strncnt(str long) MSVCRT___strncnt
|
||||
@ varargs __swprintf_l(ptr wstr ptr) MSVCRT___swprintf_l
|
||||
@ cdecl __sys_errlist()
|
||||
@ cdecl __sys_nerr()
|
||||
|
|
|
@ -965,7 +965,7 @@
|
|||
@ stub __report_gsfailure
|
||||
@ extern __setlc_active msvcr120.__setlc_active
|
||||
@ cdecl __setusermatherr(ptr) msvcr120.__setusermatherr
|
||||
@ stub __strncnt
|
||||
@ cdecl __strncnt(str long) msvcr120.__strncnt
|
||||
@ varargs __swprintf_l(ptr wstr ptr) msvcr120.__swprintf_l
|
||||
@ cdecl __sys_errlist() msvcr120.__sys_errlist
|
||||
@ cdecl __sys_nerr() msvcr120.__sys_nerr
|
||||
|
|
|
@ -305,7 +305,7 @@
|
|||
@ stub __set_flsgetvalue
|
||||
@ extern __setlc_active MSVCRT___setlc_active
|
||||
@ cdecl __setusermatherr(ptr) MSVCRT___setusermatherr
|
||||
@ stub __strncnt
|
||||
@ cdecl __strncnt(str long) MSVCRT___strncnt
|
||||
@ varargs __swprintf_l(ptr wstr ptr) MSVCRT___swprintf_l
|
||||
@ cdecl __sys_errlist()
|
||||
@ cdecl __sys_nerr()
|
||||
|
|
|
@ -289,7 +289,7 @@
|
|||
@ stub __set_flsgetvalue
|
||||
@ extern __setlc_active MSVCRT___setlc_active
|
||||
@ cdecl __setusermatherr(ptr) MSVCRT___setusermatherr
|
||||
@ stub __strncnt
|
||||
@ cdecl __strncnt(str long) MSVCRT___strncnt
|
||||
@ varargs __swprintf_l(ptr wstr ptr) MSVCRT___swprintf_l
|
||||
@ cdecl __sys_errlist()
|
||||
@ cdecl __sys_nerr()
|
||||
|
|
|
@ -134,6 +134,7 @@ static int (__cdecl *p__fpieee_flt)(ULONG, EXCEPTION_POINTERS*, int (__cdecl *ha
|
|||
static int (__cdecl *p__memicmp)(const char*, const char*, size_t);
|
||||
static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t, _locale_t);
|
||||
static int (__cdecl *p__vsnwprintf)(wchar_t *buffer,size_t count, const wchar_t *format, __ms_va_list valist);
|
||||
static size_t (__cdecl *p___strncnt)(const char *str, size_t count);
|
||||
|
||||
/* make sure we use the correct errno */
|
||||
#undef errno
|
||||
|
@ -403,6 +404,7 @@ static BOOL init(void)
|
|||
SET(p__memicmp, "_memicmp");
|
||||
SET(p__memicmp_l, "_memicmp_l");
|
||||
SET(p__vsnwprintf, "_vsnwprintf");
|
||||
SET(p___strncnt, "__strncnt");
|
||||
|
||||
if (sizeof(void *) == 8)
|
||||
{
|
||||
|
@ -1894,6 +1896,35 @@ static void test__vsnwprintf(void)
|
|||
ok(p_set_invalid_parameter_handler(old_handler) == test_invalid_parameter_handler, "Cannot reset invalid parameter handler\n");
|
||||
}
|
||||
|
||||
static void test___strncnt(void)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
const char *str;
|
||||
size_t size;
|
||||
size_t ret;
|
||||
}
|
||||
strncnt_tests[] =
|
||||
{
|
||||
{ NULL, 0, 0 },
|
||||
{ "a", 0, 0 },
|
||||
{ "a", 1, 1 },
|
||||
{ "a", 10, 1 },
|
||||
{ "abc", 1, 1 },
|
||||
};
|
||||
unsigned int i;
|
||||
size_t ret;
|
||||
|
||||
if (0)
|
||||
ret = p___strncnt(NULL, 1);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(strncnt_tests); ++i)
|
||||
{
|
||||
ret = p___strncnt(strncnt_tests[i].str, strncnt_tests[i].size);
|
||||
ok(ret == strncnt_tests[i].ret, "%u: unexpected return value %u.\n", i, (int)ret);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(msvcr90)
|
||||
{
|
||||
if(!init())
|
||||
|
@ -1931,4 +1962,5 @@ START_TEST(msvcr90)
|
|||
#ifdef __i386__
|
||||
test__fpieee_flt();
|
||||
#endif
|
||||
test___strncnt();
|
||||
}
|
||||
|
|
|
@ -281,7 +281,7 @@
|
|||
@ cdecl __set_app_type(long) MSVCRT___set_app_type
|
||||
@ extern __setlc_active MSVCRT___setlc_active
|
||||
@ cdecl __setusermatherr(ptr) MSVCRT___setusermatherr
|
||||
# stub __strncnt(str long)
|
||||
@ cdecl __strncnt(str long) MSVCRT___strncnt
|
||||
@ cdecl __threadhandle() kernel32.GetCurrentThread
|
||||
@ cdecl __threadid() kernel32.GetCurrentThreadId
|
||||
@ cdecl __toascii(long) MSVCRT___toascii
|
||||
|
|
|
@ -2060,3 +2060,22 @@ char* __cdecl MSVCRT_strpbrk(const char *str, const char *accept)
|
|||
{
|
||||
return strpbrk(str, accept);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* __strncnt (MSVCRT.@)
|
||||
*/
|
||||
MSVCRT_size_t __cdecl MSVCRT___strncnt(const char *str, MSVCRT_size_t size)
|
||||
{
|
||||
MSVCRT_size_t ret = 0;
|
||||
|
||||
#if _MSVCR_VER >= 140
|
||||
while (*str++ && size--)
|
||||
#else
|
||||
while (size-- && *str++)
|
||||
#endif
|
||||
{
|
||||
ret++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@ static size_t (__cdecl *p__mbsnlen)(const unsigned char*, size_t);
|
|||
static int (__cdecl *p__mbccpy_s)(unsigned char*, size_t, int*, const unsigned char*);
|
||||
static int (__cdecl *p__memicmp)(const char*, const char*, size_t);
|
||||
static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t, _locale_t);
|
||||
static size_t (__cdecl *p___strncnt)(const char*, size_t);
|
||||
|
||||
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y)
|
||||
#define SET(x,y) SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y)
|
||||
|
@ -3568,6 +3569,41 @@ static void test__tcsnicoll(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void test___strncnt(void)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
const char *str;
|
||||
size_t size;
|
||||
size_t ret;
|
||||
}
|
||||
strncnt_tests[] =
|
||||
{
|
||||
{ NULL, 0, 0 },
|
||||
{ "a", 0, 0 },
|
||||
{ "a", 1, 1 },
|
||||
{ "a", 10, 1 },
|
||||
{ "abc", 1, 1 },
|
||||
};
|
||||
unsigned int i;
|
||||
size_t ret;
|
||||
|
||||
if (!p___strncnt)
|
||||
{
|
||||
win_skip("__strncnt() is not available.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (0) /* crashes */
|
||||
ret = p___strncnt(NULL, 1);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(strncnt_tests); ++i)
|
||||
{
|
||||
ret = p___strncnt(strncnt_tests[i].str, strncnt_tests[i].size);
|
||||
ok(ret == strncnt_tests[i].ret, "%u: unexpected return value %u.\n", i, (int)ret);
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST(string)
|
||||
{
|
||||
char mem[100];
|
||||
|
@ -3626,6 +3662,7 @@ START_TEST(string)
|
|||
p__mbccpy_s = (void*)GetProcAddress(hMsvcrt, "_mbccpy_s");
|
||||
p__memicmp = (void*)GetProcAddress(hMsvcrt, "_memicmp");
|
||||
p__memicmp_l = (void*)GetProcAddress(hMsvcrt, "_memicmp_l");
|
||||
p___strncnt = (void*)GetProcAddress(hMsvcrt, "__strncnt");
|
||||
|
||||
/* MSVCRT memcpy behaves like memmove for overlapping moves,
|
||||
MFC42 CString::Insert seems to rely on that behaviour */
|
||||
|
@ -3693,4 +3730,5 @@ START_TEST(string)
|
|||
test__strupr();
|
||||
test__tcsncoll();
|
||||
test__tcsnicoll();
|
||||
test___strncnt();
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@ static void __cdecl test_invalid_parameter_handler(const wchar_t *expression,
|
|||
static double (__cdecl *p_strtod)(const char*, char** end);
|
||||
static int (__cdecl *p__memicmp)(const char*, const char*, size_t);
|
||||
static int (__cdecl *p__memicmp_l)(const char*, const char*, size_t,_locale_t);
|
||||
static size_t (__cdecl *p___strncnt)(const char*, size_t);
|
||||
|
||||
static BOOL init(void)
|
||||
{
|
||||
|
@ -105,6 +106,7 @@ static BOOL init(void)
|
|||
p_strtod = (void*)GetProcAddress(module, "strtod");
|
||||
p__memicmp = (void*)GetProcAddress(module, "_memicmp");
|
||||
p__memicmp_l = (void*)GetProcAddress(module, "_memicmp_l");
|
||||
p___strncnt = (void*)GetProcAddress(module, "__strncnt");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -244,10 +246,50 @@ static void test__memicmp_l(void)
|
|||
ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
|
||||
"Cannot reset invalid parameter handler\n");
|
||||
}
|
||||
|
||||
|
||||
static void test___strncnt(void)
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
const char *str;
|
||||
size_t size;
|
||||
size_t ret;
|
||||
}
|
||||
strncnt_tests[] =
|
||||
{
|
||||
{ "a", 0, 0 },
|
||||
{ "a", 1, 1 },
|
||||
{ "a", 10, 1 },
|
||||
{ "abc", 1, 1 },
|
||||
};
|
||||
unsigned int i;
|
||||
size_t ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(strncnt_tests); ++i)
|
||||
{
|
||||
ret = p___strncnt(strncnt_tests[i].str, strncnt_tests[i].size);
|
||||
ok(ret == strncnt_tests[i].ret, "%u: unexpected return value %u.\n", i, (int)ret);
|
||||
}
|
||||
|
||||
ok(p_set_invalid_parameter_handler(test_invalid_parameter_handler) == NULL,
|
||||
"Invalid parameter handler was already set\n");
|
||||
|
||||
if (0) /* crashes */
|
||||
{
|
||||
ret = p___strncnt(NULL, 0);
|
||||
ret = p___strncnt(NULL, 1);
|
||||
}
|
||||
|
||||
ok(p_set_invalid_parameter_handler(NULL) == test_invalid_parameter_handler,
|
||||
"Cannot reset invalid parameter handler\n");
|
||||
}
|
||||
|
||||
START_TEST(string)
|
||||
{
|
||||
if (!init()) return;
|
||||
test_strtod();
|
||||
test__memicmp();
|
||||
test__memicmp_l();
|
||||
test___strncnt();
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@
|
|||
@ cdecl __stdio_common_vswprintf_p(int64 ptr long wstr ptr ptr) MSVCRT__stdio_common_vswprintf_p
|
||||
@ cdecl __stdio_common_vswprintf_s(int64 ptr long wstr ptr ptr) MSVCRT__stdio_common_vswprintf_s
|
||||
@ cdecl __stdio_common_vswscanf(int64 ptr long wstr ptr ptr) MSVCRT__stdio_common_vswscanf
|
||||
@ stub __strncnt
|
||||
@ cdecl __strncnt(str long) MSVCRT___strncnt
|
||||
@ cdecl __sys_errlist()
|
||||
@ cdecl __sys_nerr()
|
||||
@ cdecl __threadhandle() kernel32.GetCurrentThread
|
||||
|
|
Loading…
Reference in New Issue