From 515d54433138596e81267237542bd9168b8cc787 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Mon, 7 Nov 2011 09:24:30 +0100 Subject: stdlib: add qsort_r GNU extension like qsort but takes a 3 parameter comparision function. Signed-off-by: Bernhard Reutner-Fischer --- include/stdlib.h | 10 +++++++++- libc/stdlib/Makefile.in | 2 +- libc/stdlib/qsort_r.c | 7 +++++++ libc/stdlib/stdlib.c | 23 ++++++++++++++++++----- 4 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 libc/stdlib/qsort_r.c 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 + * + * 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 -- cgit v1.2.3