NeoMutt  2021-02-05-666-ge300cd
Teaching an old dog new tricks
DOXYGEN
qsort_r.c
Go to the documentation of this file.
1 
29 #include "config.h"
30 #include <stddef.h>
31 #include <stdlib.h>
32 #include "qsort_r.h"
33 
34 typedef int (*qsort_compar_t)(const void *a, const void *b);
35 
36 #if !defined(HAVE_QSORT_S) && !defined(HAVE_QSORT_R)
37 #include <assert.h>
41 static void *global_data = NULL;
42 
51 static int relay_compar(const void *a, const void *b)
52 {
53  return global_compar(a, b, global_data);
54 }
55 #endif
56 
68 void mutt_qsort_r(void *base, size_t nmemb, size_t size, qsort_r_compar_t compar, void *arg)
69 {
70 #ifdef HAVE_QSORT_S
71  /* FreeBSD 13, where qsort_r had incompatible signature but qsort_s works */
72  qsort_s(base, nmemb, size, compar, arg);
73 #elif defined(HAVE_QSORT_R)
74  /* glibc, POSIX (https://www.austingroupbugs.net/view.php?id=900) */
75  qsort_r(base, nmemb, size, compar, arg);
76 #else
77  /* This fallback is not re-entrant. */
78  assert((global_compar == NULL) && (global_data == NULL));
79  global_compar = compar;
80  global_data = arg;
81  qsort(base, nmemb, size, relay_compar);
82  global_compar = NULL;
83  global_data = NULL;
84 #endif
85 }
Context-free sorting function.
int(* qsort_r_compar_t)(const void *a, const void *b, void *arg)
Definition: qsort_r.h:28
void mutt_qsort_r(void *base, size_t nmemb, size_t size, qsort_r_compar_t compar, void *arg)
Sort an array, where the comparator has access to opaque data rather than requiring global variables...
Definition: qsort_r.c:68
static qsort_r_compar_t global_compar
Original comparator in fallback implementation.
Definition: qsort_r.c:39
static int relay_compar(const void *a, const void *b)
Shim to pass context through to real comparator.
Definition: qsort_r.c:51
static void * global_data
Original opaque data in fallback implementation.
Definition: qsort_r.c:41
int(* qsort_compar_t)(const void *a, const void *b)
Definition: qsort_r.c:34