mirror of
https://gitlab.com/gnuwget/wget2.git
synced 2026-02-01 14:41:08 +00:00
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:
@ -41,6 +41,7 @@ fnmatch
|
||||
futimens
|
||||
glob
|
||||
nanosleep
|
||||
qsort_r
|
||||
strcase
|
||||
strdup
|
||||
strndup
|
||||
|
||||
29
configure.ac
29
configure.ac
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
Reference in New Issue
Block a user