2007-11-13 Ulrich Drepper <drepper@redhat.com>
+ * stdlib/stdlib.h: Define __compar_d_fn_t. Declare qsort_r.
+ * include/stdlib.h: Add hidden_proto for qsort_t and adjust protoype
+ for _quicksort.
+ * stdlib/msort.c (qsort): Now a wrapper around qsort_r.
+ (qsort_r): Renamed from qsort. Take additional parameter and pass it
+ on as third parameter to compare function and _quicksort.
+ * stdlib/qsort.c (_quicksort): Take additional parameter and pass on
+ to the compare function.
+ * stdlib/Versions [libc] (GLIBC_2.8): Add qsort_r.
+ * Versions.def: Add GLIBC_2.8 for libc.
+
* posix/tst-rfc3484.c: Adjust for addition of prefixlen field.
* posix/tst-rfc3484-2.c: Likewise.
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
+ GLIBC_2.8
%ifdef USE_IN_LIBIO
HURD_CTHREADS_0.3
%endif
libc_hidden_proto (getenv)
libc_hidden_proto (bsearch)
libc_hidden_proto (qsort)
+libc_hidden_proto (qsort_r)
libc_hidden_proto (lrand48_r)
libc_hidden_proto (wctomb)
libc_hidden_proto (__secure_getenv)
const char *combines, int replace);
extern void _quicksort (void *const pbase, size_t total_elems,
- size_t size, __compar_fn_t cmp);
+ size_t size, __compar_d_fn_t cmp, void *arg);
extern int __on_exit (void (*__func) (int __status, void *__arg), void *__arg);
# Silent change in SUS.
realpath;
}
+ GLIBC_2.8 {
+ qsort_r;
+ }
GLIBC_PRIVATE {
# functions which have an additional interface since they are
# are cancelable.
{
size_t s;
size_t var;
- __compar_fn_t cmp;
+ __compar_d_fn_t cmp;
+ void *arg;
char *t;
};
static void msort_with_tmp (const struct msort_param *p, void *b, size_t n);
char *tmp = p->t;
const size_t s = p->s;
- __compar_fn_t cmp = p->cmp;
+ __compar_d_fn_t cmp = p->cmp;
+ void *arg = p->arg;
switch (p->var)
{
case 0:
while (n1 > 0 && n2 > 0)
{
- if ((*cmp) (b1, b2) <= 0)
+ if ((*cmp) (b1, b2, arg) <= 0)
{
*(uint32_t *) tmp = *(uint32_t *) b1;
b1 += sizeof (uint32_t);
case 1:
while (n1 > 0 && n2 > 0)
{
- if ((*cmp) (b1, b2) <= 0)
+ if ((*cmp) (b1, b2, arg) <= 0)
{
*(uint64_t *) tmp = *(uint64_t *) b1;
b1 += sizeof (uint64_t);
unsigned long *bl;
tmp += s;
- if ((*cmp) (b1, b2) <= 0)
+ if ((*cmp) (b1, b2, arg) <= 0)
{
bl = (unsigned long *) b1;
b1 += s;
case 3:
while (n1 > 0 && n2 > 0)
{
- if ((*cmp) (*(const void **) b1, *(const void **) b2) <= 0)
+ if ((*cmp) (*(const void **) b1, *(const void **) b2, arg) <= 0)
{
*(void **) tmp = *(void **) b1;
b1 += sizeof (void *);
default:
while (n1 > 0 && n2 > 0)
{
- if ((*cmp) (b1, b2) <= 0)
+ if ((*cmp) (b1, b2, arg) <= 0)
{
tmp = (char *) __mempcpy (tmp, b1, s);
b1 += s;
memcpy (b, p->t, (n - n2) * s);
}
+
void
-qsort (void *b, size_t n, size_t s, __compar_fn_t cmp)
+qsort_r (void *b, size_t n, size_t s, __compar_d_fn_t cmp, void *arg)
{
size_t size = n * s;
char *tmp = NULL;
/* If the memory requirements are too high don't allocate memory. */
if (size / pagesize > (size_t) phys_pages)
{
- _quicksort (b, n, s, cmp);
+ _quicksort (b, n, s, cmp, arg);
return;
}
{
/* Couldn't get space, so use the slower algorithm
that doesn't need a temporary array. */
- _quicksort (b, n, s, cmp);
+ _quicksort (b, n, s, cmp, arg);
return;
}
p.t = tmp;
}
p.s = s;
- p.cmp = cmp;
p.var = 4;
+ p.cmp = cmp;
+ p.arg = arg;
if (s > 32)
{
while (kp != ip);
tp[j] = jp;
- memcpy (jp, tmp_storage, s);
+ memcpy (jp, tmp_storage, s);
}
}
else
}
free (tmp);
}
+libc_hidden_def (qsort_r)
+
+
+void
+qsort (void *b, size_t n, size_t s, __compar_fn_t cmp)
+{
+ return qsort_r (b, n, s, (__compar_d_fn_t) cmp, NULL);
+}
libc_hidden_def (qsort)
void
_quicksort (void *const pbase, size_t total_elems, size_t size,
- __compar_fn_t cmp)
+ __compar_d_fn_t cmp, void *arg)
{
register char *base_ptr = (char *) pbase;
char *mid = lo + size * ((hi - lo) / size >> 1);
- if ((*cmp) ((void *) mid, (void *) lo) < 0)
+ if ((*cmp) ((void *) mid, (void *) lo, arg) < 0)
SWAP (mid, lo, size);
- if ((*cmp) ((void *) hi, (void *) mid) < 0)
+ if ((*cmp) ((void *) hi, (void *) mid, arg) < 0)
SWAP (mid, hi, size);
else
goto jump_over;
- if ((*cmp) ((void *) mid, (void *) lo) < 0)
+ if ((*cmp) ((void *) mid, (void *) lo, arg) < 0)
SWAP (mid, lo, size);
jump_over:;
that this algorithm runs much faster than others. */
do
{
- while ((*cmp) ((void *) left_ptr, (void *) mid) < 0)
+ while ((*cmp) ((void *) left_ptr, (void *) mid, arg) < 0)
left_ptr += size;
- while ((*cmp) ((void *) mid, (void *) right_ptr) < 0)
+ while ((*cmp) ((void *) mid, (void *) right_ptr, arg) < 0)
right_ptr -= size;
if (left_ptr < right_ptr)
and the operation speeds up insertion sort's inner loop. */
for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)
- if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr) < 0)
+ if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0)
tmp_ptr = run_ptr;
if (tmp_ptr != base_ptr)
while ((run_ptr += size) <= end_ptr)
{
tmp_ptr = run_ptr - size;
- while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr) < 0)
+ while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr, arg) < 0)
tmp_ptr -= size;
tmp_ptr += size;
typedef __compar_fn_t comparison_fn_t;
# endif
#endif
+#ifdef __USE_GNU
+typedef int (*__compar_d_fn_t) (__const void *, __const void *, void *);
+#endif
__BEGIN_NAMESPACE_STD
/* Do a binary search for KEY in BASE, which consists of NMEMB elements
using COMPAR to perform the comparisons. */
extern void qsort (void *__base, size_t __nmemb, size_t __size,
__compar_fn_t __compar) __nonnull ((1, 4));
+#ifdef __USE_GNU
+extern void qsort_r (void *__base, size_t __nmemb, size_t __size,
+ __compar_d_fn_t __compar, void *__arg)
+ __nonnull ((1, 4));
+#endif
/* Return the absolute value of X. */