msvcrt: Add bsearch_s implementation by reusing code and tests from ntdll.
This commit is contained in:
parent
f857ad5225
commit
f320f6cf48
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -123,6 +123,33 @@ void* CDECL _lsearch(const void* match, void* start,
|
|||
return 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.@)
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue