mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-06 03:18:13 +00:00

committed by
Ozkan Sezer

parent
5a26b26880
commit
4800edfa0c
@@ -65,7 +65,7 @@ void SDL_qsort(void *base, size_t nmemb, size_t size, SDL_CompareCallback compar
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
This code came from Gareth McCaughan, under the zlib license.
|
This code came from Gareth McCaughan, under the zlib license.
|
||||||
Specifically this: https://www.mccaughan.org.uk/software/qsort.c-1.15
|
Specifically this: https://www.mccaughan.org.uk/software/qsort.c-1.16
|
||||||
|
|
||||||
Everything below this comment until the HAVE_QSORT #endif was from Gareth
|
Everything below this comment until the HAVE_QSORT #endif was from Gareth
|
||||||
(any minor changes will be noted inline).
|
(any minor changes will be noted inline).
|
||||||
@@ -112,7 +112,7 @@ benefit!
|
|||||||
* Gareth McCaughan
|
* Gareth McCaughan
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Copyright (c) 1998-2016 Gareth McCaughan
|
/* Copyright (c) 1998-2021 Gareth McCaughan
|
||||||
*
|
*
|
||||||
* This software is provided 'as-is', without any express or implied
|
* This software is provided 'as-is', without any express or implied
|
||||||
* warranty. In no event will the authors be held liable for any
|
* warranty. In no event will the authors be held liable for any
|
||||||
@@ -148,17 +148,23 @@ benefit!
|
|||||||
* (pre-insertion-sort messed up).
|
* (pre-insertion-sort messed up).
|
||||||
* Disable DEBUG_QSORT by default.
|
* Disable DEBUG_QSORT by default.
|
||||||
* Tweak comments very slightly.
|
* Tweak comments very slightly.
|
||||||
|
* 2021-02-20 v1.16 Fix bug kindly reported by Ray Gardner
|
||||||
|
* (error in recursion leading to possible
|
||||||
|
* stack overflow).
|
||||||
|
* When checking alignment, avoid casting
|
||||||
|
* pointer to possibly-smaller integer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* BEGIN SDL CHANGE ... commented this out with an #if 0 block. --ryan. */
|
/* BEGIN SDL CHANGE ... commented this out with an #if 0 block. --ryan. */
|
||||||
#if 0
|
#if 0
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#undef DEBUG_QSORT
|
#undef DEBUG_QSORT
|
||||||
|
|
||||||
static char _ID[]="<qsort.c gjm 1.15 2016-03-10>";
|
static char _ID[]="<qsort.c gjm 1.16 2021-02-20>";
|
||||||
#endif
|
#endif
|
||||||
/* END SDL CHANGE ... commented this out with an #if 0 block. --ryan. */
|
/* END SDL CHANGE ... commented this out with an #if 0 block. --ryan. */
|
||||||
|
|
||||||
@@ -168,7 +174,8 @@ static char _ID[]="<qsort.c gjm 1.15 2016-03-10>";
|
|||||||
#define WORD_BYTES sizeof(int)
|
#define WORD_BYTES sizeof(int)
|
||||||
|
|
||||||
/* How big does our stack need to be? Answer: one entry per
|
/* How big does our stack need to be? Answer: one entry per
|
||||||
* bit in a |size_t|.
|
* bit in a |size_t|. (Actually, a bit less because we don't
|
||||||
|
* recurse all the way down to size-1 subarrays.)
|
||||||
*/
|
*/
|
||||||
#define STACK_SIZE (8*sizeof(size_t))
|
#define STACK_SIZE (8*sizeof(size_t))
|
||||||
|
|
||||||
@@ -207,11 +214,12 @@ typedef struct { char * first; char * last; } stack_entry;
|
|||||||
* on large datasets for locality-of-reference reasons,
|
* on large datasets for locality-of-reference reasons,
|
||||||
* but it makes the code much nastier and increases
|
* but it makes the code much nastier and increases
|
||||||
* bookkeeping overhead.
|
* bookkeeping overhead.
|
||||||
* 2. We always save the shorter and get to work on the
|
* 2. We always save the longer and get to work on the
|
||||||
* longer. This guarantees that every time we push
|
* shorter. This guarantees that whenever we push
|
||||||
* an item onto the stack its size is <= 1/2 of that
|
* a k'th entry onto the stack we are about to get
|
||||||
* of its parent; so the stack can't need more than
|
* working on something of size <= N/2^k where N is
|
||||||
* log_2(max-array-size) entries.
|
* the original array size; so the stack can't need
|
||||||
|
* more than log_2(max-array-size) entries.
|
||||||
* 3. We choose a pivot by looking at the first, last
|
* 3. We choose a pivot by looking at the first, last
|
||||||
* and middle elements. We arrange them into order
|
* and middle elements. We arrange them into order
|
||||||
* because it's easy to do that in conjunction with
|
* because it's easy to do that in conjunction with
|
||||||
@@ -273,8 +281,8 @@ typedef struct { char * first; char * last; } stack_entry;
|
|||||||
if (r>=Trunc) doRight \
|
if (r>=Trunc) doRight \
|
||||||
else pop \
|
else pop \
|
||||||
} \
|
} \
|
||||||
else if (l<=r) { pushLeft; doRight } \
|
else if (l<=r) { pushRight; doLeft } \
|
||||||
else if (r>=Trunc) { pushRight; doLeft }\
|
else if (r>=Trunc) { pushLeft; doRight }\
|
||||||
else doLeft \
|
else doLeft \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,7 +533,7 @@ fprintf(stderr, "after partitioning first=#%lu last=#%lu\n", (first-(char*)base)
|
|||||||
extern void qsortG(void *base, size_t nmemb, size_t size, SDL_CompareCallback compare) {
|
extern void qsortG(void *base, size_t nmemb, size_t size, SDL_CompareCallback compare) {
|
||||||
|
|
||||||
if (nmemb<=1) return;
|
if (nmemb<=1) return;
|
||||||
if (((size_t)base|size)&(WORD_BYTES-1))
|
if (((uintptr_t)base|size)&(WORD_BYTES-1))
|
||||||
qsort_nonaligned(base,nmemb,size,compare);
|
qsort_nonaligned(base,nmemb,size,compare);
|
||||||
else if (size!=WORD_BYTES)
|
else if (size!=WORD_BYTES)
|
||||||
qsort_aligned(base,nmemb,size,compare);
|
qsort_aligned(base,nmemb,size,compare);
|
||||||
|
Reference in New Issue
Block a user