I tried to write a portable version of qsort_r / qsort_s (called sort_r), shown in the example. I also put this code in the git repository https://github.com/noporpoise/sort_r )
struct sort_r_data { void *arg; int (*compar)(const void *a1, const void *a2, void *aarg); }; int sort_r_arg_swap(void *s, const void *aa, const void *bb) { struct sort_r_data *ss = (struct sort_r_data*)s; return (ss->compar)(aa, bb, ss->arg); } void sort_r(void *base, size_t nel, size_t width, int (*compar)(const void *a1, const void *a2, void *aarg), void *arg) { #if (defined _GNU_SOURCE || defined __GNU__ || defined __linux__) qsort_r(base, nel, width, compar, arg); #elif (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || \ defined __FREEBSD__ || defined __BSD__ || \ defined OpenBSD3_1 || defined OpenBSD3_9) struct sort_r_data tmp; tmp.arg = arg; tmp.compar = compar; qsort_r(base, nel, width, &tmp, &sort_r_arg_swap); #elif (defined _WIN32 || defined _WIN64 || defined __WINDOWS__) struct sort_r_data tmp = {arg, compar}; qsort_s(*base, nel, width, &sort_r_arg_swap, &tmp); #else #error Cannot detect operating system #endif }
Usage example:
Compile / start / exit:
$ gcc -Wall -Wextra -pedantic -o sort_r sort_r.c $ ./sort_r 1 2 3 4 5 10 14 18 19 29 28 27 25 21 20 34 35 100
I tested mac and linux. Update this code if you notice errors / improvements. You can use this code as you wish.
Isaac turner
source share