From 2be18f340f6c613de07a0ed373065a9a78ede193 Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Mon, 27 Oct 2025 22:04:16 +0100
Subject: [PATCH] testqsort: use SDLTest_TestSuite
---
test/CMakeLists.txt | 3 +
test/testqsort.c | 529 ++++++++++++++++++++++++++++++++++++++------
2 files changed, 465 insertions(+), 67 deletions(-)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 800e0f6357940..4049da9421bc4 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -420,6 +420,9 @@ add_sdl_test_executable(testrendercopyex NEEDS_RESOURCES TESTUTILS SOURCES testr
add_sdl_test_executable(testmessage SOURCES testmessage.c)
add_sdl_test_executable(testdisplayinfo SOURCES testdisplayinfo.c)
add_sdl_test_executable(testqsort NONINTERACTIVE SOURCES testqsort.c)
+if(EMSCRIPTEN)
+ target_link_options(testqsort PRIVATE -sALLOW_MEMORY_GROWTH)
+endif()
add_sdl_test_executable(testbounds NONINTERACTIVE SOURCES testbounds.c)
add_sdl_test_executable(testcustomcursor SOURCES testcustomcursor.c)
add_sdl_test_executable(testvulkan NO_C90 SOURCES testvulkan.c)
diff --git a/test/testqsort.c b/test/testqsort.c
index 6230e74657952..3e419bccf5714 100644
--- a/test/testqsort.c
+++ b/test/testqsort.c
@@ -14,10 +14,20 @@
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_test.h>
+typedef struct {
+ Uint8 major;
+ Uint8 minor;
+ Uint8 micro;
+} VersionTuple;
+
static int a_global_var = 77;
+static int (SDLCALL * global_compare_cbfn)(const void *_a, const void *_b);
+
+static unsigned long arraylens[16] = { 12, 1024 * 100 };
+static unsigned int count_arraylens = 2;
static int SDLCALL
-num_compare(const void *_a, const void *_b)
+compare_int(const void *_a, const void *_b)
{
const int a = *((const int *)_a);
const int b = *((const int *)_b);
@@ -25,51 +35,429 @@ num_compare(const void *_a, const void *_b)
}
static int SDLCALL
-num_compare_r(void *userdata, const void *a, const void *b)
+compare_float(const void *_a, const void *_b)
+{
+ const float a = *((const float *)_a);
+ const float b = *((const float *)_b);
+ return (a < b) ? -1 : ((a > b) ? 1 : 0);
+}
+
+static int SDLCALL
+compare_double(const void *_a, const void *_b)
+{
+ const double a = *((const double *)_a);
+ const double b = *((const double *)_b);
+ return (a < b) ? -1 : ((a > b) ? 1 : 0);
+}
+
+static int SDLCALL
+compare_intptr(const void *_a, const void *_b)
+{
+ const int* a = *((const int **)_a);
+ const int* b = *((const int **)_b);
+ return compare_int(a, b);
+}
+
+static int SDLCALL
+compare_version(const void *_a, const void *_b)
+{
+ const VersionTuple *a = ((const VersionTuple *)_a);
+ const VersionTuple *b = ((const VersionTuple *)_b);
+ int d;
+ d = (int)a->major - (int)b->major;
+ if (d != 0) {
+ return d;
+ }
+ d = (int)a->minor - (int)b->minor;
+ if (d != 0) {
+ return d;
+ }
+ return (int)a->micro - (int)b->micro;
+}
+
+static int SDLCALL
+generic_compare_r(void *userdata, const void *a, const void *b)
{
if (userdata != &a_global_var) {
- SDL_Log("Uhoh, invalid userdata during qsort!");
+ SDLTest_AssertCheck(userdata == &a_global_var, "User data of callback must be identical to global data");
}
- return num_compare(a, b);
+ return global_compare_cbfn(a, b);
}
-static void
-test_sort(const char *desc, int *nums, const int arraylen)
+#define STR2(S) "[" #S "] "
+#define STR(S) STR2(S)
+
+#define TEST_ARRAY_IS_SORTED(TYPE, ARRAY, SIZE, IS_LE) \
+ do { \
+ size_t sorted_index; \
+ Uint64 count_non_sorted = 0; \
+ for (sorted_index = 0; sorted_index < (SIZE) - 1; sorted_index++) { \
+ if (!IS_LE((ARRAY)[sorted_index], (ARRAY)[sorted_index + 1])) { \
+ count_non_sorted += 1; \
+ } \
+ } \
+ SDLTest_AssertCheck(count_non_sorted == 0, \
+ STR(TYPE) "Array (size=%d) is sorted (bad count=%" SDL_PRIu64 ")", (SIZE), count_non_sorted); \
+ } while (0)
+
+/* This test is O(n^2), so very slow (a hashmap can speed this up):
+ * - we cannot trust qsort
+ * - the arrays can contain duplicate items
+ * - the arrays are not int
+ */
+#define TEST_ARRAY_LOST_NO_ELEMENTS(TYPE, ORIGINAL, SORTED, SIZE, IS_SAME) \
+ do { \
+ size_t original_index; \
+ bool *original_seen = SDL_calloc((SIZE), sizeof(bool)); \
+ Uint64 lost_count = 0; \
+ SDL_assert(original_seen != NULL); \
+ for (original_index = 0; original_index < (SIZE); original_index++) { \
+ size_t sorted_index; \
+ for (sorted_index = 0; sorted_index < (SIZE); sorted_index++) { \
+ if (IS_SAME((ORIGINAL)[original_index], (SORTED)[sorted_index])) { \
+ original_seen[original_index] = true; \
+ break; \
+ } \
+ } \
+ } \
+ for (original_index = 0; original_index < (SIZE); original_index++) { \
+ if (!original_seen[original_index]) { \
+ SDLTest_AssertCheck(original_seen[original_index], \
+ STR(TYPE) "Element %d is missing in the sorted array", (int)original_index); \
+ lost_count += 1; \
+ } \
+ } \
+ SDLTest_AssertCheck(lost_count == 0, \
+ STR(TYPE) "No elements were lost (lost count=%" SDL_PRIu64 ")", lost_count); \
+ SDL_free(original_seen); \
+ } while (0)
+
+#define TEST_QSORT_ARRAY_GENERIC(TYPE, ARRAY, SIZE, QSORT_CALL, CHECK_ARRAY_ELEMS, IS_LE, WHAT) \
+ do { \
+ SDL_memcpy(sorted, (ARRAY), sizeof(TYPE) * (SIZE)); \
+ SDLTest_AssertPass(STR(TYPE) "About to call " WHAT "(%d, %d)", \
+ (int)(SIZE), (int)sizeof(TYPE)); \
+ QSORT_CALL; \
+ SDLTest_AssertPass(STR(TYPE) WHAT " finished"); \
+ TEST_ARRAY_IS_SORTED(TYPE, sorted, SIZE, IS_LE); \
+ SDLTest_AssertPass(STR(TYPE) "Verifying element preservation..."); \
+ CHECK_ARRAY_ELEMS(TYPE, sorted, (ARRAY), (SIZE)); \
+ } while (0)
+
+#define TEST_QSORT_ARRAY_QSORT(TYPE, ARRAY, SIZE, COMPARE_CBFN, CHECK_ARRAY_ELEMS, IS_LE) \
+ do { \
+ SDLTest_AssertPass(STR(TYPE) "Testing SDL_qsort of array with size %u", (unsigned)(SIZE)); \
+ global_compare_cbfn = NULL; \
+ TEST_QSORT_ARRAY_GENERIC(TYPE, ARRAY, SIZE, \
+ SDL_qsort(sorted, (SIZE), sizeof(TYPE), COMPARE_CBFN), \
+ CHECK_ARRAY_ELEMS, IS_LE, "SDL_qsort"); \
+ } while (0);
+
+#define TEST_QSORT_ARRAY_QSORT_R(TYPE, ARRAY, SIZE, COMPARE_CBFN, CHECK_ARRAY_ELEMS, IS_LE) \
+ do { \
+ SDLTest_AssertPass(STR(TYPE) "Testing SDL_qsort_r of array with size %u", (unsigned)(SIZE)); \
+ global_compare_cbfn = (COMPARE_CBFN); \
+ TEST_QSORT_ARRAY_GENERIC(TYPE, ARRAY, SIZE, \
+ SDL_qsort_r(sorted, (SIZE), sizeof(TYPE), generic_compare_r, &a_global_var), \
+ CHECK_ARRAY_ELEMS, IS_LE, "SDL_qsort_r"); \
+ } while (0);
+
+#define TEST_QSORT_ARRAY(TYPE, ARRAY, SIZE, COMPARE_CBFN, CHECK_ARRAY_ELEMS, IS_LE) \
+ do { \
+ TYPE *sorted = SDL_calloc((SIZE), sizeof(TYPE)); \
+ SDL_assert(sorted != NULL); \
+ \
+ TEST_QSORT_ARRAY_QSORT(TYPE, ARRAY, SIZE, COMPARE_CBFN, CHECK_ARRAY_ELEMS, IS_LE); \
+ \
+ TEST_QSORT_ARRAY_QSORT_R(TYPE, ARRAY, SIZE, COMPARE_CBFN, CHECK_ARRAY_ELEMS, IS_LE); \
+ \
+ SDL_free(sorted); \
+ } while (0)
+
+#define INT_ISLE(A, B) ((A) <= (B))
+
+#define INTPTR_ISLE(A, B) (*(A) <= *(B))
+
+#define FLOAT_ISLE(A, B) ((A) <= (B))
+
+#define DOUBLE_ISLE(A, B) ((A) <= (B))
+
+#define VERSION_ISLE(A, B) (compare_version(&(A), &(B)) <= 0)
+
+#define CHECK_ELEMS_SORTED_ARRAY(TYPE, SORTED, INPUT, SIZE) \
+ do { \
+ unsigned int check_index; \
+ for (check_index = 0; check_index < (SIZE); check_index++) { \
+ if ((SORTED)[check_index] != (INPUT)[check_index]) { \
+ SDLTest_AssertCheck(false, \
+ "sorted[%u] == input[%u]", \
+ check_index, check_index); \
+ } \
+ } \
+ } while (0)
+
+static int SDLCALL qsort_testAlreadySorted(void *arg)
{
- static int nums_copy[1024 * 100];
- int i;
- int prev;
+ unsigned int iteration;
+ (void)arg;
- SDL_assert(SDL_arraysize(nums_copy) >= arraylen);
+ for (iteration = 0; iteration < count_arraylens; iteration++) {
+ const unsigned int arraylen = arraylens[iteration];
+ unsigned int i;
+ int *ints = SDL_malloc(sizeof(int) * arraylen);
+ int **intptrs = SDL_malloc(sizeof(int *) * arraylen);
+ double *doubles = SDL_malloc(sizeof(double) * arraylen);
- SDL_Log("test: %s arraylen=%d", desc, arraylen);
+ for (i = 0; i < arraylen; i++) {
+ ints[i] = i;
+ intptrs[i] = &ints[i];
+ doubles[i] = (double)i * SDL_PI_D;
+ }
+ TEST_QSORT_ARRAY(int, ints, arraylen, compare_int, CHECK_ELEMS_SORTED_ARRAY, INT_ISLE);
+ TEST_QSORT_ARRAY(int *, intptrs, arraylen, compare_intptr, CHECK_ELEMS_SORTED_ARRAY, INTPTR_ISLE);
+ TEST_QSORT_ARRAY(double, doubles, arraylen, compare_double, CHECK_ELEMS_SORTED_ARRAY, DOUBLE_ISLE);
+
+ SDL_free(ints);
+ SDL_free(intptrs);
+ SDL_free(doubles);
+ }
+ return TEST_COMPLETED;
+}
+
+#define CHECK_ELEMS_SORTED_ARRAY_EXCEPT_LAST(TYPE, SORTED, INPUT, SIZE) \
+ do { \
+ unsigned int check_index; \
+ for (check_index = 0; check_index < (SIZE) - 1; check_index++) { \
+ if (SDL_memcmp(&(SORTED)[check_index + 1], &(INPUT)[check_index], sizeof(TYPE)) != 0) { \
+ SDLTest_AssertCheck(false, \
+ STR(TYPE) "sorted[%u] == input[%u]", \
+ check_index + 1, check_index); \
+ } \
+ } \
+ } while (0)
- SDL_memcpy(nums_copy, nums, arraylen * sizeof (*nums));
+static int SDLCALL qsort_testAlreadySortedExceptLast(void *arg)
+{
+ unsigned int iteration;
+ (void)arg;
- SDL_qsort(nums, arraylen, sizeof(nums[0]), num_compare);
- SDL_qsort_r(nums_copy, arraylen, sizeof(nums[0]), num_compare_r, &a_global_var);
+ for (iteration = 0; iteration < count_arraylens; iteration++) {
+ const unsigned int arraylen = arraylens[iteration];
+ unsigned int i;
+ int *ints = SDL_malloc(sizeof(int) * arraylen);
+ int **intptrs = SDL_malloc(sizeof(int *) * arraylen);
+ double *doubles = SDL_malloc(sizeof(double) * arraylen);
+ VersionTuple *versions = SDL_calloc(arraylen, sizeof(VersionTuple));
- prev = nums[0];
- for (i = 1; i < arraylen; i++) {
- const int val = nums[i];
- const int val2 = nums_copy[i];
- if ((val < prev) || (val != val2)) {
- SDL_Log("sort is broken!");
- return;
+ for (i = 0; i < arraylen; i++) {
+ ints[i] = i;
+ intptrs[i] = &ints[i];
+ doubles[i] = (double)i * SDL_PI_D;
+ versions[i].micro = (i + 1) % 256;
+ versions[i].minor = (i + 1) % (256 * 256) / 256;
+ versions[i].major = (i + 1) % (256 * 256 * 256) / 256 / 256;
}
- prev = val;
+ ints[arraylen - 1] = -1;
+ doubles[arraylen - 1] = -1.;
+ versions[arraylen - 1].major = 0;
+ versions[arraylen - 1].minor = 0;
+ versions[arraylen - 1].micro = 0;
+ TEST_QSORT_ARRAY(int, ints, arraylen, compare_int, CHECK_ELEMS_SORTED_ARRAY_EXCEPT_LAST, INT_ISLE);
+ TEST_QSORT_ARRAY(int *, intptrs, arraylen, compare_intptr, CHECK_ELEMS_SORTED_ARRAY_EXCEPT_LAST, INTPTR_ISLE);
+ TEST_QSORT_ARRAY(double, doubles, arraylen, compare_double, CHECK_ELEMS_SORTED_ARRAY_EXCEPT_LAST, DOUBLE_ISLE);
+ TEST_QSORT_ARRAY(VersionTuple, versions, arraylen, compare_version, CHECK_ELEMS_SORTED_ARRAY_EXCEPT_LAST, VERSION_ISLE);
+
+ SDL_free(ints);
+ SDL_free(intptrs);
+ SDL_free(doubles);
+ SDL_free(versions);
}
+ return TEST_COMPLETED;
}
+#define CHECK_ELEMS_SORTED_ARRAY_REVERSED(TYPE, SORTED, INPUT, SIZE) \
+ do { \
+ unsigned int check_index; \
+ for (check_index = 0; check_index < (SIZE); check_index++) { \
+ if (SDL_memcmp(&(SORTED)[check_index], &(INPUT)[(SIZE) - check_index - 1], sizeof(TYPE)) != 0) { \
+ SDLTest_AssertCheck(false, \
+ STR(TYPE) "sorted[%u] != input[%u]", \
+ check_index, (SIZE) - check_index - 1); \
+ } \
+ } \
+ } while (0)
+
+static int SDLCALL qsort_testReverseSorted(void *arg)
+{
+ unsigned int iteration;
+ (void)arg;
+
+ for (iteration = 0; iteration < count_arraylens; iteration++) {
+ const unsigned int arraylen = arraylens[iteration];
+ unsigned int i;
+ int *ints = SDL_malloc(sizeof(int) * arraylen);
+ int **intptrs = SDL_malloc(sizeof(int *) * arraylen);
+ double *doubles = SDL_malloc(sizeof(double) * arraylen);
+ VersionTuple *versions = SDL_calloc(arraylen, sizeof(VersionTuple));
+
+ for (i = 0; i < arraylen; i++) {
+ ints[i] = (arraylen - 1) - i;
+ intptrs[i] = &ints[i];
+ doubles[i] = (double)((arraylen - 1) - i) * SDL_PI_D;
+ versions[i].micro = ints[i] % 256;
+ versions[i].minor = ints[i] % (256 * 256) / 256;
+ versions[i].major = ints[i] % (256 * 256 * 256) / 256 / 256;
+ }
+ TEST_QSORT_ARRAY(int, ints, arraylen, compare_int, CHECK_ELEMS_SORTED_ARRAY_REVERSED, INT_ISLE);
+ TEST_QSORT_ARRAY(int *, intptrs, arraylen, compare_intptr, CHECK_ELEMS_SORTED_ARRAY_REVERSED, INTPTR_ISLE);
+ TEST_QSORT_ARRAY(double, doubles, arraylen, compare_double, CHECK_ELEMS_SORTED_ARRAY_REVERSED, DOUBLE_ISLE);
+ TEST_QSORT_ARRAY(VersionTuple, versions, arraylen, compare_version, CHECK_ELEMS_SORTED_ARRAY_REVERSED, VERSION_ISLE);
+
+ SDL_free(ints);
+ SDL_free(intptrs);
+ SDL_free(doubles);
+ SDL_free(versions);
+ }
+ return TEST_COMPLETED;
+}
+
+#define MAX_RANDOM_INT_VALUE (1024 * 1024)
+
+#define CHECK_ELEMS_SORTED_ARRAY_RANDOM_INT(TYPE, SORTED, INPUT, SIZE) \
+ do { \
+ int *presences = SDL_calloc(MAX_RANDOM_INT_VALUE, sizeof(int)); \
+ unsigned int check_index; \
+ for (check_index = 0; check_index < (SIZE); check_index++) { \
+ presences[(SORTED)[check_index]] += 1; \
+ presences[(INPUT)[check_index]] -= 1; \
+ } \
+ for (check_index = 0; check_index < MAX_RANDOM_INT_VALUE; check_index++) { \
+ if (presences[check_index] != 0) { \
+ SDLTest_AssertCheck(false, "Value %d appears %s in sorted array", \
+ check_index, \
+ presences[check_index] > 0 ? "MORE" : "LESS"); \
+ } \
+ } \
+ SDL_free(presences); \
+ } while (0)
+
+#define VERSION_TO_INT(VERSION) (((VERSION).major * 256 + (VERSION).minor) * 256 + (VERSION).micro)
+#define INT_VERSION_MAJOR(V) (((V) / (256 * 256) % 256))
+#define INT_VERSION_MINOR(V) (((V) / (256)) % 256)
+#define INT_VERSION_MICRO(V) ((V) % 256)
+
+#define CHECK_ELEMS_SORTED_ARRAY_RANDOM_VERSION(TYPE, SORTED, INPUT, SIZE) \
+ do { \
+ int *presences = SDL_calloc(256 * 256 * 256, sizeof(int)); \
+ unsigned int check_index; \
+ for (check_index = 0; check_index < (SIZE); check_index++) { \
+ presences[VERSION_TO_INT((SORTED)[check_index])] += 1; \
+ presences[VERSION_TO_INT((INPUT)[check_index])] -= 1; \
+ } \
+ for (check_index = 0; check_index < 256 * 256 * 256; check_index++) { \
+ if (presences[check_index] != 0) { \
+ SDLTest_AssertCheck(false, STR(TYPE) "Version %d.%d.%d appears %s in sorted array", \
+ INT_VERSION_MAJOR(check_index), \
+ INT_VERSION_MINOR(check_index), \
+ INT_VERSION_MICRO(check_index), \
+ presences[check_index] > 0 ? "MORE" : "LESS"); \
+ } \
+ } \
+ SDL_free(presences); \
+ } while (0)
+
+#define CHECK_ELEMS_SORTED_ARRAY_RPS(TYPE, SORTED, INPUT, SIZE) \
+ do { \
+ int presences[3] = { 0 }; \
+ unsigned int check_index; \
+ for (check_index = 0; check_index < (SIZE); check_index++) { \
+ presences[(SORTED)[check_index]] += 1; \
+ presences[(INPUT)[check_index]] -= 1; \
+ } \
+ for (check_index = 0; check_index < SDL_arraysize(presences); check_index++) { \
+ if (presences[check_index] != 0) { \
+ SDLTest_AssertCheck(false, STR(TYPE) "%d appeared or disappeared", \
+ check_index); \
+ } \
+ } \
+ } while (0)
+
+#define CHECK_ELEMS_SORTED_ARRAY_RANDOM_NOP(TYPE, SORTED, INPUT, SIZE) \
+ SDLTest_AssertPass(STR(TYPE) "Skipping elements presence check")
+
+static int SDLCALL qsort_testRandomSorted(void *arg)
+{
+ unsigned int iteration;
+ (void)arg;
+
+ for (iteration = 0; iteration < count_arraylens; iteration++) {
+ const unsigned int arraylen = arraylens[iteration];
+ unsigned int i;
+ int *ints = SDL_malloc(sizeof(int) * arraylen);
+ float *floats = SDL_malloc(sizeof(float) * arraylen);
+ VersionTuple *versions = SDL_calloc(arraylen, sizeof(VersionTuple));
+
+ for (i = 0; i < arraylen; i++) {
+ ints[i] = SDLTest_RandomIntegerInRange(0, MAX_RANDOM_INT_VALUE - 1);
+ floats[i] = SDLTest_RandomFloat() * SDL_PI_F;
+ versions[i].micro = SDLTest_RandomIntegerInRange(0, 255);
+ versions[i].minor = SDLTest_RandomIntegerInRange(0, 255);
+ versions[i].major = SDLTest_RandomIntegerInRange(0, 255);
+ }
+ TEST_QSORT_ARRAY(int, ints, arraylen, compare_int, CHECK_ELEMS_SORTED_ARRAY_RANDOM_INT, INT_ISLE);
+ TEST_QSORT_ARRAY(float, floats, arraylen, compare_float, CHECK_ELEMS_SORTED_ARRAY_RANDOM_NOP, FLOAT_ISLE);
+ TEST_QSORT_ARRAY(VersionTuple, versions, arraylen, compare_version, CHECK_ELEMS_SORTED_ARRAY_RANDOM_VERSION, VERSION_ISLE);
+
+ SDL_free(ints);
+ SDL_free(floats);
+ SDL_free(versions);
+ }
+ return TEST_COMPLETED;
+}
+
+static const SDLTest_TestCaseReference qsortTestAlreadySorted = {
+ qsort_testAlreadySorted, "qsort_testAlreadySorted", "Test sorting already sorted array", TEST_ENABLED
+};
+
+static const SDLTest_TestCaseReference qsortTestAlreadySortedExceptLast = {
+ qsort_testAlreadySortedExceptLast, "qsort_testAlreadySortedExceptLast", "Test sorting nearly sorted array (last item is not in order)", TEST_ENABLED
+};
+
+static const SDLTest_TestCaseReference qsortTestReverseSorted = {
+ qsort_testReverseSorted, "qsort_testReverseSorted", "Test sorting an array in reverse order", TEST_ENABLED
+};
+
+static const SDLTest_TestCaseReference qsortTestRandomSorted = {
+ qsort_testRandomSorted, "qsort_testRandomSorted", "Test sorting a random array", TEST_ENABLED
+};
+
+static const SDLTest_TestCaseReference *qsortTests[] = {
+ &qsortTestAlreadySorted,
+ &qsortTestAlreadySortedExceptLast,
+ &qsortTestReverseSorted,
+ &qsortTestRandomSorted,
+ NULL
+};
+
+static SDLTest_TestSuiteReference qsortTestSuite = {
+ "qsort",
+ NULL,
+ qsortTests,
+ NULL
+};
+
+static SDLTest_TestSuiteReference *testSuites[] = {
+ &qsortTestSuite,
+ NULL
+};
+
int main(int argc, char *argv[])
{
- static int nums[1024 * 100];
- static const int itervals[] = { SDL_arraysize(nums), 12 };
int i;
- int iteration;
+ int result;
SDLTest_CommonState *state;
- Uint64 seed = 0;
- int seed_seen = 0;
+ SDLTest_TestSuiteRunner *runner;
+ bool list = false;
/* Initialize test framework */
state = SDLTest_CommonCreateState(argv, 0);
@@ -77,27 +465,47 @@ int main(int argc, char *argv[])
return 1;
}
+ runner = SDLTest_CreateTestSuiteRunner(state, testSuites);
+
/* Parse commandline */
for (i = 1; i < argc;) {
int consumed;
consumed = SDLTest_CommonArg(state, i);
if (!consumed) {
- if (!seed_seen) {
- char *endptr = NULL;
-
- seed = (Uint64)SDL_strtoull(argv[i], &endptr, 0);
- if (endptr != argv[i] && *endptr == '\0') {
- seed_seen = 1;
- consumed = 1;
- } else {
- SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Invalid seed. Use a decimal or hexadecimal number.");
- return 1;
+
+ if (SDL_strcasecmp(argv[i], "--array-lengths") == 0) {
+ count_arraylens = 0;
+ consumed = 1;
+ while (argv[i + consumed] && argv[i + consumed][0] != '-') {
+ char *endptr = NULL;
+ unsigned int arraylen = (unsigned int)SDL_strtoul(argv[i + 1], &endptr, 10);
+ if (*endptr != '\0') {
+ count_arraylens = 0;
+ break;
+ }
+ if (count_arraylens >= SDL_arraysize(arraylens)) {
+ SDL_LogWarn(SDL_LOG_CATEGORY_TEST, "Dropping array length %d", arraylen);
+ } else {
+ arraylens[count_arraylens] = arraylen;
+ }
+ count_arraylens++;
+ consumed++;
+ }
+ if (consumed == 0) {
+ SDL_LogError(SDL_LOG_CATEGORY_TEST, "--array-lengths needs positive int numbers");
}
+ } else if (SDL_strcasecmp(argv[i], "--list") == 0) {
+ consumed = 1;
+ list = true;
}
}
if (consumed <= 0) {
- static const char *options[] = { "[seed]", NULL };
+ static const char *options[] = {
+ "[--list]",
+ "[--array-lengths N1 [N2 [N3 [...]]]",
+ NULL
+ };
SDLTest_CommonLogUsage(state, argv[0], options);
return 1;
}
@@ -105,38 +513,25 @@ int main(int argc, char *argv[])
i += consumed;
}
- if (!seed_seen) {
- seed = SDL_GetPerformanceCounter();
- }
- SDL_Log("Using random seed 0x%" SDL_PRIx64, seed);
-
- for (iteration = 0; iteration < SDL_arraysize(itervals); iteration++) {
- const int arraylen = itervals[iteration];
-
- for (i = 0; i < arraylen; i++) {
- nums[i] = i;
- }
- test_sort("already sorted", nums, arraylen);
-
- for (i = 0; i < arraylen; i++) {
- nums[i] = i;
- }
- nums[arraylen - 1] = -1;
- test_sort("already sorted except last element", nums, arraylen);
-
- for (i = 0; i < arraylen; i++) {
- nums[i] = (arraylen - 1) - i;
- }
- test_sort("reverse sorted", nums, arraylen);
-
- for (i = 0; i < arraylen; i++) {
- nums[i] = SDL_rand_r(&seed, 1000000);
+ /* List all suites. */
+ if (list) {
+ int suiteCounter;
+ for (suiteCounter = 0; testSuites[suiteCounter]; ++suiteCounter) {
+ int testCounter;
+ SDLTest_TestSuiteReference *testSuite = testSuites[suiteCounter];
+ SDL_Log("Test suite: %s", testSuite->name);
+ for (testCounter = 0; testSuite->testCases[testCounter]; ++testCounter) {
+ const SDLTest_TestCaseReference *testCase = testSuite->testCases[testCounter];
+ SDL_Log(" test: %s%s", testCase->name, testCase->enabled ? "" : " (disabled)");
+ }
}
- test_sort("random sorted", nums, arraylen);
+ result = 0;
+ } else {
+ result = SDLTest_ExecuteTestSuiteRunner(runner);
}
SDL_Quit();
+ SDLTest_DestroyTestSuiteRunner(runner);
SDLTest_CommonDestroyState(state);
-
- return 0;
+ return result;
}
(Patch may be truncated, please check the link at the top of this post.)