mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-10-02 16:23:57 +08:00
stdlib: qsort and bsearch changes.
- Always use internal qsort and bsearch implementation. - add "_r" reentrant versions. The reasons for always using the internal versions is that the C runtime versions' callbacks are not mark STDCALL, so we would have add bridge functions for them anyhow, The C runtime qsort_r/qsort_s have different orders of arguments on different platforms, and most importantly: qsort() isn't a stable sort, and isn't guaranteed to give the same ordering for two objects marked as equal by the callback...as such, Visual Studio and glibc can give different sort results for the same data set...in this sense, having one piece of code shared on all platforms makes sense here, for reliabillity. bsearch does not have a standard _r version at all, and suffers from the same SDLCALL concern. Since the code is simple and we would have to work around the C runtime, it's easier to just go with the built-in function and remove all the CMake C runtime tests. Fixes #9159.
This commit is contained in:
+1
-2
@@ -1058,7 +1058,7 @@ if(SDL_LIBC)
|
||||
|
||||
set(symbols_to_check
|
||||
abs acos acosf asin asinf atan atan2 atan2f atanf atof atoi
|
||||
bcopy bsearch
|
||||
bcopy
|
||||
calloc ceil ceilf copysign copysignf cos cosf
|
||||
_Exit exp expf
|
||||
fabs fabsf floor floorf fmod fmodf fopen64 free fseeko fseeko64
|
||||
@@ -1067,7 +1067,6 @@ if(SDL_LIBC)
|
||||
log log10 log10f logf lround lroundf _ltoa
|
||||
malloc memcmp memcpy memmove memset modf modff
|
||||
pow powf putenv
|
||||
qsort
|
||||
realloc rindex round roundf
|
||||
scalbn scalbnf setenv sin sinf sqr sqrt sqrtf sscanf strchr
|
||||
strcmp strlcat strlcpy strlen strncmp strnlen
|
||||
|
||||
@@ -42,6 +42,7 @@ words = [
|
||||
'atanf',
|
||||
'atof',
|
||||
'atoi',
|
||||
'bsearch',
|
||||
'calloc',
|
||||
'ceil',
|
||||
'ceilf',
|
||||
@@ -90,6 +91,8 @@ words = [
|
||||
'pow',
|
||||
'powf',
|
||||
'qsort',
|
||||
'qsort_r',
|
||||
'qsort_s',
|
||||
'realloc',
|
||||
'round',
|
||||
'roundf',
|
||||
|
||||
@@ -498,6 +498,9 @@ extern DECLSPEC int SDLCALL SDL_setenv(const char *name, const char *value, int
|
||||
extern DECLSPEC void SDLCALL SDL_qsort(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *));
|
||||
extern DECLSPEC void * SDLCALL SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (const void *, const void *));
|
||||
|
||||
extern DECLSPEC void SDLCALL SDL_qsort_r(void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (void *, const void *, const void *), void *userdata);
|
||||
extern DECLSPEC void * SDLCALL SDL_bsearch_r(const void *key, const void *base, size_t nmemb, size_t size, int (SDLCALL *compare) (void *, const void *, const void *), void *userdata);
|
||||
|
||||
extern DECLSPEC int SDLCALL SDL_abs(int x);
|
||||
|
||||
/* NOTE: these double-evaluate their arguments, so you should never have side effects in the parameters */
|
||||
|
||||
@@ -82,8 +82,6 @@
|
||||
#cmakedefine HAVE_PUTENV 1
|
||||
#cmakedefine HAVE_UNSETENV 1
|
||||
#endif
|
||||
#cmakedefine HAVE_QSORT 1
|
||||
#cmakedefine HAVE_BSEARCH 1
|
||||
#cmakedefine HAVE_ABS 1
|
||||
#cmakedefine HAVE_BCOPY 1
|
||||
#cmakedefine HAVE_MEMSET 1
|
||||
|
||||
@@ -63,8 +63,6 @@
|
||||
#define HAVE_PUTENV 1
|
||||
#define HAVE_SETENV 1
|
||||
#define HAVE_UNSETENV 1
|
||||
#define HAVE_QSORT 1
|
||||
#define HAVE_BSEARCH 1
|
||||
#define HAVE_ABS 1
|
||||
#define HAVE_BCOPY 1
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
@@ -65,8 +65,6 @@
|
||||
#define HAVE_SETENV 1
|
||||
#define HAVE_PUTENV 1
|
||||
#define HAVE_UNSETENV 1
|
||||
#define HAVE_QSORT 1
|
||||
#define HAVE_BSEARCH 1
|
||||
#define HAVE_ABS 1
|
||||
#define HAVE_BCOPY 1
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
@@ -55,8 +55,6 @@
|
||||
#define HAVE_PUTENV 1
|
||||
#define HAVE_SETENV 1
|
||||
#define HAVE_UNSETENV 1
|
||||
#define HAVE_QSORT 1
|
||||
#define HAVE_BSEARCH 1
|
||||
#define HAVE_ABS 1
|
||||
#define HAVE_BCOPY 1
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
@@ -59,8 +59,6 @@
|
||||
#define HAVE_SETENV 1
|
||||
#define HAVE_PUTENV 1
|
||||
#define HAVE_UNSETENV 1
|
||||
#define HAVE_QSORT 1
|
||||
#define HAVE_BSEARCH 1
|
||||
#define HAVE_ABS 1
|
||||
#define HAVE_BCOPY 1
|
||||
#define HAVE_MEMSET 1
|
||||
|
||||
@@ -135,8 +135,6 @@ typedef unsigned int uintptr_t;
|
||||
#define HAVE_CALLOC 1
|
||||
#define HAVE_REALLOC 1
|
||||
#define HAVE_FREE 1
|
||||
#define HAVE_QSORT 1
|
||||
#define HAVE_BSEARCH 1
|
||||
#define HAVE_ABS 1
|
||||
#define HAVE_MEMSET 1
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
@@ -76,8 +76,6 @@
|
||||
#define HAVE_CALLOC 1
|
||||
#define HAVE_REALLOC 1
|
||||
#define HAVE_FREE 1
|
||||
#define HAVE_QSORT 1
|
||||
#define HAVE_BSEARCH 1
|
||||
#define HAVE_ABS 1
|
||||
#define HAVE_MEMSET 1
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
@@ -76,8 +76,6 @@
|
||||
#define HAVE_CALLOC 1
|
||||
#define HAVE_REALLOC 1
|
||||
#define HAVE_FREE 1
|
||||
#define HAVE_QSORT 1
|
||||
#define HAVE_BSEARCH 1
|
||||
#define HAVE_ABS 1
|
||||
#define HAVE_MEMSET 1
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
@@ -76,8 +76,6 @@
|
||||
#define HAVE_CALLOC 1
|
||||
#define HAVE_REALLOC 1
|
||||
#define HAVE_FREE 1
|
||||
#define HAVE_QSORT 1
|
||||
#define HAVE_BSEARCH 1
|
||||
#define HAVE_ABS 1
|
||||
#define HAVE_MEMSET 1
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
@@ -971,6 +971,8 @@ SDL3_0.0.0 {
|
||||
SDL_CloseCamera;
|
||||
SDL_GetCameraPermissionState;
|
||||
SDL_GetCameraDevicePosition;
|
||||
SDL_qsort_r;
|
||||
SDL_bsearch_r;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
};
|
||||
|
||||
@@ -996,3 +996,5 @@
|
||||
#define SDL_CloseCamera SDL_CloseCamera_REAL
|
||||
#define SDL_GetCameraPermissionState SDL_GetCameraPermissionState_REAL
|
||||
#define SDL_GetCameraDevicePosition SDL_GetCameraDevicePosition_REAL
|
||||
#define SDL_qsort_r SDL_qsort_r_REAL
|
||||
#define SDL_bsearch_r SDL_bsearch_r_REAL
|
||||
|
||||
@@ -1021,3 +1021,5 @@ SDL_DYNAPI_PROC(int,SDL_ReleaseCameraFrame,(SDL_Camera *a, SDL_Surface *b),(a,b)
|
||||
SDL_DYNAPI_PROC(void,SDL_CloseCamera,(SDL_Camera *a),(a),)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetCameraPermissionState,(SDL_Camera *a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_CameraPosition,SDL_GetCameraDevicePosition,(SDL_CameraDeviceID a),(a),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_qsort_r,(void *a, size_t b, size_t c, int (SDLCALL *d)(void *, const void *, const void *), void *e),(a,b,c,d,e),)
|
||||
SDL_DYNAPI_PROC(void*,SDL_bsearch_r,(const void *a, const void *b, size_t c, size_t d, int (SDLCALL *e)(void *, const void *, const void *), void *f),(a,b,c,d,e,f),return)
|
||||
|
||||
+65
-62
File diff suppressed because it is too large
Load Diff
+19
-1
@@ -14,6 +14,8 @@
|
||||
#include <SDL3/SDL_main.h>
|
||||
#include <SDL3/SDL_test.h>
|
||||
|
||||
static int a_global_var = 77;
|
||||
|
||||
static int SDLCALL
|
||||
num_compare(const void *_a, const void *_b)
|
||||
{
|
||||
@@ -22,20 +24,36 @@ num_compare(const void *_a, const void *_b)
|
||||
return (a < b) ? -1 : ((a > b) ? 1 : 0);
|
||||
}
|
||||
|
||||
static int SDLCALL
|
||||
num_compare_r(void *userdata, const void *a, const void *b)
|
||||
{
|
||||
if (userdata != &a_global_var) {
|
||||
SDL_Log("Uhoh, invalid userdata during qsort!");
|
||||
}
|
||||
return num_compare(a, b);
|
||||
}
|
||||
|
||||
static void
|
||||
test_sort(const char *desc, int *nums, const int arraylen)
|
||||
{
|
||||
static int nums_copy[1024 * 100];
|
||||
int i;
|
||||
int prev;
|
||||
|
||||
SDL_assert(SDL_arraysize(nums_copy) >= arraylen);
|
||||
|
||||
SDL_Log("test: %s arraylen=%d", desc, arraylen);
|
||||
|
||||
SDL_memcpy(nums_copy, nums, arraylen * sizeof (*nums));
|
||||
|
||||
SDL_qsort(nums, arraylen, sizeof(nums[0]), num_compare);
|
||||
SDL_qsort_r(nums_copy, arraylen, sizeof(nums[0]), num_compare_r, &a_global_var);
|
||||
|
||||
prev = nums[0];
|
||||
for (i = 1; i < arraylen; i++) {
|
||||
const int val = nums[i];
|
||||
if (val < prev) {
|
||||
const int val2 = nums_copy[i];
|
||||
if ((val < prev) || (val != val2)) {
|
||||
SDL_Log("sort is broken!");
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user