Skip to content

Commit cfce6eb

Browse files
committed
add support for C11 Annex K qsort_s()
standard defined re-entrant variant of qsort(). Unfortunately, Annex K is optional.
1 parent 6568e9a commit cfce6eb

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

.github/workflows/dev-short-tests.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ jobs:
693693
- name: Install musl-tools
694694
run: |
695695
sudo apt install -y musl-tools
696-
- name: Compile the project with musl-gcc
696+
- name: Compile with musl-gcc and test-zstd
697697
run: |
698698
CC=musl-gcc CFLAGS="-Werror -O3" CPPFLAGS=-DZDICT_QSORT=ZDICT_QSORT_C90 make -j -C tests test-zstd V=1
699699

lib/dictBuilder/cover.c

+15-6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
# endif
3030
#endif
3131

32+
#define __STDC_WANT_LIB_EXT1__ 1 /* request C11 Annex K, which includes qsort_s() */
33+
3234
#include <stdio.h> /* fprintf */
3335
#include <stdlib.h> /* malloc, free, qsort_r */
3436

@@ -68,16 +70,19 @@
6870
#define ZDICT_QSORT_C90 ZDICT_QSORT_MIN
6971
#define ZDICT_QSORT_GNU 1
7072
#define ZDICT_QSORT_APPLE 2
71-
#define ZDICT_QSORT_MSVC ZDICT_QSORT_MAX
72-
#define ZDICT_QSORT_MAX 3
73+
#define ZDICT_QSORT_MSVC 3
74+
#define ZDICT_QSORT_C11 ZDICT_QSORT_MAX
75+
#define ZDICT_QSORT_MAX 4
7376

7477
#ifndef ZDICT_QSORT
7578
# if defined(__APPLE__)
7679
# define ZDICT_QSORT ZDICT_QSORT_APPLE /* uses qsort_r() with a different order for parameters */
7780
# elif defined(_GNU_SOURCE)
7881
# define ZDICT_QSORT ZDICT_QSORT_GNU /* uses qsort_r() */
7982
# elif defined(_WIN32) && defined(_MSC_VER)
80-
# define ZDICT_QSORT ZDICT_QSORT_MSVC /* uses qsort_s() */
83+
# define ZDICT_QSORT ZDICT_QSORT_MSVC /* uses qsort_s() with a different order for parameters */
84+
# elif defined(STDC_LIB_EXT1) && (STDC_LIB_EXT1 > 0) /* C11 Annex K */
85+
# define ZDICT_QSORT ZDICT_QSORT_C11 /* uses qsort_s() */
8186
# else
8287
# define ZDICT_QSORT ZDICT_QSORT_C90 /* uses standard qsort() which is not re-entrant (requires global variable) */
8388
# endif
@@ -204,7 +209,7 @@ static U32 *COVER_map_at(COVER_map_t *map, U32 key) {
204209
*/
205210
static void COVER_map_remove(COVER_map_t *map, U32 key) {
206211
U32 i = COVER_map_index(map, key);
207-
COVER_map_pair_t *del = &map->data[i];
212+
COVER_map_pair_t* del = &map->data[i];
208213
U32 shift = 1;
209214
if (del->value == MAP_EMPTY_VALUE) {
210215
return;
@@ -307,7 +312,7 @@ static int COVER_cmp8(COVER_ctx_t *ctx, const void *lp, const void *rp) {
307312
*/
308313
#if (ZDICT_QSORT == ZDICT_QSORT_MSVC) || (ZDICT_QSORT == ZDICT_QSORT_APPLE)
309314
static int WIN_CDECL COVER_strict_cmp(void* g_coverCtx, const void* lp, const void* rp) {
310-
#elif (ZDICT_QSORT == ZDICT_QSORT_GNU)
315+
#elif (ZDICT_QSORT == ZDICT_QSORT_GNU) || (ZDICT_QSORT == ZDICT_QSORT_C11)
311316
static int COVER_strict_cmp(const void *lp, const void *rp, void *g_coverCtx) {
312317
#else /* C90 fallback.*/
313318
static int COVER_strict_cmp(const void *lp, const void *rp) {
@@ -323,7 +328,7 @@ static int COVER_strict_cmp(const void *lp, const void *rp) {
323328
*/
324329
#if (ZDICT_QSORT == ZDICT_QSORT_MSVC) || (ZDICT_QSORT == ZDICT_QSORT_APPLE)
325330
static int WIN_CDECL COVER_strict_cmp8(void* g_coverCtx, const void* lp, const void* rp) {
326-
#elif (ZDICT_QSORT == ZDICT_QSORT_GNU)
331+
#elif (ZDICT_QSORT == ZDICT_QSORT_GNU) || (ZDICT_QSORT == ZDICT_QSORT_C11)
327332
static int COVER_strict_cmp8(const void *lp, const void *rp, void *g_coverCtx) {
328333
#else /* C90 fallback.*/
329334
static int COVER_strict_cmp8(const void *lp, const void *rp) {
@@ -355,6 +360,10 @@ static void stableSort(COVER_ctx_t *ctx)
355360
qsort_s(ctx->suffix, ctx->suffixSize, sizeof(U32),
356361
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
357362
ctx);
363+
#elif (ZDICT_QSORT == ZDICT_QSORT_C11)
364+
qsort_s(ctx->suffix, ctx->suffixSize, sizeof(U32),
365+
(ctx->d <= 8 ? &COVER_strict_cmp8 : &COVER_strict_cmp),
366+
ctx);
358367
#elif defined(__OpenBSD__)
359368
/* On OpenBSD, qsort() is not guaranteed to be stable, their mergesort() is.
360369
* Note(@cyan): qsort() is never guaranteed to be stable,

0 commit comments

Comments
 (0)