add qsort_r wrapper to fix differences between BSD and GNU qsort_r

The order of parameters of both qsort_r and its compar function differ,
the wrapper matches the GNU version and swaps things around on FreeBSD.
This commit is contained in:
Nicolas Gilles 2014-04-29 19:35:09 +02:00 committed by Jaroslav Kysela
parent 9f74192d65
commit 20e2a668bd
3 changed files with 31 additions and 1 deletions

View file

@ -642,7 +642,7 @@ void
idnode_set_sort
( idnode_set_t *is, idnode_sort_t *sort )
{
qsort_r(is->is_array, is->is_count, sizeof(idnode_t*), idnode_cmp_sort, (void*)sort);
tvh_qsort_r(is->is_array, is->is_count, sizeof(idnode_t*), idnode_cmp_sort, (void*)sort);
}
void

View file

@ -657,6 +657,8 @@ qsort_r(void *base, size_t nmemb, size_t size,
int (*cmp)(const void *, const void *, void *), void *aux);
#endif /* ENABLE_QSORT_R */
void tvh_qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *arg);
/* printing */
#ifndef __WORDSIZE
# if ULONG_MAX == 0xffffffffffffffff

View file

@ -168,3 +168,31 @@ qsort_r(void *base, size_t nmemb, size_t size,
qsort(base, nmemb, size, qsort_r_wrap);
}
#endif /* ENABLE_QSORT_R */
#if defined(PLATFORM_FREEBSD)
struct tvh_qsort_data {
void *arg;
int (*compar)(const void *, const void *, void *);
};
static int
tvh_qsort_swap(void *arg, const void *a, const void *b)
{
struct tvh_qsort_data *data = arg;
return data->compar(a, b, data->arg);
}
#endif /* PLATFORM_FREEBSD */
void
tvh_qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *arg)
{
#if defined(PLATFORM_FREEBSD)
struct tvh_qsort_data swap_arg = {arg, compar};
qsort_r(base, nmemb, size, &swap_arg, tvh_qsort_swap);
#else
qsort_r(base, nmemb, size, compar, arg);
#endif
}