Atlas - testqsort.c
Home / ext / SDL / test Lines: 1 | Size: 27738 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 3 4 This software is provided 'as-is', without any express or implied 5 warranty. In no event will the authors be held liable for any damages 6 arising from the use of this software. 7 8 Permission is granted to anyone to use this software for any purpose, 9 including commercial applications, and to alter it and redistribute it 10 freely. 11*/ 12 13#ifdef TEST_STDLIB_QSORT 14#define _GNU_SOURCE 15#include <stdlib.h> 16#endif 17 18#include <SDL3/SDL.h> 19#include <SDL3/SDL_main.h> 20#include <SDL3/SDL_test.h> 21 22typedef struct { 23 Uint8 major; 24 Uint8 minor; 25 Uint8 micro; 26} VersionTuple; 27 28static int a_global_var = 77; 29static int (SDLCALL * global_compare_cbfn)(const void *_a, const void *_b); 30 31static unsigned long arraylens[16] = { 12, 1024 * 100 }; 32static unsigned int count_arraylens = 2; 33 34static int SDLCALL 35compare_int(const void *_a, const void *_b) 36{ 37 const int a = *((const int *)_a); 38 const int b = *((const int *)_b); 39 return (a < b) ? -1 : ((a > b) ? 1 : 0); 40} 41 42static int SDLCALL 43compare_float(const void *_a, const void *_b) 44{ 45 const float a = *((const float *)_a); 46 const float b = *((const float *)_b); 47 return (a < b) ? -1 : ((a > b) ? 1 : 0); 48} 49 50static int SDLCALL 51compare_double(const void *_a, const void *_b) 52{ 53 const double a = *((const double *)_a); 54 const double b = *((const double *)_b); 55 return (a < b) ? -1 : ((a > b) ? 1 : 0); 56} 57 58static int SDLCALL 59compare_intptr(const void *_a, const void *_b) 60{ 61 const int* a = *((const int **)_a); 62 const int* b = *((const int **)_b); 63 return compare_int(a, b); 64} 65 66static int SDLCALL 67compare_version(const void *_a, const void *_b) 68{ 69 const VersionTuple *a = ((const VersionTuple *)_a); 70 const VersionTuple *b = ((const VersionTuple *)_b); 71 int d; 72 d = (int)a->major - (int)b->major; 73 if (d != 0) { 74 return d; 75 } 76 d = (int)a->minor - (int)b->minor; 77 if (d != 0) { 78 return d; 79 } 80 return (int)a->micro - (int)b->micro; 81} 82 83#ifdef TEST_STDLIB_QSORT 84#define SDL_qsort qsort 85#define SDL_qsort_r qsort_r 86#endif 87 88static int SDLCALL 89#ifdef TEST_STDLIB_QSORT 90generic_compare_r(const void *a, const void *b, void *userdata) 91#else 92generic_compare_r(void *userdata, const void *a, const void *b) 93#endif 94{ 95 if (userdata != &a_global_var) { 96 SDLTest_AssertCheck(userdata == &a_global_var, "User data of callback must be identical to global data"); 97 } 98 return global_compare_cbfn(a, b); 99} 100 101#define STR2(S) "[" #S "] " 102#define STR(S) STR2(S) 103 104#define TEST_ARRAY_IS_SORTED(TYPE, ARRAY, SIZE, IS_LE) \ 105 do { \ 106 size_t sorted_index; \ 107 Uint64 count_non_sorted = 0; \ 108 for (sorted_index = 0; sorted_index < (SIZE) - 1; sorted_index++) { \ 109 if (!IS_LE((ARRAY)[sorted_index], (ARRAY)[sorted_index + 1])) { \ 110 count_non_sorted += 1; \ 111 } \ 112 } \ 113 SDLTest_AssertCheck(count_non_sorted == 0, \ 114 STR(TYPE) "Array (size=%d) is sorted (bad count=%" SDL_PRIu64 ")", (SIZE), count_non_sorted); \ 115 } while (0) 116 117/* This test is O(n^2), so very slow (a hashmap can speed this up): 118 * - we cannot trust qsort 119 * - the arrays can contain duplicate items 120 * - the arrays are not int 121 */ 122#define TEST_ARRAY_LOST_NO_ELEMENTS(TYPE, ORIGINAL, SORTED, SIZE, IS_SAME) \ 123 do { \ 124 size_t original_index; \ 125 bool *original_seen = SDL_calloc((SIZE), sizeof(bool)); \ 126 Uint64 lost_count = 0; \ 127 SDL_assert(original_seen != NULL); \ 128 for (original_index = 0; original_index < (SIZE); original_index++) { \ 129 size_t sorted_index; \ 130 for (sorted_index = 0; sorted_index < (SIZE); sorted_index++) { \ 131 if (IS_SAME((ORIGINAL)[original_index], (SORTED)[sorted_index])) { \ 132 original_seen[original_index] = true; \ 133 break; \ 134 } \ 135 } \ 136 } \ 137 for (original_index = 0; original_index < (SIZE); original_index++) { \ 138 if (!original_seen[original_index]) { \ 139 SDLTest_AssertCheck(original_seen[original_index], \ 140 STR(TYPE) "Element %d is missing in the sorted array", (int)original_index); \ 141 lost_count += 1; \ 142 } \ 143 } \ 144 SDLTest_AssertCheck(lost_count == 0, \ 145 STR(TYPE) "No elements were lost (lost count=%" SDL_PRIu64 ")", lost_count); \ 146 SDL_free(original_seen); \ 147 } while (0) 148 149#define TEST_QSORT_ARRAY_GENERIC(TYPE, ARRAY, SIZE, QSORT_CALL, CHECK_ARRAY_ELEMS, IS_LE, WHAT) \ 150 do { \ 151 SDL_memcpy(sorted, (ARRAY), sizeof(TYPE) * (SIZE)); \ 152 SDLTest_AssertPass(STR(TYPE) "About to call " WHAT "(%d, %d)", \ 153 (int)(SIZE), (int)sizeof(TYPE)); \ 154 QSORT_CALL; \ 155 SDLTest_AssertPass(STR(TYPE) WHAT " finished"); \ 156 TEST_ARRAY_IS_SORTED(TYPE, sorted, SIZE, IS_LE); \ 157 SDLTest_AssertPass(STR(TYPE) "Verifying element preservation..."); \ 158 CHECK_ARRAY_ELEMS(TYPE, sorted, (ARRAY), (SIZE)); \ 159 } while (0) 160 161#define TEST_QSORT_ARRAY_QSORT(TYPE, ARRAY, SIZE, COMPARE_CBFN, CHECK_ARRAY_ELEMS, IS_LE) \ 162 do { \ 163 SDLTest_AssertPass(STR(TYPE) "Testing SDL_qsort of array with size %u", (unsigned)(SIZE)); \ 164 global_compare_cbfn = NULL; \ 165 TEST_QSORT_ARRAY_GENERIC(TYPE, ARRAY, SIZE, \ 166 SDL_qsort(sorted, (SIZE), sizeof(TYPE), COMPARE_CBFN), \ 167 CHECK_ARRAY_ELEMS, IS_LE, "SDL_qsort"); \ 168 } while (0); 169 170#if defined(SDL_PLATFORM_WINDOWS) && defined(TEST_STDLIB_QSORT) 171#define TEST_QSORT_ARRAY_QSORT_R(TYPE, ARRAY, SIZE, COMPARE_CBFN, CHECK_ARRAY_ELEMS, IS_LE) \ 172 do { \ 173 SDLTest_AssertPass(STR(TYPE) "qsort_r is not available on current platform"); \ 174 } while (0) 175#else 176#define TEST_QSORT_ARRAY_QSORT_R(TYPE, ARRAY, SIZE, COMPARE_CBFN, CHECK_ARRAY_ELEMS, IS_LE) \ 177 do { \ 178 SDLTest_AssertPass(STR(TYPE) "Testing SDL_qsort_r of array with size %u", (unsigned)(SIZE)); \ 179 global_compare_cbfn = (COMPARE_CBFN); \ 180 TEST_QSORT_ARRAY_GENERIC(TYPE, ARRAY, SIZE, \ 181 SDL_qsort_r(sorted, (SIZE), sizeof(TYPE), generic_compare_r, &a_global_var), \ 182 CHECK_ARRAY_ELEMS, IS_LE, "SDL_qsort_r"); \ 183 } while (0); 184#endif 185 186#define TEST_QSORT_ARRAY(TYPE, ARRAY, SIZE, COMPARE_CBFN, CHECK_ARRAY_ELEMS, IS_LE) \ 187 do { \ 188 TYPE *sorted = SDL_calloc((SIZE), sizeof(TYPE)); \ 189 SDL_assert(sorted != NULL); \ 190 \ 191 TEST_QSORT_ARRAY_QSORT(TYPE, ARRAY, SIZE, COMPARE_CBFN, CHECK_ARRAY_ELEMS, IS_LE); \ 192 \ 193 TEST_QSORT_ARRAY_QSORT_R(TYPE, ARRAY, SIZE, COMPARE_CBFN, CHECK_ARRAY_ELEMS, IS_LE); \ 194 \ 195 SDL_free(sorted); \ 196 } while (0) 197 198#define INT_ISLE(A, B) ((A) <= (B)) 199 200#define INTPTR_ISLE(A, B) (*(A) <= *(B)) 201 202#define FLOAT_ISLE(A, B) ((A) <= (B)) 203 204#define DOUBLE_ISLE(A, B) ((A) <= (B)) 205 206#define VERSION_ISLE(A, B) (compare_version(&(A), &(B)) <= 0) 207 208#define CHECK_ELEMS_SORTED_ARRAY(TYPE, SORTED, INPUT, SIZE) \ 209 do { \ 210 unsigned int check_index; \ 211 for (check_index = 0; check_index < (SIZE); check_index++) { \ 212 if ((SORTED)[check_index] != (INPUT)[check_index]) { \ 213 SDLTest_AssertCheck(false, \ 214 "sorted[%u] == input[%u]", \ 215 check_index, check_index); \ 216 } \ 217 } \ 218 } while (0) 219 220static int SDLCALL qsort_testAlreadySorted(void *arg) 221{ 222 unsigned int iteration; 223 (void)arg; 224 225 for (iteration = 0; iteration < count_arraylens; iteration++) { 226 const unsigned int arraylen = arraylens[iteration]; 227 unsigned int i; 228 int *ints = SDL_malloc(sizeof(int) * arraylen); 229 int **intptrs = SDL_malloc(sizeof(int *) * arraylen); 230 double *doubles = SDL_malloc(sizeof(double) * arraylen); 231 232 for (i = 0; i < arraylen; i++) { 233 ints[i] = i; 234 intptrs[i] = &ints[i]; 235 doubles[i] = (double)i * SDL_PI_D; 236 } 237 TEST_QSORT_ARRAY(int, ints, arraylen, compare_int, CHECK_ELEMS_SORTED_ARRAY, INT_ISLE); 238 TEST_QSORT_ARRAY(int *, intptrs, arraylen, compare_intptr, CHECK_ELEMS_SORTED_ARRAY, INTPTR_ISLE); 239 TEST_QSORT_ARRAY(double, doubles, arraylen, compare_double, CHECK_ELEMS_SORTED_ARRAY, DOUBLE_ISLE); 240 241 SDL_free(ints); 242 SDL_free(intptrs); 243 SDL_free(doubles); 244 } 245 return TEST_COMPLETED; 246} 247 248#define CHECK_ELEMS_SORTED_ARRAY_EXCEPT_LAST(TYPE, SORTED, INPUT, SIZE) \ 249 do { \ 250 unsigned int check_index; \ 251 for (check_index = 0; check_index < (SIZE) - 1; check_index++) { \ 252 if (SDL_memcmp(&(SORTED)[check_index + 1], &(INPUT)[check_index], sizeof(TYPE)) != 0) { \ 253 SDLTest_AssertCheck(false, \ 254 STR(TYPE) "sorted[%u] == input[%u]", \ 255 check_index + 1, check_index); \ 256 } \ 257 } \ 258 } while (0) 259 260static int SDLCALL qsort_testAlreadySortedExceptLast(void *arg) 261{ 262 unsigned int iteration; 263 (void)arg; 264 265 for (iteration = 0; iteration < count_arraylens; iteration++) { 266 const unsigned int arraylen = arraylens[iteration]; 267 unsigned int i; 268 int *ints = SDL_malloc(sizeof(int) * arraylen); 269 int **intptrs = SDL_malloc(sizeof(int *) * arraylen); 270 double *doubles = SDL_malloc(sizeof(double) * arraylen); 271 VersionTuple *versions = SDL_calloc(arraylen, sizeof(VersionTuple)); 272 273 for (i = 0; i < arraylen; i++) { 274 ints[i] = i; 275 intptrs[i] = &ints[i]; 276 doubles[i] = (double)i * SDL_PI_D; 277 versions[i].micro = (i + 1) % 256; 278 versions[i].minor = (i + 1) % (256 * 256) / 256; 279 versions[i].major = (i + 1) % (256 * 256 * 256) / 256 / 256; 280 } 281 ints[arraylen - 1] = -1; 282 doubles[arraylen - 1] = -1.; 283 versions[arraylen - 1].major = 0; 284 versions[arraylen - 1].minor = 0; 285 versions[arraylen - 1].micro = 0; 286 TEST_QSORT_ARRAY(int, ints, arraylen, compare_int, CHECK_ELEMS_SORTED_ARRAY_EXCEPT_LAST, INT_ISLE); 287 TEST_QSORT_ARRAY(int *, intptrs, arraylen, compare_intptr, CHECK_ELEMS_SORTED_ARRAY_EXCEPT_LAST, INTPTR_ISLE); 288 TEST_QSORT_ARRAY(double, doubles, arraylen, compare_double, CHECK_ELEMS_SORTED_ARRAY_EXCEPT_LAST, DOUBLE_ISLE); 289 TEST_QSORT_ARRAY(VersionTuple, versions, arraylen, compare_version, CHECK_ELEMS_SORTED_ARRAY_EXCEPT_LAST, VERSION_ISLE); 290 291 SDL_free(ints); 292 SDL_free(intptrs); 293 SDL_free(doubles); 294 SDL_free(versions); 295 } 296 return TEST_COMPLETED; 297} 298 299#define CHECK_ELEMS_SORTED_ARRAY_REVERSED(TYPE, SORTED, INPUT, SIZE) \ 300 do { \ 301 unsigned int check_index; \ 302 for (check_index = 0; check_index < (SIZE); check_index++) { \ 303 if (SDL_memcmp(&(SORTED)[check_index], &(INPUT)[(SIZE) - check_index - 1], sizeof(TYPE)) != 0) { \ 304 SDLTest_AssertCheck(false, \ 305 STR(TYPE) "sorted[%u] != input[%u]", \ 306 check_index, (SIZE) - check_index - 1); \ 307 } \ 308 } \ 309 } while (0) 310 311static int SDLCALL qsort_testReverseSorted(void *arg) 312{ 313 unsigned int iteration; 314 (void)arg; 315 316 for (iteration = 0; iteration < count_arraylens; iteration++) { 317 const unsigned int arraylen = arraylens[iteration]; 318 unsigned int i; 319 int *ints = SDL_malloc(sizeof(int) * arraylen); 320 int **intptrs = SDL_malloc(sizeof(int *) * arraylen); 321 double *doubles = SDL_malloc(sizeof(double) * arraylen); 322 VersionTuple *versions = SDL_calloc(arraylen, sizeof(VersionTuple)); 323 324 for (i = 0; i < arraylen; i++) { 325 ints[i] = (arraylen - 1) - i; 326 intptrs[i] = &ints[i]; 327 doubles[i] = (double)((arraylen - 1) - i) * SDL_PI_D; 328 versions[i].micro = ints[i] % 256; 329 versions[i].minor = ints[i] % (256 * 256) / 256; 330 versions[i].major = ints[i] % (256 * 256 * 256) / 256 / 256; 331 } 332 TEST_QSORT_ARRAY(int, ints, arraylen, compare_int, CHECK_ELEMS_SORTED_ARRAY_REVERSED, INT_ISLE); 333 TEST_QSORT_ARRAY(int *, intptrs, arraylen, compare_intptr, CHECK_ELEMS_SORTED_ARRAY_REVERSED, INTPTR_ISLE); 334 TEST_QSORT_ARRAY(double, doubles, arraylen, compare_double, CHECK_ELEMS_SORTED_ARRAY_REVERSED, DOUBLE_ISLE); 335 TEST_QSORT_ARRAY(VersionTuple, versions, arraylen, compare_version, CHECK_ELEMS_SORTED_ARRAY_REVERSED, VERSION_ISLE); 336 337 SDL_free(ints); 338 SDL_free(intptrs); 339 SDL_free(doubles); 340 SDL_free(versions); 341 } 342 return TEST_COMPLETED; 343} 344 345#define MAX_RANDOM_INT_VALUE (1024 * 1024) 346 347#define CHECK_ELEMS_SORTED_ARRAY_RANDOM_INT(TYPE, SORTED, INPUT, SIZE) \ 348 do { \ 349 int *presences = SDL_calloc(MAX_RANDOM_INT_VALUE, sizeof(int)); \ 350 unsigned int check_index; \ 351 for (check_index = 0; check_index < (SIZE); check_index++) { \ 352 presences[(SORTED)[check_index]] += 1; \ 353 presences[(INPUT)[check_index]] -= 1; \ 354 } \ 355 for (check_index = 0; check_index < MAX_RANDOM_INT_VALUE; check_index++) { \ 356 if (presences[check_index] != 0) { \ 357 SDLTest_AssertCheck(false, "Value %d appears %s in sorted array", \ 358 check_index, \ 359 presences[check_index] > 0 ? "MORE" : "LESS"); \ 360 } \ 361 } \ 362 SDL_free(presences); \ 363 } while (0) 364 365#define VERSION_TO_INT(VERSION) (((VERSION).major * 256 + (VERSION).minor) * 256 + (VERSION).micro) 366#define INT_VERSION_MAJOR(V) (((V) / (256 * 256) % 256)) 367#define INT_VERSION_MINOR(V) (((V) / (256)) % 256) 368#define INT_VERSION_MICRO(V) ((V) % 256) 369 370#define CHECK_ELEMS_SORTED_ARRAY_RANDOM_VERSION(TYPE, SORTED, INPUT, SIZE) \ 371 do { \ 372 int *presences = SDL_calloc(256 * 256 * 256, sizeof(int)); \ 373 unsigned int check_index; \ 374 for (check_index = 0; check_index < (SIZE); check_index++) { \ 375 presences[VERSION_TO_INT((SORTED)[check_index])] += 1; \ 376 presences[VERSION_TO_INT((INPUT)[check_index])] -= 1; \ 377 } \ 378 for (check_index = 0; check_index < 256 * 256 * 256; check_index++) { \ 379 if (presences[check_index] != 0) { \ 380 SDLTest_AssertCheck(false, STR(TYPE) "Version %d.%d.%d appears %s in sorted array", \ 381 INT_VERSION_MAJOR(check_index), \ 382 INT_VERSION_MINOR(check_index), \ 383 INT_VERSION_MICRO(check_index), \ 384 presences[check_index] > 0 ? "MORE" : "LESS"); \ 385 } \ 386 } \ 387 SDL_free(presences); \ 388 } while (0) 389 390#define CHECK_ELEMS_SORTED_ARRAY_RPS(TYPE, SORTED, INPUT, SIZE) \ 391 do { \ 392 int presences[3] = { 0 }; \ 393 unsigned int check_index; \ 394 for (check_index = 0; check_index < (SIZE); check_index++) { \ 395 presences[(SORTED)[check_index]] += 1; \ 396 presences[(INPUT)[check_index]] -= 1; \ 397 } \ 398 for (check_index = 0; check_index < SDL_arraysize(presences); check_index++) { \ 399 if (presences[check_index] != 0) { \ 400 SDLTest_AssertCheck(false, STR(TYPE) "%d appeared or disappeared", \ 401 check_index); \ 402 } \ 403 } \ 404 } while (0) 405 406#define CHECK_ELEMS_SORTED_ARRAY_RANDOM_NOP(TYPE, SORTED, INPUT, SIZE) \ 407 SDLTest_AssertPass(STR(TYPE) "Skipping elements presence check") 408 409static int SDLCALL qsort_testRandomSorted(void *arg) 410{ 411 unsigned int iteration; 412 (void)arg; 413 414 for (iteration = 0; iteration < count_arraylens; iteration++) { 415 const unsigned int arraylen = arraylens[iteration]; 416 unsigned int i; 417 int *ints = SDL_malloc(sizeof(int) * arraylen); 418 float *floats = SDL_malloc(sizeof(float) * arraylen); 419 VersionTuple *versions = SDL_calloc(arraylen, sizeof(VersionTuple)); 420 421 for (i = 0; i < arraylen; i++) { 422 ints[i] = SDLTest_RandomIntegerInRange(0, MAX_RANDOM_INT_VALUE - 1); 423 floats[i] = SDLTest_RandomFloat() * SDL_PI_F; 424 versions[i].micro = SDLTest_RandomIntegerInRange(0, 255); 425 versions[i].minor = SDLTest_RandomIntegerInRange(0, 255); 426 versions[i].major = SDLTest_RandomIntegerInRange(0, 255); 427 } 428 TEST_QSORT_ARRAY(int, ints, arraylen, compare_int, CHECK_ELEMS_SORTED_ARRAY_RANDOM_INT, INT_ISLE); 429 TEST_QSORT_ARRAY(float, floats, arraylen, compare_float, CHECK_ELEMS_SORTED_ARRAY_RANDOM_NOP, FLOAT_ISLE); 430 TEST_QSORT_ARRAY(VersionTuple, versions, arraylen, compare_version, CHECK_ELEMS_SORTED_ARRAY_RANDOM_VERSION, VERSION_ISLE); 431 432 SDL_free(ints); 433 SDL_free(floats); 434 SDL_free(versions); 435 } 436 return TEST_COMPLETED; 437} 438 439static const SDLTest_TestCaseReference qsortTestAlreadySorted = { 440 qsort_testAlreadySorted, "qsort_testAlreadySorted", "Test sorting already sorted array", TEST_ENABLED 441}; 442 443static const SDLTest_TestCaseReference qsortTestAlreadySortedExceptLast = { 444 qsort_testAlreadySortedExceptLast, "qsort_testAlreadySortedExceptLast", "Test sorting nearly sorted array (last item is not in order)", TEST_ENABLED 445}; 446 447static const SDLTest_TestCaseReference qsortTestReverseSorted = { 448 qsort_testReverseSorted, "qsort_testReverseSorted", "Test sorting an array in reverse order", TEST_ENABLED 449}; 450 451static const SDLTest_TestCaseReference qsortTestRandomSorted = { 452 qsort_testRandomSorted, "qsort_testRandomSorted", "Test sorting a random array", TEST_ENABLED 453}; 454 455static const SDLTest_TestCaseReference *qsortTests[] = { 456 &qsortTestAlreadySorted, 457 &qsortTestAlreadySortedExceptLast, 458 &qsortTestReverseSorted, 459 &qsortTestRandomSorted, 460 NULL 461}; 462 463static SDLTest_TestSuiteReference qsortTestSuite = { 464 "qsort", 465 NULL, 466 qsortTests, 467 NULL 468}; 469 470static SDLTest_TestSuiteReference *testSuites[] = { 471 &qsortTestSuite, 472 NULL 473}; 474 475int main(int argc, char *argv[]) 476{ 477 int i; 478 int result; 479 SDLTest_CommonState *state; 480 SDLTest_TestSuiteRunner *runner; 481 bool list = false; 482 483 /* Initialize test framework */ 484 state = SDLTest_CommonCreateState(argv, 0); 485 if (!state) { 486 return 1; 487 } 488 489 runner = SDLTest_CreateTestSuiteRunner(state, testSuites); 490 491 /* Parse commandline */ 492 for (i = 1; i < argc;) { 493 int consumed; 494 495 consumed = SDLTest_CommonArg(state, i); 496 if (!consumed) { 497 498 if (SDL_strcasecmp(argv[i], "--array-lengths") == 0) { 499 count_arraylens = 0; 500 consumed = 1; 501 while (argv[i + consumed] && argv[i + consumed][0] != '-') { 502 char *endptr = NULL; 503 unsigned int arraylen = (unsigned int)SDL_strtoul(argv[i + 1], &endptr, 10); 504 if (*endptr != '\0') { 505 count_arraylens = 0; 506 break; 507 } 508 if (count_arraylens >= SDL_arraysize(arraylens)) { 509 SDL_LogWarn(SDL_LOG_CATEGORY_TEST, "Dropping array length %d", arraylen); 510 } else { 511 arraylens[count_arraylens] = arraylen; 512 } 513 count_arraylens++; 514 consumed++; 515 } 516 if (consumed == 0) { 517 SDL_LogError(SDL_LOG_CATEGORY_TEST, "--array-lengths needs positive int numbers"); 518 } 519 } else if (SDL_strcasecmp(argv[i], "--list") == 0) { 520 consumed = 1; 521 list = true; 522 } 523 } 524 if (consumed <= 0) { 525 static const char *options[] = { 526 "[--list]", 527 "[--array-lengths N1 [N2 [N3 [...]]]", 528 NULL 529 }; 530 SDLTest_CommonLogUsage(state, argv[0], options); 531 return 1; 532 } 533 534 i += consumed; 535 } 536 537 /* List all suites. */ 538 if (list) { 539 int suiteCounter; 540 for (suiteCounter = 0; testSuites[suiteCounter]; ++suiteCounter) { 541 int testCounter; 542 SDLTest_TestSuiteReference *testSuite = testSuites[suiteCounter]; 543 SDL_Log("Test suite: %s", testSuite->name); 544 for (testCounter = 0; testSuite->testCases[testCounter]; ++testCounter) { 545 const SDLTest_TestCaseReference *testCase = testSuite->testCases[testCounter]; 546 SDL_Log(" test: %s%s", testCase->name, testCase->enabled ? "" : " (disabled)"); 547 } 548 } 549 result = 0; 550 } else { 551 result = SDLTest_ExecuteTestSuiteRunner(runner); 552 } 553 554 SDL_Quit(); 555 SDLTest_DestroyTestSuiteRunner(runner); 556 SDLTest_CommonDestroyState(state); 557 return result; 558} 559[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.