[PATCH v3] msvcrt: Add _lfind_s

Daniel Lehman dlehman25 at gmail.com
Mon Nov 28 21:37:18 CST 2016


v2: update spec files, remove comments
v3: fix build

Signed-off-by: Daniel Lehman <dlehman25 at gmail.com>
---
 .../api-ms-win-crt-utility-l1-1-0.spec             |  2 +-
 dlls/msvcr100/msvcr100.spec                        |  2 +-
 dlls/msvcr110/msvcr110.spec                        |  2 +-
 dlls/msvcr120/msvcr120.spec                        |  2 +-
 dlls/msvcr120_app/msvcr120_app.spec                |  2 +-
 dlls/msvcr80/msvcr80.spec                          |  2 +-
 dlls/msvcr90/msvcr90.spec                          |  2 +-
 dlls/msvcrt/misc.c                                 | 26 ++++++++
 dlls/msvcrt/msvcrt.spec                            |  2 +-
 dlls/msvcrt/tests/misc.c                           | 72 ++++++++++++++++++++++
 dlls/ucrtbase/ucrtbase.spec                        |  2 +-
 11 files changed, 107 insertions(+), 9 deletions(-)

diff --git a/dlls/api-ms-win-crt-utility-l1-1-0/api-ms-win-crt-utility-l1-1-0.spec b/dlls/api-ms-win-crt-utility-l1-1-0/api-ms-win-crt-utility-l1-1-0.spec
index b335cf8..dffac44 100644
--- a/dlls/api-ms-win-crt-utility-l1-1-0/api-ms-win-crt-utility-l1-1-0.spec
+++ b/dlls/api-ms-win-crt-utility-l1-1-0/api-ms-win-crt-utility-l1-1-0.spec
@@ -3,7 +3,7 @@
 @ cdecl _byteswap_ulong(long) ucrtbase._byteswap_ulong
 @ cdecl _byteswap_ushort(long) ucrtbase._byteswap_ushort
 @ cdecl _lfind(ptr ptr ptr long ptr) ucrtbase._lfind
-@ stub _lfind_s
+@ cdecl _lfind_s(ptr ptr ptr long ptr ptr) urtbase._lfind_s
 @ cdecl _lrotl(long long) ucrtbase._lrotl
 @ cdecl _lrotr(long long) ucrtbase._lrotr
 @ cdecl _lsearch(ptr ptr ptr long ptr) ucrtbase._lsearch
diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index 15d5339..a33d00a 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -1040,7 +1040,7 @@
 @ cdecl _jn(long double) MSVCRT__jn
 @ cdecl _kbhit()
 @ cdecl _lfind(ptr ptr ptr long ptr)
-@ stub _lfind_s
+@ cdecl _lfind_s(ptr ptr ptr long ptr ptr)
 @ cdecl _loaddll(str)
 @ cdecl -arch=x86_64 _local_unwind(ptr ptr)
 @ cdecl -arch=i386 _local_unwind2(ptr long)
diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec
index e4ca89d..97f39a5 100644
--- a/dlls/msvcr110/msvcr110.spec
+++ b/dlls/msvcr110/msvcr110.spec
@@ -1386,7 +1386,7 @@
 @ cdecl _jn(long double) MSVCRT__jn
 @ cdecl _kbhit()
 @ 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_asin_precise() MSVCRT___libm_sse2_asin
 @ cdecl -arch=i386  _libm_sse2_atan_precise() MSVCRT___libm_sse2_atan
diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec
index f305062..aeb42ee 100644
--- a/dlls/msvcr120/msvcr120.spec
+++ b/dlls/msvcr120/msvcr120.spec
@@ -1396,7 +1396,7 @@
 @ cdecl _ldsign(double) MSVCR120__dsign
 @ cdecl _ldtest(ptr) MSVCR120__ldtest
 @ 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_asin_precise() MSVCRT___libm_sse2_asin
 @ cdecl -arch=i386  _libm_sse2_atan_precise() MSVCRT___libm_sse2_atan
diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec
index 449e8e1..cae7585 100644
--- a/dlls/msvcr120_app/msvcr120_app.spec
+++ b/dlls/msvcr120_app/msvcr120_app.spec
@@ -1260,7 +1260,7 @@
 @ cdecl _ldsign(double) msvcr120._ldsign
 @ cdecl _ldtest(ptr) msvcr120._ldtest
 @ 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_asin_precise() msvcr120._libm_sse2_asin_precise
 @ cdecl -arch=i386  _libm_sse2_atan_precise() msvcr120._libm_sse2_atan_precise
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index 4bcef50..ab81251 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -712,7 +712,7 @@
 @ cdecl _jn(long double) MSVCRT__jn
 @ cdecl _kbhit()
 @ cdecl _lfind(ptr ptr ptr long ptr)
-@ stub _lfind_s
+@ cdecl _lfind_s(ptr ptr ptr long ptr ptr)
 @ cdecl _loaddll(str)
 @ cdecl -arch=x86_64 _local_unwind(ptr ptr)
 @ cdecl -arch=i386 _local_unwind2(ptr long)
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 5c34e77..5f7d98f 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -690,7 +690,7 @@
 @ cdecl _jn(long double) MSVCRT__jn
 @ cdecl _kbhit()
 @ cdecl _lfind(ptr ptr ptr long ptr)
-@ stub _lfind_s
+@ cdecl _lfind_s(ptr ptr ptr long ptr ptr)
 @ cdecl _loaddll(str)
 @ cdecl -arch=x86_64 _local_unwind(ptr ptr)
 @ cdecl -arch=i386 _local_unwind2(ptr long)
diff --git a/dlls/msvcrt/misc.c b/dlls/msvcrt/misc.c
index c1510ef..23a089a 100644
--- a/dlls/msvcrt/misc.c
+++ b/dlls/msvcrt/misc.c
@@ -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.@)
  */
 void* CDECL _lsearch(const void* match, void* start,
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 0c1d4ad..d38b0fa 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -655,7 +655,7 @@
 @ cdecl _jn(long double) MSVCRT__jn
 @ cdecl _kbhit()
 @ 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 -arch=x86_64 _local_unwind(ptr ptr)
 @ cdecl -arch=i386 _local_unwind2(ptr long)
diff --git a/dlls/msvcrt/tests/misc.c b/dlls/msvcrt/tests/misc.c
index 77f2873..a6d2833 100644
--- a/dlls/msvcrt/tests/misc.c
+++ b/dlls/msvcrt/tests/misc.c
@@ -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_exp)(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)
 {
@@ -76,6 +78,7 @@ static void init(void)
     p_atan = (void *)GetProcAddress(hmod, "atan");
     p_exp = (void *)GetProcAddress(hmod, "exp");
     p_tanh = (void *)GetProcAddress(hmod, "tanh");
+    p_lfind_s = (void *)GetProcAddress(hmod, "_lfind_s");
 }
 
 static void test_rand_s(void)
@@ -597,6 +600,74 @@ static void test_thread_handle_close(void)
     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)
 {
     int arg_c;
@@ -626,4 +697,5 @@ START_TEST(misc)
     test_qsort_s();
     test_math_functions();
     test_thread_handle_close();
+    test__lfind_s();
 }
diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec
index 0005850..6253065 100644
--- a/dlls/ucrtbase/ucrtbase.spec
+++ b/dlls/ucrtbase/ucrtbase.spec
@@ -542,7 +542,7 @@
 @ cdecl _ldtest(ptr) MSVCR120__ldtest
 @ stub _ldunscale
 @ 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_asin_precise() MSVCRT___libm_sse2_asin
 @ cdecl -arch=i386  _libm_sse2_atan_precise() MSVCRT___libm_sse2_atan
-- 
2.7.4




More information about the wine-patches mailing list