ntdll: Implement bsearch, lfind to use correct comparator functions.

oldstable
Marcus Meissner 2010-05-12 17:26:33 +02:00 committed by Alexandre Julliard
parent b2ff743ccb
commit 2ecd1dfaba
3 changed files with 68 additions and 21 deletions

View File

@ -294,3 +294,49 @@ void __cdecl NTDLL_qsort( void *base, size_t nmemb, size_t size,
NTDLL_mergesort( base, secondarr, size, compar, 0, nmemb-1 );
RtlFreeHeap (GetProcessHeap(),0, secondarr);
}
/*********************************************************************
* bsearch (NTDLL.@)
*/
void * __cdecl
NTDLL_bsearch( const void *key, const void *base, size_t nmemb,
size_t size, int (__cdecl *compar)(const void *, const void *) )
{
int begin, end, cursor;
begin = 0;
end = nmemb-1;
while (1) {
int ret;
cursor = (end-begin)/2+begin;
ret = compar(key,(char*)base+(cursor*size));
if (!ret)
return (char*)base+(cursor*size);
if (ret < 0)
end = cursor;
else
begin = cursor;
if ((end-begin)<=1)
break;
}
if (!compar(key,(char*)base+(begin*size)))
return (char*)base+(begin*size);
if (!compar(key,(char*)base+(end*size)))
return (char*)base+(end*size);
return NULL;
}
/*********************************************************************
* _lfind (NTDLL.@)
*/
void * __cdecl _lfind( const void *key, const void *base, unsigned int *nmemb,
size_t size, int(__cdecl *compar)(const void *, const void *) )
{
size_t i, n = *nmemb;
for (i=0;i<n;i++)
if (!compar(key,(char*)base+(size*i)))
return (char*)base+(size*i);
return NULL;
}

View File

@ -82,27 +82,6 @@ void * __cdecl NTDLL_memset( void *dst, int c, size_t n )
}
/*********************************************************************
* bsearch (NTDLL.@)
*/
void * __cdecl NTDLL_bsearch( const void *key, const void *base, size_t nmemb,
size_t size, int (*compar)(const void *, const void *) )
{
return bsearch( key, base, nmemb, size, compar );
}
/*********************************************************************
* _lfind (NTDLL.@)
*/
void * __cdecl _lfind( const void *key, const void *base, unsigned int *nmemb,
size_t size, int(*compar)(const void *, const void *) )
{
size_t n = *nmemb;
return lfind( key, base, &n, size, compar );
}
/*********************************************************************
* strcat (NTDLL.@)
*/

View File

@ -58,6 +58,7 @@ static LPWSTR (WINAPIV *p_wcschr)(LPCWSTR, WCHAR);
static LPWSTR (WINAPIV *p_wcsrchr)(LPCWSTR, WCHAR);
static void (__cdecl *p_qsort)(void *,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
static void* (__cdecl *p_bsearch)(void *,void*,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
static void InitFunctionPtrs(void)
@ -94,6 +95,7 @@ static void InitFunctionPtrs(void)
p_wcschr= (void *)GetProcAddress(hntdll, "wcschr");
p_wcsrchr= (void *)GetProcAddress(hntdll, "wcsrchr");
p_qsort= (void *)GetProcAddress(hntdll, "qsort");
p_bsearch= (void *)GetProcAddress(hntdll, "bsearch");
} /* if */
}
@ -1194,6 +1196,24 @@ static void test_qsort(void)
ok(!strcmp(strarr[6],"World"), "badly sorted, strarr[6] is %s\n", strarr[6]);
}
static void test_bsearch(void)
{
int arr[7] = { 1, 3, 4, 8, 16, 23, 42 };
int *x, l, i,j ;
/* just try all all sizes */
for (j=1;j<sizeof(arr)/sizeof(arr[0]);j++) {
for (i=0;i<j;i++) {
l = arr[i];
x = p_bsearch (&l, arr, j, sizeof(arr[0]), intcomparefunc);
ok (x == &arr[i], "bsearch did not find %d entry in loopsize %d.\n", i, j);
}
l = 4242;
x = p_bsearch (&l, arr, j, sizeof(arr[0]), intcomparefunc);
ok (x == NULL, "bsearch did find 4242 entry in loopsize %d.\n", j);
}
}
START_TEST(string)
{
InitFunctionPtrs();
@ -1224,4 +1244,6 @@ START_TEST(string)
test_atol();
if (p_qsort)
test_qsort();
if (p_bsearch)
test_bsearch();
}