Add gnulib module qsort_r

* autogen.sh: Add gnulib module qsort_r
* configure.ac: Remove qsort_r code
* libwget/vector.c: Remove conditional code
This commit is contained in:
Tim Rühsen
2016-01-11 17:30:47 +01:00
parent 1e8c3848d0
commit 434fb5fe4c
3 changed files with 2 additions and 95 deletions

View File

@ -41,6 +41,7 @@ fnmatch
futimens
glob
nanosleep
qsort_r
strcase
strdup
strndup

View File

@ -385,34 +385,7 @@ AC_FUNC_MMAP
#AC_FUNC_REALLOC
AC_CHECK_FUNCS([\
memchr memmove memset mkdir munmap select setlocale socket\
strchr strerror strrchr strstr strlcpy vasprintf nl_langinfo pwrite qsort_r])
# BSD / OSX have a qsort_r with swapped arguments
if test x$ac_cv_func_qsort_r = xyes ; then
AC_MSG_CHECKING([argument style of qsort_r])
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#define _GNU_SOURCE
#include <stdlib.h>
static int cmp(const void *a, const void *b, void *c)
{
return *(const int *)a - *(const int *)b;
}
int main(void)
{
int arr[3] = { 1, 2, 0 };
qsort_r(arr, 3, sizeof(int), cmp, NULL);
return !(arr[0] == 0 && arr[1] == 1 && arr[2] == 2);
}]])],
[
AC_MSG_RESULT([GNU])
],[
AC_DEFINE(HAVE_QSORT_R_BSD, 1, [Define to 1 if you have the 'qsort_r' function with BSD style arguments])
AC_MSG_RESULT([BSD])
])
fi
strchr strerror strrchr strstr strlcpy vasprintf nl_langinfo pwrite])
AC_CONFIG_FILES([Makefile
lib/Makefile

View File

@ -387,84 +387,17 @@ void wget_vector_set_destructor(wget_vector_t *v, void (*destructor)(void *elem)
v->destructor = destructor;
}
#if HAVE_QSORT_R_BSD
static int G_GNUC_WGET_NONNULL_ALL _compare(void *v, const void *p1, const void *p2)
{
return ((wget_vector_t *)v)->cmp(*((void **)p1), *((void **)p2));
}
#elif HAVE_QSORT_R
static int G_GNUC_WGET_NONNULL_ALL _compare(const void *p1, const void *p2, void *v)
{
return ((wget_vector_t *)v)->cmp(*((void **)p1), *((void **)p2));
}
#else
// fallback to non-reentrant code (e.g. for OpenBSD <= 5.8)
static wget_vector_t *_v;
static int G_GNUC_WGET_NONNULL_ALL _compare(const void *p1, const void *p2)
{
return _v->cmp(*((void **)p1), *((void **)p2));
}
#endif
void wget_vector_sort(wget_vector_t *v)
{
/*
* Without the intermediate _compare function below, v->cmp must take 'const void **elem{1|2}'
* but than, the other calls to v->cmp must change as well.
*
* To work lock-less (e.g. with a mutex), we need 'nested functions' (GCC, Intel, IBM)
* or BLOCKS (clang) or the GNU libc extension qsort_r().
* Using BLOCKS would also need a qsort_b() function...
*
*/
#if HAVE_QSORT_R_BSD
if (v && v->cmp) {
qsort_r(v->entry, v->cur, sizeof(void *), v, _compare);
v->sorted = 1;
}
#elif HAVE_QSORT_R
if (v && v->cmp) {
qsort_r(v->entry, v->cur, sizeof(void *), _compare, v);
v->sorted = 1;
}
#else
// fallback to non-reentrant code (e.g. for OpenBSD <= 5.8)
if (v && v->cmp) {
static wget_thread_mutex_t
mutex = WGET_THREAD_MUTEX_INITIALIZER;
wget_thread_mutex_lock(&mutex);
_v = v;
qsort(v->entry, v->cur, sizeof(void *), _compare);
v->sorted = 1;
wget_thread_mutex_unlock(&mutex);
}
#endif
/*
// trampoline version (e.g. gcc, but not on OpenBSD !)
int G_GNUC_WGET_NONNULL_ALL _compare(const void *p1, const void *p2)
{
return v->cmp(*((void **)p1), *((void **)p2));
}
if (v && v->cmp) {
qsort(v->entry, v->cur, sizeof(void *), _compare);
v->sorted = 1;
}
#error You need gcc or qsort_r() to build Wget
// this should work as soon as the qsort_b() function is available ;-)
if (v && v->cmp) {
int (^_compare)(const void *, const void *) = ^ int (const void *p1, const void *p2) {
return v->cmp(*((void **)p1), *((void **)p2));
};
qsort_b(v->pl, v->cur, sizeof(void *), _compare);
v->sorted = 1;
}
*/
}
// Find first entry that matches the specified element,