=?UTF-8?Q?Andr=C3=A9=20Hentschel=20?=: msvcrt: Add bsearch_s implementation by reusing code and tests from ntdll.

Alexandre Julliard julliard at winehq.org
Tue Jul 17 11:05:35 CDT 2012


Module: wine
Branch: master
Commit: f320f6cf4843eab3d22b60674808e4e3de964b5a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f320f6cf4843eab3d22b60674808e4e3de964b5a

Author: André Hentschel <nerv at dawncrow.de>
Date:   Mon Jul 16 20:36:10 2012 +0200

msvcrt: Add bsearch_s implementation by reusing code and tests from ntdll.

---

 dlls/msvcr100/msvcr100.spec  |    2 +-
 dlls/msvcr80/msvcr80.spec    |    2 +-
 dlls/msvcr90/msvcr90.spec    |    2 +-
 dlls/msvcr90/tests/msvcr90.c |   48 ++++++++++++++++++++++++++++++++++++++++++
 dlls/msvcrt/misc.c           |   27 +++++++++++++++++++++++
 dlls/msvcrt/msvcrt.spec      |    2 +-
 6 files changed, 79 insertions(+), 4 deletions(-)

diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec
index bf3a068..70bcbd0 100644
--- a/dlls/msvcr100/msvcr100.spec
+++ b/dlls/msvcr100/msvcr100.spec
@@ -1434,7 +1434,7 @@
 @ cdecl atoi(str) msvcrt.atoi
 @ cdecl atol(str) msvcrt.atol
 @ cdecl bsearch(ptr ptr long long ptr) msvcrt.bsearch
-@ stub bsearch_s
+@ cdecl bsearch_s(ptr ptr long long ptr ptr) msvcrt.bsearch_s
 @ cdecl btowc(long) msvcrt.btowc
 @ cdecl calloc(long long) msvcrt.calloc
 @ cdecl ceil(double) msvcrt.ceil
diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec
index 8686359..d758176 100644
--- a/dlls/msvcr80/msvcr80.spec
+++ b/dlls/msvcr80/msvcr80.spec
@@ -1290,7 +1290,7 @@
 @ cdecl atoi(str) msvcrt.atoi
 @ cdecl atol(str) msvcrt.atol
 @ cdecl bsearch(ptr ptr long long ptr) msvcrt.bsearch
-@ stub bsearch_s
+@ cdecl bsearch_s(ptr ptr long long ptr ptr) msvcrt.bsearch_s
 @ cdecl btowc(long) msvcrt.btowc
 @ cdecl calloc(long long) msvcrt.calloc
 @ cdecl ceil(double) msvcrt.ceil
diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec
index 6aefe20..5c27fca 100644
--- a/dlls/msvcr90/msvcr90.spec
+++ b/dlls/msvcr90/msvcr90.spec
@@ -1285,7 +1285,7 @@
 @ cdecl atoi(str) msvcrt.atoi
 @ cdecl atol(str) msvcrt.atol
 @ cdecl bsearch(ptr ptr long long ptr) msvcrt.bsearch
-@ stub bsearch_s
+@ cdecl bsearch_s(ptr ptr long long ptr ptr) msvcrt.bsearch_s
 @ cdecl btowc(long) msvcrt.btowc
 @ cdecl calloc(long long) msvcrt.calloc
 @ cdecl ceil(double) msvcrt.ceil
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c
index dc15472..92945ae 100644
--- a/dlls/msvcr90/tests/msvcr90.c
+++ b/dlls/msvcr90/tests/msvcr90.c
@@ -72,6 +72,8 @@ static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
 static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int);
 static int (__cdecl *p_wcsncat_s)(wchar_t *dst, size_t elem, const wchar_t *src, size_t count);
 static void (__cdecl *p_qsort_s)(void *, size_t, size_t, int (__cdecl *)(void *, const void *, const void *), void *);
+static void* (__cdecl *p_bsearch_s)(const void *, const void *, size_t, size_t,
+                                    int (__cdecl *compare)(void *, const void *, const void *), void *);
 static int (__cdecl *p_controlfp_s)(unsigned int *, unsigned int, unsigned int);
 static int (__cdecl *p_atoflt)(_CRT_FLOAT *, char *);
 static unsigned int (__cdecl *p_set_abort_behavior)(unsigned int, unsigned int);
@@ -134,6 +136,7 @@ static void* (WINAPI *pEncodePointer)(void *);
 
 static int cb_called[4];
 static int g_qsort_s_context_counter;
+static int g_bsearch_s_context_counter;
 
 static inline int almost_equal_f(float f1, float f2)
 {
@@ -250,6 +253,7 @@ static BOOL init(void)
     SET(p_itoa_s, "_itoa_s");
     SET(p_wcsncat_s,"wcsncat_s" );
     SET(p_qsort_s, "qsort_s");
+    SET(p_bsearch_s, "bsearch_s");
     SET(p_controlfp_s, "_controlfp_s");
     SET(p_atoflt, "_atoflt");
     SET(p_set_abort_behavior, "_set_abort_behavior");
@@ -750,6 +754,49 @@ static void test_qsort_s(void)
     ok(!strcmp(strarr[6],"World"),  "badly sorted, strarr[6] is %s\n", strarr[6]);
 }
 
