Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/stdlib/qsort.c
Show All 36 Lines | |||||
#include <errno.h> | #include <errno.h> | ||||
#include <stdint.h> | #include <stdint.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include "libc_private.h" | #include "libc_private.h" | ||||
#if defined(I_AM_QSORT_R) | #if defined(I_AM_QSORT_R) | ||||
typedef int cmp_t(const void *, const void *, void *); | |||||
#elif defined(I_AM_QSORT_R_COMPAT) | |||||
typedef int cmp_t(void *, const void *, const void *); | typedef int cmp_t(void *, const void *, const void *); | ||||
#elif defined(I_AM_QSORT_S) | #elif defined(I_AM_QSORT_S) | ||||
typedef int cmp_t(const void *, const void *, void *); | 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 *); | ||||
Show All 14 Lines | do { | ||||
*b++ = t; | *b++ = t; | ||||
} while (--es > 0); | } while (--es > 0); | ||||
} | } | ||||
#define vecswap(a, b, n) \ | #define vecswap(a, b, n) \ | ||||
if ((n) > 0) swapfunc(a, b, n) | if ((n) > 0) swapfunc(a, b, n) | ||||
#if defined(I_AM_QSORT_R) | #if defined(I_AM_QSORT_R) | ||||
#define CMP(t, x, y) (cmp((x), (y), (t))) | |||||
#elif defined(I_AM_QSORT_R_COMPAT) | |||||
#define CMP(t, x, y) (cmp((t), (x), (y))) | #define CMP(t, x, y) (cmp((t), (x), (y))) | ||||
#elif defined(I_AM_QSORT_S) | #elif defined(I_AM_QSORT_S) | ||||
#define CMP(t, x, y) (cmp((x), (y), (t))) | #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 | ||||
#if !defined(I_AM_QSORT_R) && !defined(I_AM_QSORT_S) | #if !defined(I_AM_QSORT_R) && !defined(I_AM_QSORT_R_COMPAT) && !defined(I_AM_QSORT_S) | ||||
__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 )); | ||||
} | } | ||||
/* | /* | ||||
* The actual qsort() implementation is static to avoid preemptible calls when | * The actual qsort() implementation is static to avoid preemptible calls when | ||||
* recursing. Also give them different names for improved debugging. | * recursing. Also give them different names for improved debugging. | ||||
*/ | */ | ||||
#if defined(I_AM_QSORT_R) | #if defined(I_AM_QSORT_R) | ||||
#define local_qsort local_qsort_r | #define local_qsort local_qsort_r | ||||
#elif defined(I_AM_QSORT_R_COMPAT) | |||||
#define local_qsort local_qsort_r_compat | |||||
#elif defined(I_AM_QSORT_S) | #elif defined(I_AM_QSORT_S) | ||||
#define local_qsort local_qsort_s | #define local_qsort local_qsort_s | ||||
#endif | #endif | ||||
static void | static void | ||||
local_qsort(void *a, size_t n, size_t es, cmp_t *cmp, void *thunk) | local_qsort(void *a, size_t n, size_t es, cmp_t *cmp, void *thunk) | ||||
{ | { | ||||
char *pa, *pb, *pc, *pd, *pl, *pm, *pn; | char *pa, *pb, *pc, *pd, *pl, *pm, *pn; | ||||
size_t d1, d2; | size_t d1, d2; | ||||
▲ Show 20 Lines • Show All 98 Lines • ▼ Show 20 Lines | if (d1 > es) { | ||||
n = d1 / es; | n = d1 / es; | ||||
goto loop; | goto loop; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
#if defined(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) | (qsort_r)(void *a, size_t n, size_t es, cmp_t *cmp, void *thunk) | ||||
kib: Why not put this into qsort_r_compat.c ? | |||||
{ | { | ||||
local_qsort_r(a, n, es, cmp, thunk); | local_qsort_r(a, n, es, cmp, thunk); | ||||
} | |||||
#elif defined(I_AM_QSORT_R_COMPAT) | |||||
void | |||||
__qsort_r_compat(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) | |||||
{ | |||||
local_qsort_r_compat(a, n, es, cmp, thunk); | |||||
} | } | ||||
#elif defined(I_AM_QSORT_S) | #elif defined(I_AM_QSORT_S) | ||||
errno_t | errno_t | ||||
qsort_s(void *a, rsize_t n, rsize_t es, cmp_t *cmp, void *thunk) | qsort_s(void *a, rsize_t n, rsize_t es, cmp_t *cmp, void *thunk) | ||||
{ | { | ||||
if (n > RSIZE_MAX) { | if (n > RSIZE_MAX) { | ||||
__throw_constraint_handler_s("qsort_s : n > RSIZE_MAX", EINVAL); | __throw_constraint_handler_s("qsort_s : n > RSIZE_MAX", EINVAL); | ||||
return (EINVAL); | return (EINVAL); | ||||
Show All 26 Lines |
Why not put this into qsort_r_compat.c ?