Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/stdlib/qsort.c
Show All 29 Lines | |||||
#if defined(LIBC_SCCS) && !defined(lint) | #if defined(LIBC_SCCS) && !defined(lint) | ||||
static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93"; | static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93"; | ||||
#endif /* LIBC_SCCS and not lint */ | #endif /* LIBC_SCCS and not lint */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#ifdef I_AM_QSORT_R | #if defined(I_AM_QSORT_R) | ||||
typedef int cmp_t(void *, const void *, const void *); | typedef int cmp_t(void *, const void *, const void *); | ||||
#elif defined(I_AM_GLIBC_QSORT_R) | |||||
typedef int cmp_t(const void *, const void *, void *); | |||||
#else | #else | ||||
typedef int cmp_t(const void *, const void *); | typedef int cmp_t(const void *, const void *); | ||||
#endif | #endif | ||||
static inline char *med3(char *, char *, char *, cmp_t *, void *); | static inline char *med3(char *, char *, char *, cmp_t *, void *); | ||||
static inline void swapfunc(char *, char *, int, int, int); | static inline void swapfunc(char *, char *, int, int, int); | ||||
#define MIN(a, b) ((a) < (b) ? a : b) | #define MIN(a, b) ((a) < (b) ? a : b) | ||||
Show All 36 Lines | if (swaptype_long == 0) { \ | ||||
*(int *)(a) = *(int *)(b); \ | *(int *)(a) = *(int *)(b); \ | ||||
*(int *)(b) = t; \ | *(int *)(b) = t; \ | ||||
} else \ | } else \ | ||||
swapfunc(a, b, es, swaptype_long, swaptype_int) | swapfunc(a, b, es, swaptype_long, swaptype_int) | ||||
#define vecswap(a, b, n) \ | #define vecswap(a, b, n) \ | ||||
if ((n) > 0) swapfunc(a, b, n, swaptype_long, swaptype_int) | if ((n) > 0) swapfunc(a, b, n, swaptype_long, swaptype_int) | ||||
#ifdef I_AM_QSORT_R | #if defined(I_AM_QSORT_R) | ||||
#define CMP(t, x, y) (cmp((t), (x), (y))) | #define CMP(t, x, y) (cmp((t), (x), (y))) | ||||
#elif defined(I_AM_GLIBC_QSORT_R) | |||||
#define CMP(t, x, y) (cmp((x), (y), (t))) | |||||
#else | #else | ||||
#define CMP(t, x, y) (cmp((x), (y))) | #define CMP(t, x, y) (cmp((x), (y))) | ||||
#endif | #endif | ||||
static inline char * | static inline char * | ||||
med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk | med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk | ||||
#ifndef I_AM_QSORT_R | #if !defined(I_AM_QSORT_R) && !defined(I_AM_GLIBC_QSORT_R) | ||||
__unused | __unused | ||||
#endif | #endif | ||||
) | ) | ||||
{ | { | ||||
return CMP(thunk, a, b) < 0 ? | return CMP(thunk, a, b) < 0 ? | ||||
(CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) | (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) | ||||
:(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); | :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c )); | ||||
} | } | ||||
#ifdef I_AM_QSORT_R | #if defined(I_AM_QSORT_R) | ||||
void | void | ||||
qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) | __freebsd11_qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) | ||||
#elif defined(I_AM_GLIBC_QSORT_R) | |||||
void | |||||
(qsort_r)(void *a, size_t n, size_t es, cmp_t *cmp, void *thunk) | |||||
#else | #else | ||||
#define thunk NULL | #define thunk NULL | ||||
void | void | ||||
qsort(void *a, size_t n, size_t es, cmp_t *cmp) | qsort(void *a, size_t n, size_t es, cmp_t *cmp) | ||||
#endif | #endif | ||||
{ | { | ||||
char *pa, *pb, *pc, *pd, *pl, *pm, *pn; | char *pa, *pb, *pc, *pd, *pl, *pm, *pn; | ||||
size_t d, r; | size_t d, r; | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | loop: SWAPINIT(long, a, es); | ||||
} | } | ||||
pn = (char *)a + n * es; | pn = (char *)a + n * es; | ||||
r = MIN(pa - (char *)a, pb - pa); | r = MIN(pa - (char *)a, pb - pa); | ||||
vecswap(a, pb - r, r); | vecswap(a, pb - r, r); | ||||
r = MIN(pd - pc, pn - pd - es); | r = MIN(pd - pc, pn - pd - es); | ||||
vecswap(pb, pn - r, r); | vecswap(pb, pn - r, r); | ||||
if ((r = pb - pa) > es) | if ((r = pb - pa) > es) | ||||
#ifdef I_AM_QSORT_R | #if defined(I_AM_QSORT_R) | ||||
qsort_r(a, r / es, es, thunk, cmp); | __freebsd11_qsort_r(a, r / es, es, thunk, cmp); | ||||
#elif defined(I_AM_GLIBC_QSORT_R) | |||||
(qsort_r)(a, r / es, es, cmp, thunk); | |||||
#else | #else | ||||
qsort(a, r / es, es, cmp); | qsort(a, r / es, es, cmp); | ||||
#endif | #endif | ||||
if ((r = pd - pc) > es) { | if ((r = pd - pc) > es) { | ||||
/* Iterate rather than recurse to save stack space */ | /* Iterate rather than recurse to save stack space */ | ||||
a = pn - r; | a = pn - r; | ||||
n = r / es; | n = r / es; | ||||
goto loop; | goto loop; | ||||
} | } | ||||
/* qsort(pn - r, r / es, es, cmp);*/ | /* qsort(pn - r, r / es, es, cmp);*/ | ||||
} | } | ||||
#if defined(I_AM_QSORT_R) | |||||
__sym_compat(dirname, __freebsd11_qsort_r, FBSD_1.0); | |||||
cem: s/dirname/qsort_r/. Will be fixed in the next patch. | |||||
#endif |
s/dirname/qsort_r/. Will be fixed in the next patch.