summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2011-11-07 09:24:30 +0100
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2011-11-07 09:24:30 +0100
commit515d54433138596e81267237542bd9168b8cc787 (patch)
treef2d6745268b788cc38d1b67deb32f71916b10fec
parent84144d142cb9f041dd18285cb2ad9dbe6619b0a2 (diff)
stdlib: add qsort_r
GNU extension like qsort but takes a 3 parameter comparision function. Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
-rw-r--r--include/stdlib.h10
-rw-r--r--libc/stdlib/Makefile.in2
-rw-r--r--libc/stdlib/qsort_r.c7
-rw-r--r--libc/stdlib/stdlib.c23
4 files changed, 35 insertions, 7 deletions
diff --git a/include/stdlib.h b/include/stdlib.h
index e9a8b84c2..1f15531e4 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -690,6 +690,9 @@ typedef int (*__compar_fn_t) (__const void *, __const void *);
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
@@ -703,7 +706,12 @@ extern void *bsearch (__const void *__key, __const void *__base,
extern void qsort (void *__base, size_t __nmemb, size_t __size,
__compar_fn_t __compar) __nonnull ((1, 4));
libc_hidden_proto(qsort)
-
+#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));
+libc_hidden_proto(qsort_r)
+#endif
/* Return the absolute value of X. */
extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur;
diff --git a/libc/stdlib/Makefile.in b/libc/stdlib/Makefile.in
index 760ccf7e6..73e5462f6 100644
--- a/libc/stdlib/Makefile.in
+++ b/libc/stdlib/Makefile.in
@@ -29,7 +29,7 @@ CSRC-$(UCLIBC_SUSV3_LEGACY) += mktemp.c
# multi source stdlib.c
CSRC-y += abs.c labs.c atoi.c atol.c strtol.c strtoul.c _stdlib_strto_l.c \
- qsort.c bsearch.c \
+ qsort.c qsort_r.c bsearch.c \
llabs.c atoll.c strtoll.c strtoull.c _stdlib_strto_ll.c
# (aliases) strtoq.o strtouq.o
CSRC-$(UCLIBC_HAS_FLOATS) += atof.c
diff --git a/libc/stdlib/qsort_r.c b/libc/stdlib/qsort_r.c
new file mode 100644
index 000000000..1db270e62
--- /dev/null
+++ b/libc/stdlib/qsort_r.c
@@ -0,0 +1,7 @@
+/* Copyright (C) 2004-2006 Manuel Novoa III <mjn3@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#define L_qsort_r
+#include "stdlib.c"
diff --git a/libc/stdlib/stdlib.c b/libc/stdlib/stdlib.c
index cd9a0cac6..9e8c347fd 100644
--- a/libc/stdlib/stdlib.c
+++ b/libc/stdlib/stdlib.c
@@ -784,7 +784,7 @@ void *bsearch(const void *key, const void *base, size_t /* nmemb */ high,
#endif
/**********************************************************************/
-#ifdef L_qsort
+#ifdef L_qsort_r
/* This code is derived from a public domain shell sort routine by
* Ray Gardner and found in Bob Stout's snippets collection. The
@@ -794,10 +794,11 @@ void *bsearch(const void *key, const void *base, size_t /* nmemb */ high,
* calculation, as well as to reduce the generated code size with
* bcc and gcc. */
-void qsort(void *base,
+void qsort_r(void *base,
size_t nel,
size_t width,
- int (*comp)(const void *, const void *))
+ __compar_d_fn_t comp,
+ void *arg)
{
size_t wgap, i, j, k;
char tmp;
@@ -823,7 +824,7 @@ void qsort(void *base,
j -= wgap;
a = j + ((char *)base);
b = a + wgap;
- if ((*comp)(a, b) <= 0) {
+ if ((*comp)(a, b, arg) <= 0) {
break;
}
k = width;
@@ -839,7 +840,7 @@ void qsort(void *base,
} while (wgap);
}
}
-libc_hidden_def(qsort)
+libc_hidden_def(qsort_r)
/* ---------- original snippets version below ---------- */
@@ -886,6 +887,18 @@ void ssort(void *base,
#endif
#endif
+
+#ifdef L_qsort
+void qsort(void *base,
+ size_t nel,
+ size_t width,
+ __compar_fn_t comp)
+{
+ return qsort_r (base, nel, width, (__compar_d_fn_t) comp, NULL);
+}
+libc_hidden_def(qsort)
+#endif
+
/**********************************************************************/
#ifdef L__stdlib_mb_cur_max