From f320f6cf4843eab3d22b60674808e4e3de964b5a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20Hentschel?= Date: Mon, 16 Jul 2012 20:36:10 +0200 Subject: [PATCH] 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 bf3a0687ccf..70bcbd0a185 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 86863598c9f..d758176bbe2 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 6aefe206920..5c27fcad5d2 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 dc15472d918..92945ae8a3c 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 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 d40e38f8415..8f2c111d4b6 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 04ef9ad5c1b..934c247695e 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 -- 2.11.4.GIT