Commit cada88a6 authored by Daniel Lehman's avatar Daniel Lehman Committed by Alexandre Julliard

msvcrt: Add _lfind_s.

parent 5ac02423
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
@ cdecl _byteswap_ulong(long) ucrtbase._byteswap_ulong @ cdecl _byteswap_ulong(long) ucrtbase._byteswap_ulong
@ cdecl _byteswap_ushort(long) ucrtbase._byteswap_ushort @ cdecl _byteswap_ushort(long) ucrtbase._byteswap_ushort
@ cdecl _lfind(ptr ptr ptr long ptr) ucrtbase._lfind @ cdecl _lfind(ptr ptr ptr long ptr) ucrtbase._lfind
@ stub _lfind_s @ cdecl _lfind_s(ptr ptr ptr long ptr ptr) ucrtbase._lfind_s
@ cdecl _lrotl(long long) ucrtbase._lrotl @ cdecl _lrotl(long long) ucrtbase._lrotl
@ cdecl _lrotr(long long) ucrtbase._lrotr @ cdecl _lrotr(long long) ucrtbase._lrotr
@ cdecl _lsearch(ptr ptr ptr long ptr) ucrtbase._lsearch @ cdecl _lsearch(ptr ptr ptr long ptr) ucrtbase._lsearch
......
...@@ -1040,7 +1040,7 @@ ...@@ -1040,7 +1040,7 @@
@ cdecl _jn(long double) MSVCRT__jn @ cdecl _jn(long double) MSVCRT__jn
@ cdecl _kbhit() @ cdecl _kbhit()
@ cdecl _lfind(ptr ptr ptr long ptr) @ cdecl _lfind(ptr ptr ptr long ptr)
@ stub _lfind_s @ cdecl _lfind_s(ptr ptr ptr long ptr ptr)
@ cdecl _loaddll(str) @ cdecl _loaddll(str)
@ cdecl -arch=x86_64 _local_unwind(ptr ptr) @ cdecl -arch=x86_64 _local_unwind(ptr ptr)
@ cdecl -arch=i386 _local_unwind2(ptr long) @ cdecl -arch=i386 _local_unwind2(ptr long)
......
...@@ -1386,7 +1386,7 @@ ...@@ -1386,7 +1386,7 @@
@ cdecl _jn(long double) MSVCRT__jn @ cdecl _jn(long double) MSVCRT__jn
@ cdecl _kbhit() @ cdecl _kbhit()
@ cdecl _lfind(ptr ptr ptr long ptr) @ cdecl _lfind(ptr ptr ptr long ptr)
@ stub _lfind_s @ cdecl _lfind_s(ptr ptr ptr long ptr ptr)
@ cdecl -arch=i386 _libm_sse2_acos_precise() MSVCRT___libm_sse2_acos @ cdecl -arch=i386 _libm_sse2_acos_precise() MSVCRT___libm_sse2_acos
@ cdecl -arch=i386 _libm_sse2_asin_precise() MSVCRT___libm_sse2_asin @ cdecl -arch=i386 _libm_sse2_asin_precise() MSVCRT___libm_sse2_asin
@ cdecl -arch=i386 _libm_sse2_atan_precise() MSVCRT___libm_sse2_atan @ cdecl -arch=i386 _libm_sse2_atan_precise() MSVCRT___libm_sse2_atan
......
...@@ -1396,7 +1396,7 @@ ...@@ -1396,7 +1396,7 @@
@ cdecl _ldsign(double) MSVCR120__dsign @ cdecl _ldsign(double) MSVCR120__dsign
@ cdecl _ldtest(ptr) MSVCR120__ldtest @ cdecl _ldtest(ptr) MSVCR120__ldtest
@ cdecl _lfind(ptr ptr ptr long ptr) @ cdecl _lfind(ptr ptr ptr long ptr)
@ stub _lfind_s @ cdecl _lfind_s(ptr ptr ptr long ptr ptr)
@ cdecl -arch=i386 _libm_sse2_acos_precise() MSVCRT___libm_sse2_acos @ cdecl -arch=i386 _libm_sse2_acos_precise() MSVCRT___libm_sse2_acos
@ cdecl -arch=i386 _libm_sse2_asin_precise() MSVCRT___libm_sse2_asin @ cdecl -arch=i386 _libm_sse2_asin_precise() MSVCRT___libm_sse2_asin
@ cdecl -arch=i386 _libm_sse2_atan_precise() MSVCRT___libm_sse2_atan @ cdecl -arch=i386 _libm_sse2_atan_precise() MSVCRT___libm_sse2_atan
......
...@@ -1260,7 +1260,7 @@ ...@@ -1260,7 +1260,7 @@
@ cdecl _ldsign(double) msvcr120._ldsign @ cdecl _ldsign(double) msvcr120._ldsign
@ cdecl _ldtest(ptr) msvcr120._ldtest @ cdecl _ldtest(ptr) msvcr120._ldtest
@ cdecl _lfind(ptr ptr ptr long ptr) msvcr120._lfind @ cdecl _lfind(ptr ptr ptr long ptr) msvcr120._lfind
@ stub _lfind_s @ cdecl _lfind_s(ptr ptr ptr long ptr ptr) msvcr120._lfind_s
@ cdecl -arch=i386 _libm_sse2_acos_precise() msvcr120._libm_sse2_acos_precise @ cdecl -arch=i386 _libm_sse2_acos_precise() msvcr120._libm_sse2_acos_precise
@ cdecl -arch=i386 _libm_sse2_asin_precise() msvcr120._libm_sse2_asin_precise @ cdecl -arch=i386 _libm_sse2_asin_precise() msvcr120._libm_sse2_asin_precise
@ cdecl -arch=i386 _libm_sse2_atan_precise() msvcr120._libm_sse2_atan_precise @ cdecl -arch=i386 _libm_sse2_atan_precise() msvcr120._libm_sse2_atan_precise
......
...@@ -712,7 +712,7 @@ ...@@ -712,7 +712,7 @@
@ cdecl _jn(long double) MSVCRT__jn @ cdecl _jn(long double) MSVCRT__jn
@ cdecl _kbhit() @ cdecl _kbhit()
@ cdecl _lfind(ptr ptr ptr long ptr) @ cdecl _lfind(ptr ptr ptr long ptr)
@ stub _lfind_s @ cdecl _lfind_s(ptr ptr ptr long ptr ptr)
@ cdecl _loaddll(str) @ cdecl _loaddll(str)
@ cdecl -arch=x86_64 _local_unwind(ptr ptr) @ cdecl -arch=x86_64 _local_unwind(ptr ptr)
@ cdecl -arch=i386 _local_unwind2(ptr long) @ cdecl -arch=i386 _local_unwind2(ptr long)
......
...@@ -690,7 +690,7 @@ ...@@ -690,7 +690,7 @@
@ cdecl _jn(long double) MSVCRT__jn @ cdecl _jn(long double) MSVCRT__jn
@ cdecl _kbhit() @ cdecl _kbhit()
@ cdecl _lfind(ptr ptr ptr long ptr) @ cdecl _lfind(ptr ptr ptr long ptr)
@ stub _lfind_s @ cdecl _lfind_s(ptr ptr ptr long ptr ptr)
@ cdecl _loaddll(str) @ cdecl _loaddll(str)
@ cdecl -arch=x86_64 _local_unwind(ptr ptr) @ cdecl -arch=x86_64 _local_unwind(ptr ptr)
@ cdecl -arch=i386 _local_unwind2(ptr long) @ cdecl -arch=i386 _local_unwind2(ptr long)
......
...@@ -103,6 +103,32 @@ void* CDECL _lfind(const void* match, const void* start, ...@@ -103,6 +103,32 @@ void* CDECL _lfind(const void* match, const void* start,
} }
/********************************************************************* /*********************************************************************
* _lfind_s (MSVCRT.@)
*/
void* CDECL _lfind_s(const void* match, const void* start,
unsigned int* array_size, unsigned int elem_size,
int (CDECL *cf)(void*,const void*,const void*),
void* context)
{
unsigned int size;
if (!MSVCRT_CHECK_PMT(match != NULL)) return NULL;
if (!MSVCRT_CHECK_PMT(array_size != NULL)) return NULL;
if (!MSVCRT_CHECK_PMT(start != NULL || *array_size == 0)) return NULL;
if (!MSVCRT_CHECK_PMT(cf != NULL)) return NULL;
if (!MSVCRT_CHECK_PMT(elem_size != 0)) return NULL;
size = *array_size;
if (size)
do
{
if (cf(context, match, start) == 0)
return (void *)start; /* found */
start = (const char *)start + elem_size;
} while (--size);
return NULL;
}
/*********************************************************************
* _lsearch (MSVCRT.@) * _lsearch (MSVCRT.@)
*/ */
void* CDECL _lsearch(const void* match, void* start, void* CDECL _lsearch(const void* match, void* start,
......
...@@ -655,7 +655,7 @@ ...@@ -655,7 +655,7 @@
@ cdecl _jn(long double) MSVCRT__jn @ cdecl _jn(long double) MSVCRT__jn
@ cdecl _kbhit() @ cdecl _kbhit()
@ cdecl _lfind(ptr ptr ptr long ptr) @ cdecl _lfind(ptr ptr ptr long ptr)
# stub _lfind_s(ptr ptr ptr long ptr ptr) @ cdecl _lfind_s(ptr ptr ptr long ptr ptr)
@ cdecl _loaddll(str) @ cdecl _loaddll(str)
@ cdecl -arch=x86_64 _local_unwind(ptr ptr) @ cdecl -arch=x86_64 _local_unwind(ptr ptr)
@ cdecl -arch=i386 _local_unwind2(ptr long) @ cdecl -arch=i386 _local_unwind2(ptr long)
......
...@@ -59,6 +59,8 @@ static void (__cdecl *p_qsort_s)(void*, MSVCRT_size_t, MSVCRT_size_t, ...@@ -59,6 +59,8 @@ static void (__cdecl *p_qsort_s)(void*, MSVCRT_size_t, MSVCRT_size_t,
static double (__cdecl *p_atan)(double); static double (__cdecl *p_atan)(double);
static double (__cdecl *p_exp)(double); static double (__cdecl *p_exp)(double);
static double (__cdecl *p_tanh)(double); static double (__cdecl *p_tanh)(double);
static void *(__cdecl *p_lfind_s)(const void*, const void*, unsigned int*,
size_t, int (__cdecl *)(void*, const void*, const void*), void*);
static void init(void) static void init(void)
{ {
...@@ -76,6 +78,7 @@ static void init(void) ...@@ -76,6 +78,7 @@ static void init(void)
p_atan = (void *)GetProcAddress(hmod, "atan"); p_atan = (void *)GetProcAddress(hmod, "atan");
p_exp = (void *)GetProcAddress(hmod, "exp"); p_exp = (void *)GetProcAddress(hmod, "exp");
p_tanh = (void *)GetProcAddress(hmod, "tanh"); p_tanh = (void *)GetProcAddress(hmod, "tanh");
p_lfind_s = (void *)GetProcAddress(hmod, "_lfind_s");
} }
static void test_rand_s(void) static void test_rand_s(void)
...@@ -597,6 +600,74 @@ static void test_thread_handle_close(void) ...@@ -597,6 +600,74 @@ static void test_thread_handle_close(void)
ok(ret, "ret = %d\n", ret); ok(ret, "ret = %d\n", ret);
} }
static int __cdecl _lfind_s_comp(void *ctx, const void *l, const void *r)
{
*(int *)ctx = 0xdeadc0de;
return *(int *)l - *(int *)r;
}
static void test__lfind_s(void)
{
static const int tests[] = {9000, 8001, 7002, 6003, 1003, 5004, 4005, 3006, 2007};
unsigned int num;
void *found;
int ctx;
int key;
if (!p_lfind_s)
{
win_skip("_lfind_s is not available\n");
return;
}
key = 1234;
num = sizeof(tests)/sizeof(tests[0]);
errno = 0xdeadbeef;
found = p_lfind_s(NULL, tests, &num, sizeof(int), _lfind_s_comp, NULL);
ok(errno == EINVAL, "errno = %d\n", errno);
ok(!found, "Expected NULL, got %p\n", found);
errno = 0xdeadbeef;
found = p_lfind_s(&key, NULL, &num, sizeof(int), _lfind_s_comp, NULL);
ok(errno == EINVAL, "errno = %d\n", errno);
ok(!found, "Expected NULL, got %p\n", found);
errno = 0xdeadbeef;
found = p_lfind_s(&key, tests, &num, 0, _lfind_s_comp, NULL);
ok(errno == EINVAL, "errno = %d\n", errno);
ok(!found, "Expected NULL, got %p\n", found);
errno = 0xdeadbeef;
found = p_lfind_s(&key, tests, &num, sizeof(int), NULL, NULL);
ok(errno == EINVAL, "errno = %d\n", errno);
ok(!found, "Expected NULL, got %p\n", found);
ctx = -1;
key = 9000;
errno = 0xdeadbeef;
found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
ok(errno == 0xdeadbeef, "errno = %d\n", errno);
ok(found == tests, "Expected %p, got %p\n", tests, found);
ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
ctx = -1;
key = 2007;
errno = 0xdeadbeef;
found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
ok(errno == 0xdeadbeef, "errno = %d\n", errno);
ok(found == tests+8, "Expected %p, got %p\n", tests+8, found);
ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
ctx = -1;
key = 1234;
errno = 0xdeadbeef;
found = p_lfind_s(&key, tests, &num, sizeof(int), _lfind_s_comp, &ctx);
ok(errno == 0xdeadbeef, "errno = %d\n", errno);
ok(!found, "Expected NULL, got %p\n", found);
ok(ctx == 0xdeadc0de, "Expected 0xdeadc0de, got %x\n", ctx);
}
START_TEST(misc) START_TEST(misc)
{ {
int arg_c; int arg_c;
...@@ -626,4 +697,5 @@ START_TEST(misc) ...@@ -626,4 +697,5 @@ START_TEST(misc)
test_qsort_s(); test_qsort_s();
test_math_functions(); test_math_functions();
test_thread_handle_close(); test_thread_handle_close();
test__lfind_s();
} }
...@@ -542,7 +542,7 @@ ...@@ -542,7 +542,7 @@
@ cdecl _ldtest(ptr) MSVCR120__ldtest @ cdecl _ldtest(ptr) MSVCR120__ldtest
@ stub _ldunscale @ stub _ldunscale
@ cdecl _lfind(ptr ptr ptr long ptr) @ cdecl _lfind(ptr ptr ptr long ptr)
@ stub _lfind_s @ cdecl _lfind_s(ptr ptr ptr long ptr ptr)
@ cdecl -arch=i386 _libm_sse2_acos_precise() MSVCRT___libm_sse2_acos @ cdecl -arch=i386 _libm_sse2_acos_precise() MSVCRT___libm_sse2_acos
@ cdecl -arch=i386 _libm_sse2_asin_precise() MSVCRT___libm_sse2_asin @ cdecl -arch=i386 _libm_sse2_asin_precise() MSVCRT___libm_sse2_asin
@ cdecl -arch=i386 _libm_sse2_atan_precise() MSVCRT___libm_sse2_atan @ cdecl -arch=i386 _libm_sse2_atan_precise() MSVCRT___libm_sse2_atan
......
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