msvcrt: Add bsearch_s implementation by reusing code and tests from ntdll (try 7)
André Hentschel
nerv at dawncrow.de
Mon Jul 16 13:36:10 CDT 2012
---
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 | 28 ++++++++++++++++++++++++
dlls/msvcrt/msvcrt.spec | 2 +-
6 files changed, 80 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..83424b7 100644
--- a/dlls/msvcrt/misc.c
+++ b/dlls/msvcrt/misc.c
@@ -124,6 +124,34 @@ 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;
+
+ if (!MSVCRT_CHECK_PMT(size != 0) || !MSVCRT_CHECK_PMT(compare != NULL))
+ return NULL;
+
+ max = nmemb - 1;
+ 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
--
1.7.4.1
--
Best Regards, André Hentschel
More information about the wine-patches
mailing list