Browse Source

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>
Bernhard Reutner-Fischer 12 years ago
parent
commit
515d544331
4 changed files with 35 additions and 7 deletions
  1. 9 1
      include/stdlib.h
  2. 1 1
      libc/stdlib/Makefile.in
  3. 7 0
      libc/stdlib/qsort_r.c
  4. 18 5
      libc/stdlib/stdlib.c

+ 9 - 1
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;

+ 1 - 1
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

+ 7 - 0
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"

+ 18 - 5
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