+static void test_bsearch_s(void)
+{
+    int arr[7] = { 1, 3, 4, 8, 16, 23, 42 };
+    int *x, l, i, j = 1;
+
+    errno = 0xdeadbeef;
+    SET_EXPECT(invalid_parameter_handler);
+    x = p_bsearch_s(NULL, NULL, 0, 0, NULL, NULL);
+    ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
+    CHECK_CALLED(invalid_parameter_handler);
+
+    g_bsearch_s_context_counter = 0;
+    SET_EXPECT(invalid_parameter_handler);
+    x = p_bsearch_s(&l, arr, j, 0, intcomparefunc, &g_bsearch_s_context_counter);
+    ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
+    ok(g_bsearch_s_context_counter == 0, "callback shouldn't have been called\n");
+    CHECK_CALLED(invalid_parameter_handler);
+
+    g_bsearch_s_context_counter = 0;
+    SET_EXPECT(invalid_parameter_handler);
+    x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), NULL, &g_bsearch_s_context_counter);
+    ok(x == NULL, "Expected bsearch_s to return NULL, got %p\n", x);
+    ok(g_bsearch_s_context_counter == 0, "callback shouldn't have been called\n");
+    CHECK_CALLED(invalid_parameter_handler);
+    ok(errno == 0xdeadbeef, "errno = %x\n", errno);
+
+    /* just try all array sizes */
+    for (j=1;j<sizeof(arr)/sizeof(arr[0]);j++) {
+        for (i=0;i<j;i++) {
+            l = arr[i];
+            g_bsearch_s_context_counter = 0;
+            x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), intcomparefunc, &g_bsearch_s_context_counter);
+            ok (x == &arr[i], "bsearch_s did not find %d entry in loopsize %d.\n", i, j);
+            ok(g_bsearch_s_context_counter > 0, "callback wasn't called\n");
+        }
+        l = 4242;
+        g_bsearch_s_context_counter = 0;
+        x = p_bsearch_s(&l, arr, j, sizeof(arr[0]), intcomparefunc, &g_bsearch_s_context_counter);
+        ok (x == NULL, "bsearch_s did find 4242 entry in loopsize %d.\n", j);
+        ok(g_bsearch_s_context_counter > 0, "callback wasn't called\n");
+    }
+}
+
 static void test_controlfp_s(void)
 {
     unsigned int cur;
@@ -1162,6 +1209,7 @@ START_TEST(msvcr90)
     test__itoa_s();
     test_wcsncat_s();
     test_qsort_s();
+    test_bsearch_s();
     test_controlfp_s();
     test__atoflt();
     test__set_abort_behavior();
diff --git a/dlls/msvcrt/misc.c b/dlls/msvcrt/misc.c
index d40e38f..8f2c111 100644
--- a/dlls/msvcrt/misc.c
+++ b/dlls/msvcrt/misc.c
@@ -124,6 +124,33 @@ void* CDECL _lsearch(const void* match, void* start,
 }
 
 /*********************************************************************
+ *                  bsearch_s (msvcrt.@)
+ */
+void* CDECL MSVCRT_bsearch_s(const void *key, const void *base,
+                             MSVCRT_size_t nmemb, MSVCRT_size_t size,
+                             int (__cdecl *compare)(void *, const void *, const void *), void *ctx)
+{
+    ssize_t min = 0;
+    ssize_t max = nmemb - 1;
+
+    if (!MSVCRT_CHECK_PMT(size != 0) || !MSVCRT_CHECK_PMT(compare != NULL))
+        return NULL;
+
+    while (min <= max)
+    {
+        ssize_t cursor = (min + max) / 2;
+        int ret = compare(ctx, key,(const char *)base+(cursor*size));
+        if (!ret)
+            return (char*)base+(cursor*size);
+        if (ret < 0)
+            max = cursor - 1;
+        else
+            min = cursor + 1;
+    }
+    return NULL;
+}
+
+/*********************************************************************
  *		_chkesp (MSVCRT.@)
  *
  * Trap to a debugger if the value of the stack pointer has changed.
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 04ef9ad..934c247 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -1226,7 +1226,7 @@
 @ cdecl atoi(str) ntdll.atoi
 @ cdecl atol(str) ntdll.atol
 @ cdecl bsearch(ptr ptr long long ptr) ntdll.bsearch
-# stub bsearch_s(ptr ptr long long ptr ptr)
+@ cdecl bsearch_s(ptr ptr long long ptr ptr) MSVCRT_bsearch_s
 @ cdecl btowc(long) MSVCRT_btowc
 @ cdecl calloc(long long) MSVCRT_calloc
 @ cdecl ceil(double) MSVCRT_ceil




More information about the wine-cvs mailing list