update SDL3 from 3.2.20 to 3.4.2

This commit is contained in:
Sven Balzer
2026-04-01 18:25:03 +02:00
parent 1daf4d79f1
commit 05b19704f8
1626 changed files with 124218 additions and 191491 deletions
+29 -31
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -25,28 +25,7 @@
*/
#include <SDL3/SDL_test.h>
/* Enable to have color in logs */
#if 1
#define COLOR_RED "\033[0;31m"
#define COLOR_GREEN "\033[0;32m"
#define COLOR_YELLOW "\033[0;93m"
#define COLOR_BLUE "\033[0;94m"
#define COLOR_END "\033[0m"
#else
#define COLOR_RED ""
#define COLOR_GREEN ""
#define COLOR_BLUE ""
#define COLOR_YELLOW ""
#define COLOR_END ""
#endif
/* Assert check message format */
#define SDLTEST_ASSERT_CHECK_FORMAT "Assert '%s': %s"
/* Assert summary message format */
#define SDLTEST_ASSERT_SUMMARY_FORMAT "Assert Summary: Total=%d " COLOR_GREEN "Passed=%d" COLOR_END " " COLOR_RED "Failed=%d" COLOR_END
#define SDLTEST_ASSERT_SUMMARY_FORMAT_OK "Assert Summary: Total=%d " COLOR_GREEN "Passed=%d" COLOR_END " " COLOR_GREEN "Failed=%d" COLOR_END
#include "SDL_test_internal.h"
/* ! counts the failed asserts */
static int SDLTest_AssertsFailed = 0;
@@ -54,6 +33,24 @@ static int SDLTest_AssertsFailed = 0;
/* ! counts the passed asserts */
static int SDLTest_AssertsPassed = 0;
static void SDLTest_LogAssertMessage(bool success, const char *assertion)
{
SDL_LogPriority priority;
const char *color;
const char *message;
if (success) {
priority = SDL_LOG_PRIORITY_INFO;
color = COLOR_GREEN;
message = "Passed";
} else {
priority = SDL_LOG_PRIORITY_ERROR;
color = COLOR_RED;
message = "Failed";
}
SDLTest_LogMessage(priority, "Assert '%s': %s%s%s", assertion, color, message, COLOR_END);
}
/*
* Assert that logs and break execution flow on failures (i.e. for harness errors).
*/
@@ -89,10 +86,10 @@ int SDLTest_AssertCheck(int assertCondition, SDL_PRINTF_FORMAT_STRING const char
/* Log pass or fail message */
if (assertCondition == ASSERT_FAIL) {
SDLTest_AssertsFailed++;
SDLTest_LogError(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, COLOR_RED "Failed" COLOR_END);
SDLTest_LogAssertMessage(false, logMessage);
} else {
SDLTest_AssertsPassed++;
SDLTest_Log(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, COLOR_GREEN "Passed" COLOR_END);
SDLTest_LogAssertMessage(true, logMessage);
}
return assertCondition;
@@ -114,7 +111,7 @@ void SDLTest_AssertPass(SDL_PRINTF_FORMAT_STRING const char *assertDescription,
/* Log pass message */
SDLTest_AssertsPassed++;
SDLTest_Log(SDLTEST_ASSERT_CHECK_FORMAT, logMessage, COLOR_GREEN "Passed" COLOR_END);
SDLTest_LogAssertMessage(true, logMessage);
}
/*
@@ -133,11 +130,12 @@ void SDLTest_ResetAssertSummary(void)
void SDLTest_LogAssertSummary(void)
{
int totalAsserts = SDLTest_AssertsPassed + SDLTest_AssertsFailed;
if (SDLTest_AssertsFailed == 0) {
SDLTest_Log(SDLTEST_ASSERT_SUMMARY_FORMAT_OK, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed);
} else {
SDLTest_LogError(SDLTEST_ASSERT_SUMMARY_FORMAT, totalAsserts, SDLTest_AssertsPassed, SDLTest_AssertsFailed);
}
bool success = SDLTest_AssertsFailed == 0;
SDLTest_LogMessage(success ? SDL_LOG_PRIORITY_INFO : SDL_LOG_PRIORITY_ERROR,
"Assert Summary: Total=%d " "%s" "Passed=%d" "%s" " " "%s" "Failed=%d" "%s",
totalAsserts, COLOR_GREEN, SDLTest_AssertsPassed, COLOR_END,
success ? COLOR_GREEN : COLOR_RED, SDLTest_AssertsFailed, COLOR_END);
}
/*
+148 -23
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -21,15 +21,28 @@
/* Ported from original test/common.c file. */
#include <SDL3/SDL_test.h>
#include "SDL_test_internal.h"
#define SDL_MAIN_NOIMPL
#define SDL_MAIN_USE_CALLBACKS
#include <SDL3/SDL_main.h>
bool SDLTest_Color = true;
static bool get_environment_bool_variable(const char *name)
{
const char *var_string = SDL_GetEnvironmentVariable(SDL_GetEnvironment(), name);
if (!var_string || var_string[0] == '\0') {
return false;
}
return true;
}
static const char *common_usage[] = {
"[-h | --help]",
"[--trackmem]",
"[--randmem]",
"[--no-color]",
"[--info all|video|modes|render|event|event_motion]",
"[--log all|error|system|audio|video|render|input]",
NULL
@@ -63,6 +76,7 @@ static const char *video_usage[] = {
"[--minimize]",
"[--mouse-focus]",
"[--noframe]",
"[--quit-after-ms N]",
"[--refresh R]",
"[--renderer driver]",
"[--resizable]",
@@ -86,6 +100,16 @@ static const char *audio_usage[] = {
NULL
};
// tests can quit after N ms
static Uint32 SDLCALL quit_after_ms_cb(void *userdata, SDL_TimerID timerID, Uint32 interval)
{
SDL_Event event;
event.type = SDL_EVENT_QUIT;
event.common.timestamp = 0;
SDL_PushEvent(&event);
return 0;
}
static void SDL_snprintfcat(SDL_OUT_Z_CAP(maxlen) char *text, size_t maxlen, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
size_t length = SDL_strlen(text);
@@ -131,6 +155,10 @@ static int SDLCALL SDLTest_CommonStateParseCommonArguments(void *data, char **ar
/* Already handled in SDLTest_CommonCreateState() */
return 1;
}
if (SDL_strcasecmp(argv[index], "--no-color") == 0) {
SDLTest_Color = false;
return 1;
}
if (SDL_strcasecmp(argv[index], "--randmem") == 0) {
/* Already handled in SDLTest_CommonCreateState() */
return 1;
@@ -509,6 +537,17 @@ static int SDLCALL SDLTest_CommonStateParseVideoArguments(void *data, char **arg
state->window_flags |= SDL_WINDOW_BORDERLESS;
return 1;
}
if (SDL_strcasecmp(argv[index], "--quit-after-ms") == 0) {
++index;
if (!argv[index]) {
return -1;
}
state->quit_after_ms_interval = SDL_atoi(argv[index]);
if (state->quit_after_ms_interval <= 0) {
return -1;
}
return 2;
}
if (SDL_strcasecmp(argv[index], "--resizable") == 0) {
state->window_flags |= SDL_WINDOW_RESIZABLE;
return 1;
@@ -664,6 +703,8 @@ SDLTest_CommonState *SDLTest_CommonCreateState(char **argv, SDL_InitFlags flags)
int i;
SDLTest_CommonState *state;
SDLTest_Color = !get_environment_bool_variable("NO_COLOR");
/* Do this first so we catch all allocations */
for (i = 1; argv[i]; ++i) {
if (SDL_strcasecmp(argv[i], "--trackmem") == 0) {
@@ -1121,7 +1162,7 @@ static SDL_Surface *SDLTest_LoadIcon(const char *file)
SDL_Surface *icon;
/* Load the icon surface */
icon = SDL_LoadBMP(file);
icon = SDL_LoadSurface(file);
if (!icon) {
SDL_Log("Couldn't load %s: %s", file, SDL_GetError());
return NULL;
@@ -1523,8 +1564,11 @@ bool SDLTest_CommonInit(SDLTest_CommonState *state)
}
}
if (state->flags & SDL_INIT_CAMERA) {
SDL_InitSubSystem(SDL_INIT_CAMERA);
SDL_InitSubSystem(state->flags);
if (state->quit_after_ms_interval) {
state->quit_after_ms_timer = SDL_AddTimer(state->quit_after_ms_interval, quit_after_ms_cb, NULL);
}
return true;
@@ -1626,6 +1670,14 @@ void SDLTest_PrintEvent(const SDL_Event *event)
event->display.displayID, (int)(scale * 100.0f));
}
break;
case SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED:
{
SDL_Rect bounds;
SDL_GetDisplayUsableBounds(event->display.displayID, &bounds);
SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " changed usable bounds to %dx%d at %d,%d",
event->display.displayID, bounds.w, bounds.h, bounds.x, bounds.y);
}
break;
case SDL_EVENT_DISPLAY_DESKTOP_MODE_CHANGED:
SDL_Log("SDL EVENT: Display %" SDL_PRIu32 " desktop mode changed to %" SDL_PRIs32 "x%" SDL_PRIs32,
event->display.displayID, event->display.data1, event->display.data2);
@@ -1733,12 +1785,12 @@ void SDLTest_PrintEvent(const SDL_Event *event)
SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " HDR %s", event->window.windowID, event->window.data1 ? "enabled" : "disabled");
break;
case SDL_EVENT_KEYBOARD_ADDED:
SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " attached",
event->kdevice.which);
SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " (%s) attached",
event->kdevice.which, SDL_GetKeyboardNameForID(event->kdevice.which));
break;
case SDL_EVENT_KEYBOARD_REMOVED:
SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " removed",
event->kdevice.which);
SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " (%s) removed",
event->kdevice.which, SDL_GetKeyboardNameForID(event->kdevice.which));
break;
case SDL_EVENT_KEY_DOWN:
case SDL_EVENT_KEY_UP: {
@@ -1775,12 +1827,12 @@ void SDLTest_PrintEvent(const SDL_Event *event)
SDL_Log("SDL EVENT: Keymap changed");
break;
case SDL_EVENT_MOUSE_ADDED:
SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " attached",
event->mdevice.which);
SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " (%s) attached",
event->mdevice.which, SDL_GetMouseNameForID(event->mdevice.which));
break;
case SDL_EVENT_MOUSE_REMOVED:
SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " removed",
event->mdevice.which);
SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " (%s) removed",
event->mdevice.which, SDL_GetMouseNameForID(event->mdevice.which));
break;
case SDL_EVENT_MOUSE_MOTION:
SDL_Log("SDL EVENT: Mouse: moved to %g,%g (%g,%g) in window %" SDL_PRIu32,
@@ -1803,12 +1855,12 @@ void SDLTest_PrintEvent(const SDL_Event *event)
event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID);
break;
case SDL_EVENT_JOYSTICK_ADDED:
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " attached",
event->jdevice.which);
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " (%s) attached",
event->jdevice.which, SDL_GetJoystickNameForID(event->jdevice.which));
break;
case SDL_EVENT_JOYSTICK_REMOVED:
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " removed",
event->jdevice.which);
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " (%s) removed",
event->jdevice.which, SDL_GetJoystickNameForID(event->jdevice.which));
break;
case SDL_EVENT_JOYSTICK_AXIS_MOTION:
SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " axis %d value: %d",
@@ -1869,12 +1921,12 @@ void SDLTest_PrintEvent(const SDL_Event *event)
event->jbattery.which, event->jbattery.percent);
break;
case SDL_EVENT_GAMEPAD_ADDED:
SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " attached",
event->gdevice.which);
SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " (%s) attached",
event->gdevice.which, SDL_GetGamepadNameForID(event->gdevice.which));
break;
case SDL_EVENT_GAMEPAD_REMOVED:
SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " removed",
event->gdevice.which);
SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " (%s) removed",
event->gdevice.which, SDL_GetGamepadNameForID(event->gdevice.which));
break;
case SDL_EVENT_GAMEPAD_REMAPPED:
SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " mapping changed",
@@ -1920,6 +1972,16 @@ void SDLTest_PrintEvent(const SDL_Event *event)
event->tfinger.dx, event->tfinger.dy, event->tfinger.pressure);
break;
case SDL_EVENT_PINCH_BEGIN:
SDL_Log("SDL EVENT: Pinch Begin");
break;
case SDL_EVENT_PINCH_UPDATE:
SDL_Log("SDL EVENT: Pinch Update, scale=%f", event->pinch.scale);
break;
case SDL_EVENT_PINCH_END:
SDL_Log("SDL EVENT: Pinch End");
break;
case SDL_EVENT_RENDER_TARGETS_RESET:
SDL_Log("SDL EVENT: render targets reset in window %" SDL_PRIu32, event->render.windowID);
break;
@@ -2059,9 +2121,7 @@ static void SDLCALL SDLTest_ScreenShotClipboardCleanup(void *context)
SDL_Log("Cleaning up screenshot image data");
if (data->image) {
SDL_free(data->image);
}
SDL_free(data->image);
SDL_free(data);
}
@@ -2230,6 +2290,7 @@ SDL_AppResult SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const
event->type != SDL_EVENT_FINGER_MOTION &&
event->type != SDL_EVENT_PEN_MOTION &&
event->type != SDL_EVENT_PEN_AXIS &&
event->type != SDL_EVENT_PINCH_UPDATE &&
event->type != SDL_EVENT_JOYSTICK_AXIS_MOTION) ||
(state->verbose & VERBOSE_MOTION)) {
SDLTest_PrintEvent(event);
@@ -2455,6 +2516,66 @@ SDL_AppResult SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const
}
}
break;
case SDLK_D:
if (withControl) {
/* Ctrl-D toggle fill-document */
SDL_Window *window = SDL_GetWindowFromEvent(event);
if (window) {
SDL_SetWindowFillDocument(window, !((SDL_GetWindowFlags(window) & SDL_WINDOW_FILL_DOCUMENT) != 0));
}
}
break;
case SDLK_P:
if (withAlt) {
/* Alt-P cycle through progress states */
SDL_Window *window = SDL_GetWindowFromEvent(event);
if (window) {
const char *name;
SDL_ProgressState progress_state = SDL_GetWindowProgressState(window);
progress_state += 1;
if (progress_state > SDL_PROGRESS_STATE_ERROR) {
progress_state = SDL_PROGRESS_STATE_NONE;
}
switch (progress_state) {
case SDL_PROGRESS_STATE_NONE:
name = "NONE";
break;
case SDL_PROGRESS_STATE_INDETERMINATE:
name = "INDETERMINATE";
break;
case SDL_PROGRESS_STATE_NORMAL:
name = "NORMAL";
break;
case SDL_PROGRESS_STATE_PAUSED:
name = "PAUSED";
break;
case SDL_PROGRESS_STATE_ERROR:
name = "ERROR";
break;
default:
name = "UNKNOWN";
break;
}
SDL_Log("Setting progress state to %s", name);
SDL_SetWindowProgressState(window, progress_state);
}
}
else if (withControl)
{
/* Ctrl-P increase progress value */
SDL_Window *window = SDL_GetWindowFromEvent(event);
if (window) {
float progress_value = SDL_GetWindowProgressValue(window);
if (withShift) {
progress_value -= 0.1f;
} else {
progress_value += 0.1f;
}
SDL_Log("Setting progress value to %.1f", progress_value);
SDL_SetWindowProgressValue(window, progress_value);
}
}
break;
case SDLK_G:
if (withControl) {
/* Ctrl-G toggle mouse grab */
@@ -2659,6 +2780,10 @@ void SDLTest_CommonQuit(SDLTest_CommonState *state)
}
SDL_free(state->windows);
}
if (state->quit_after_ms_timer) {
SDL_RemoveTimer(state->quit_after_ms_timer);
}
}
SDL_Quit();
SDLTest_CommonDestroyState(state);
+109 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -139,6 +139,114 @@ int SDLTest_CompareSurfaces(SDL_Surface *surface, SDL_Surface *referenceSurface,
return ret;
}
int SDLTest_CompareSurfacesIgnoreTransparentPixels(SDL_Surface *surface, SDL_Surface *referenceSurface, int allowable_error)
{
int ret;
int i, j;
int dist;
int sampleErrorX = 0, sampleErrorY = 0, sampleDist = 0;
SDL_Color sampleReference = { 0, 0, 0, 0 };
SDL_Color sampleActual = { 0, 0, 0, 0 };
Uint8 R, G, B, A;
Uint8 Rd, Gd, Bd, Ad;
char imageFilename[FILENAME_SIZE];
char referenceFilename[FILENAME_SIZE];
/* Validate input surfaces */
if (!surface) {
SDLTest_LogError("Cannot compare NULL surface");
return -1;
}
if (!referenceSurface) {
SDLTest_LogError("Cannot compare NULL reference surface");
return -1;
}
/* Make sure surface size is the same. */
if ((surface->w != referenceSurface->w) || (surface->h != referenceSurface->h)) {
SDLTest_LogError("Expected %dx%d surface, got %dx%d", referenceSurface->w, referenceSurface->h, surface->w, surface->h);
return -2;
}
/* Sanitize input value */
if (allowable_error < 0) {
allowable_error = 0;
}
SDL_LockSurface(surface);
SDL_LockSurface(referenceSurface);
ret = 0;
/* Compare image - should be same format. */
for (j = 0; j < surface->h; j++) {
for (i = 0; i < surface->w; i++) {
int temp;
temp = SDL_ReadSurfacePixel(surface, i, j, &R, &G, &B, &A);
if (!temp) {
SDLTest_LogError("Failed to retrieve pixel (%d,%d): %s", i, j, SDL_GetError());
ret++;
continue;
}
temp = SDL_ReadSurfacePixel(referenceSurface, i, j, &Rd, &Gd, &Bd, &Ad);
if (!temp) {
SDLTest_LogError("Failed to retrieve reference pixel (%d,%d): %s", i, j, SDL_GetError());
ret++;
continue;
}
if (Ad == SDL_ALPHA_TRANSPARENT) {
continue;
}
dist = 0;
dist += (R - Rd) * (R - Rd);
dist += (G - Gd) * (G - Gd);
dist += (B - Bd) * (B - Bd);
/* Allow some difference in blending accuracy */
if (dist > allowable_error) {
ret++;
if (ret == 1) {
sampleErrorX = i;
sampleErrorY = j;
sampleDist = dist;
sampleReference.r = Rd;
sampleReference.g = Gd;
sampleReference.b = Bd;
sampleReference.a = Ad;
sampleActual.r = R;
sampleActual.g = G;
sampleActual.b = B;
sampleActual.a = A;
}
}
}
}
SDL_UnlockSurface(surface);
SDL_UnlockSurface(referenceSurface);
/* Save test image and reference for analysis on failures */
_CompareSurfaceCount++;
if (ret != 0) {
SDLTest_LogError("Comparison of pixels with allowable error of %i failed %i times.", allowable_error, ret);
SDLTest_LogError("Reference surface format: %s", SDL_GetPixelFormatName(referenceSurface->format));
SDLTest_LogError("Actual surface format: %s", SDL_GetPixelFormatName(surface->format));
SDLTest_LogError("First detected occurrence at position %i,%i with a squared RGB-difference of %i.", sampleErrorX, sampleErrorY, sampleDist);
SDLTest_LogError("Reference pixel: R=%u G=%u B=%u A=%u", sampleReference.r, sampleReference.g, sampleReference.b, sampleReference.a);
SDLTest_LogError("Actual pixel : R=%u G=%u B=%u A=%u", sampleActual.r, sampleActual.g, sampleActual.b, sampleActual.a);
(void)SDL_snprintf(imageFilename, FILENAME_SIZE - 1, "CompareSurfaces%04d_TestOutput.bmp", _CompareSurfaceCount);
SDL_SaveBMP(surface, imageFilename);
(void)SDL_snprintf(referenceFilename, FILENAME_SIZE - 1, "CompareSurfaces%04d_Reference.bmp", _CompareSurfaceCount);
SDL_SaveBMP(referenceSurface, referenceFilename);
SDLTest_LogError("Surfaces from failed comparison saved as '%s' and '%s'", imageFilename, referenceFilename);
}
return ret;
}
int SDLTest_CompareMemory(const void *actual, size_t size_actual, const void *reference, size_t size_reference) {
#define WIDTH 16
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+43 -46
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -19,33 +19,25 @@
3. This notice may not be removed or altered from any source distribution.
*/
#include <SDL3/SDL_test.h>
#include "SDL_test_internal.h"
#include <stdlib.h> /* Needed for exit() */
/* Enable to have color in logs */
#if 1
#define COLOR_RED "\033[0;31m"
#define COLOR_GREEN "\033[0;32m"
#define COLOR_YELLOW "\033[0;93m"
#define COLOR_BLUE "\033[0;94m"
#define COLOR_END "\033[0m"
#else
#define COLOR_RED ""
#define COLOR_GREEN ""
#define COLOR_BLUE ""
#define COLOR_YELLOW ""
#define COLOR_END ""
#endif
/* Invalid test name/description message format */
#define SDLTEST_INVALID_NAME_FORMAT "(Invalid)"
/* Log summary message format */
#define SDLTEST_LOG_SUMMARY_FORMAT "%s Summary: Total=%d " COLOR_GREEN "Passed=%d" COLOR_END " " COLOR_RED "Failed=%d" COLOR_END " " COLOR_BLUE "Skipped=%d" COLOR_END
#define SDLTEST_LOG_SUMMARY_FORMAT_OK "%s Summary: Total=%d " COLOR_GREEN "Passed=%d" COLOR_END " " COLOR_GREEN "Failed=%d" COLOR_END " " COLOR_BLUE "Skipped=%d" COLOR_END
static void SDLTest_LogSummary(bool success, const char *name, int total, int passed, int failed, int skipped)
{
SDLTest_LogMessage(success ? SDL_LOG_PRIORITY_INFO : SDL_LOG_PRIORITY_ERROR,
"%s Summary: Total=%d " "%s" "Passed=%d" "%s" " " "%s" "Failed=%d" "%s" " " "%s" "Skipped=%d" "%s",
name, total, COLOR_GREEN, passed, COLOR_END, success ? COLOR_GREEN : COLOR_RED, failed, COLOR_END, COLOR_BLUE, skipped, COLOR_END);
}
/* Final result message format */
#define SDLTEST_FINAL_RESULT_FORMAT COLOR_YELLOW ">>> %s '%s':" COLOR_END " %s\n"
static void SDLTest_LogFinalResult(bool success, const char *stage, const char *name, const char *color_message, const char *message)
{
SDL_LogPriority priority = success ? SDL_LOG_PRIORITY_INFO : SDL_LOG_PRIORITY_ERROR;
SDLTest_LogMessage(priority, "%s>>> %s '%s':" "%s" " " "%s" "%s" "%s", COLOR_YELLOW, stage, name, COLOR_END, color_message ? color_message : "", message, color_message ? COLOR_END : "");
}
struct SDLTest_TestSuiteRunner {
struct
@@ -192,7 +184,6 @@ static SDL_TimerID SDLTest_SetTestTimeout(int timeout, SDL_TimerCallback callbac
SDLTest_LogError("Timeout callback can't be NULL");
return 0;
}
if (timeout < 0) {
SDLTest_LogError("Timeout value must be bigger than zero.");
return 0;
@@ -200,7 +191,7 @@ static SDL_TimerID SDLTest_SetTestTimeout(int timeout, SDL_TimerCallback callbac
/* Set timer */
timeoutInMilliseconds = timeout * 1000;
timerID = SDL_AddTimer(timeoutInMilliseconds, callback, 0x0);
timerID = SDL_AddTimer(timeoutInMilliseconds, callback, NULL);
if (timerID == 0) {
SDLTest_LogError("Creation of SDL timer failed: %s", SDL_GetError());
return 0;
@@ -243,7 +234,7 @@ static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_
}
if (!testCase->enabled && forceTestRun == false) {
SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, "Skipped (Disabled)");
SDLTest_LogFinalResult(true, "Test", testCase->name, NULL, "Skipped (Disabled)");
return TEST_RESULT_SKIPPED;
}
@@ -260,7 +251,7 @@ static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_
if (testSuite->testSetUp) {
testSuite->testSetUp(&data);
if (SDLTest_AssertSummaryToTestResult() == TEST_RESULT_FAILED) {
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Suite Setup", testSuite->name, COLOR_RED "Failed" COLOR_END);
SDLTest_LogFinalResult(false, "Suite Setup", testSuite->name, COLOR_RED, "Failed");
return TEST_RESULT_SETUP_FAILURE;
}
}
@@ -302,13 +293,13 @@ static int SDLTest_RunTest(SDLTest_TestSuiteReference *testSuite, const SDLTest_
/* Final log based on test execution result */
if (testCaseResult == TEST_SKIPPED) {
/* Test was programmatically skipped */
SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, COLOR_BLUE "Skipped (Programmatically)" COLOR_END);
SDLTest_LogFinalResult(true, "Test", testCase->name, COLOR_BLUE, "Skipped (Programmatically)");
} else if (testCaseResult == TEST_STARTED) {
/* Test did not return a TEST_COMPLETED value; assume it failed */
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, COLOR_RED "Failed (test started, but did not return TEST_COMPLETED)" COLOR_END);
SDLTest_LogFinalResult(false, "Test", testCase->name, COLOR_RED, "Skipped (test started, but did not return TEST_COMPLETED)");
} else if (testCaseResult == TEST_ABORTED) {
/* Test was aborted early; assume it failed */
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", testCase->name, COLOR_RED "Failed (Aborted)" COLOR_END);
SDLTest_LogFinalResult(false, "Test", testCase->name, COLOR_RED, "Failed (Aborted)");
} else {
SDLTest_LogAssertSummary();
}
@@ -573,9 +564,11 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
if (suiteFilter == 1 && suiteFilterName && testSuite->name &&
SDL_strcasecmp(suiteFilterName, testSuite->name) != 0) {
/* Skip suite */
SDLTest_Log("===== Test Suite %i: '%s' " COLOR_BLUE "skipped" COLOR_END "\n",
SDLTest_Log("===== Test Suite %i: '%s' " "%s" "skipped" "%s" "\n",
suiteCounter,
currentSuiteName);
currentSuiteName,
COLOR_BLUE,
COLOR_END);
} else {
int nbTestCases = 0;
@@ -635,10 +628,12 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
if (testFilter == 1 && testFilterName && testCase->name &&
SDL_strcasecmp(testFilterName, testCase->name) != 0) {
/* Skip test */
SDLTest_Log("===== Test Case %i.%i: '%s' " COLOR_BLUE "skipped" COLOR_END "\n",
SDLTest_Log("===== Test Case %i.%i: '%s' " "%s" "skipped" "%s" "\n",
suiteCounter,
testCounter,
currentTestName);
currentTestName,
COLOR_BLUE,
COLOR_END);
} else {
/* Override 'disabled' flag if we specified a test filter (i.e. force run for debugging) */
if (testFilter == 1 && !testCase->enabled) {
@@ -650,10 +645,12 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
testStartSeconds = GetClock();
/* Log test started */
SDLTest_Log(COLOR_YELLOW "----- Test Case %i.%i: '%s' started" COLOR_END,
SDLTest_Log("%s" "----- Test Case %i.%i: '%s' started" "%s",
COLOR_YELLOW,
suiteCounter,
testCounter,
currentTestName);
currentTestName,
COLOR_END);
if (testCase->description && testCase->description[0] != '\0') {
SDLTest_Log("Test Description: '%s'",
(testCase->description) ? testCase->description : SDLTEST_INVALID_NAME_FORMAT);
@@ -704,13 +701,13 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
/* Log final test result */
switch (testResult) {
case TEST_RESULT_PASSED:
SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, COLOR_GREEN "Passed" COLOR_END);
SDLTest_LogFinalResult(true, "Test", currentTestName, COLOR_GREEN, "Passed");
break;
case TEST_RESULT_FAILED:
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, COLOR_RED "Failed" COLOR_END);
SDLTest_LogFinalResult(false, "Test", currentTestName, COLOR_RED, "Failed");
break;
case TEST_RESULT_NO_ASSERT:
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Test", currentTestName, COLOR_BLUE "No Asserts" COLOR_END);
SDLTest_LogFinalResult(false, "Test", currentTestName, COLOR_BLUE, "No Asserts");
break;
}
@@ -735,11 +732,11 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
/* Log summary and final Suite result */
countSum = testPassedCount + testFailedCount + testSkippedCount;
if (testFailedCount == 0) {
SDLTest_Log(SDLTEST_LOG_SUMMARY_FORMAT_OK, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount);
SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Suite", currentSuiteName, COLOR_GREEN "Passed" COLOR_END);
SDLTest_LogSummary(true, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount);
SDLTest_LogFinalResult(true, "Suite", currentSuiteName, COLOR_GREEN, "Passed");
} else {
SDLTest_LogError(SDLTEST_LOG_SUMMARY_FORMAT, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount);
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Suite", currentSuiteName, COLOR_RED "Failed" COLOR_END);
SDLTest_LogSummary(false, "Suite", countSum, testPassedCount, testFailedCount, testSkippedCount);
SDLTest_LogFinalResult(false, "Suite", currentSuiteName, COLOR_RED, "Failed");
}
SDL_free(arrayTestCases);
@@ -762,19 +759,19 @@ int SDLTest_ExecuteTestSuiteRunner(SDLTest_TestSuiteRunner *runner)
countSum = totalTestPassedCount + totalTestFailedCount + totalTestSkippedCount;
if (totalTestFailedCount == 0) {
runResult = 0;
SDLTest_Log(SDLTEST_LOG_SUMMARY_FORMAT_OK, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount);
SDLTest_Log(SDLTEST_FINAL_RESULT_FORMAT, "Run /w seed", runSeed, COLOR_GREEN "Passed" COLOR_END);
SDLTest_LogSummary(true, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount);
SDLTest_LogFinalResult(true, "Run /w seed", runSeed, COLOR_GREEN, "Passed");
} else {
runResult = 1;
SDLTest_LogError(SDLTEST_LOG_SUMMARY_FORMAT, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount);
SDLTest_LogError(SDLTEST_FINAL_RESULT_FORMAT, "Run /w seed", runSeed, COLOR_RED "Failed" COLOR_END);
SDLTest_LogSummary(false, "Run", countSum, totalTestPassedCount, totalTestFailedCount, totalTestSkippedCount);
SDLTest_LogFinalResult(false, "Run /w seed", runSeed, COLOR_RED, "Failed");
}
/* Print repro steps for failed tests */
if (failedNumberOfTests > 0) {
SDLTest_Log("Harness input to repro failures:");
for (testCounter = 0; testCounter < failedNumberOfTests; testCounter++) {
SDLTest_Log(COLOR_RED " --seed %s --filter %s" COLOR_END, runSeed, failedTests[testCounter]->name);
SDLTest_Log("%s" " --seed %s --filter %s" "%s", COLOR_RED, runSeed, failedTests[testCounter]->name, COLOR_END);
}
}
SDL_free((void *)failedTests);
+38
View File
@@ -0,0 +1,38 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_test_internal_h
#define SDL_test_internal_h
extern bool SDLTest_Color;
#define COLOR_RAW_RED "\033[0;31m"
#define COLOR_RAW_GREEN "\033[0;32m"
#define COLOR_RAW_YELLOW "\033[0;93m"
#define COLOR_RAW_BLUE "\033[0;94m"
#define COLOR_RAW_END "\033[0m"
#define COLOR_RED (SDLTest_Color ? COLOR_RAW_RED : "")
#define COLOR_GREEN (SDLTest_Color ? COLOR_RAW_GREEN : "")
#define COLOR_YELLOW (SDLTest_Color ? COLOR_RAW_YELLOW : "")
#define COLOR_BLUE (SDLTest_Color ? COLOR_RAW_BLUE : "")
#define COLOR_END (SDLTest_Color ? COLOR_RAW_END : "")
#endif // SDL_test_internal_h
+38 -21
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -20,9 +20,7 @@
*/
/*
Used by the test framework and test cases.
*/
/* quiet windows compiler warnings */
@@ -75,21 +73,46 @@ static const char *SDLTest_TimestampToString(const time_t timestamp)
}
/*
* Prints given message with a timestamp in the TEST category and INFO priority.
* Prints given message with a timestamp in the TEST category and given priority.
*/
void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
static void SDLTest_LogMessageV(SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, va_list ap)
{
va_list list;
char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
/* Print log message into a buffer */
SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH);
va_start(list, fmt);
(void)SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, fmt, list);
va_end(list);
(void)SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, fmt, ap);
/* Log with timestamp and newline */
SDL_LogMessage(SDL_LOG_CATEGORY_TEST, SDL_LOG_PRIORITY_INFO, " %s: %s", SDLTest_TimestampToString(time(0)), logMessage);
/* Log with timestamp and newline. Messages with lower priority are slightly indented. */
if (priority > SDL_LOG_PRIORITY_INFO) {
SDL_LogMessage(SDL_LOG_CATEGORY_TEST, priority, "%s: %s", SDLTest_TimestampToString(time(NULL)), logMessage);
} else {
SDL_LogMessage(SDL_LOG_CATEGORY_TEST, priority, " %s: %s", SDLTest_TimestampToString(time(NULL)), logMessage);
}
}
/*
* Prints given message with a timestamp in the TEST category and given priority.
*/
void SDLTest_LogMessage(SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
SDLTest_LogMessageV(priority, fmt, ap);
va_end(ap);
}
/*
* Prints given message with a timestamp in the TEST category and INFO priority.
*/
void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
SDLTest_LogMessageV(SDL_LOG_PRIORITY_INFO, fmt, ap);
va_end(ap);
}
/*
@@ -97,17 +120,11 @@ void SDLTest_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
*/
void SDLTest_LogError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
{
va_list list;
char logMessage[SDLTEST_MAX_LOGMESSAGE_LENGTH];
va_list ap;
/* Print log message into a buffer */
SDL_memset(logMessage, 0, SDLTEST_MAX_LOGMESSAGE_LENGTH);
va_start(list, fmt);
(void)SDL_vsnprintf(logMessage, SDLTEST_MAX_LOGMESSAGE_LENGTH - 1, fmt, list);
va_end(list);
/* Log with timestamp and newline */
SDL_LogMessage(SDL_LOG_CATEGORY_TEST, SDL_LOG_PRIORITY_ERROR, "%s: %s", SDLTest_TimestampToString(time(0)), logMessage);
va_start(ap, fmt);
SDLTest_LogMessageV(SDL_LOG_PRIORITY_ERROR, fmt, ap);
va_end(ap);
}
static char nibble_to_char(Uint8 nibble)
+1 -1
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
+10 -9
View File
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -95,7 +95,7 @@ static unsigned int get_allocation_bucket(void *mem)
return index;
}
static SDL_tracked_allocation* SDL_GetTrackedAllocation(void *mem)
static SDL_tracked_allocation *SDL_GetTrackedAllocation(void *mem)
{
SDL_tracked_allocation *entry;
LOCK_ALLOCATOR();
@@ -216,9 +216,9 @@ static void SDL_UntrackAllocation(void *mem)
UNLOCK_ALLOCATOR();
}
static void rand_fill_memory(void* ptr, size_t start, size_t end)
static void rand_fill_memory(void *ptr, size_t start, size_t end)
{
Uint8* mem = (Uint8*) ptr;
Uint8 *mem = (Uint8 *)ptr;
size_t i;
if (!s_randfill_allocations)
@@ -295,11 +295,6 @@ void SDLTest_TrackAllocations(void)
SDLTest_Crc32Init(&s_crc32_context);
s_previous_allocations = SDL_GetNumAllocations();
if (s_previous_allocations < 0) {
SDL_Log("SDL was built without allocation count support, disabling free() validation");
} else if (s_previous_allocations != 0) {
SDL_Log("SDLTest_TrackAllocations(): There are %d previous allocations, disabling free() validation", s_previous_allocations);
}
#ifdef SDLTEST_UNWIND_NO_PROC_NAME_BY_IP
do {
/* Don't use SDL_GetHint: SDL_malloc is off limits. */
@@ -346,6 +341,12 @@ dbghelp_failed:
SDLTest_TrackedCalloc,
SDLTest_TrackedRealloc,
SDLTest_TrackedFree);
if (s_previous_allocations < 0) {
SDL_Log("SDL was built without allocation count support, disabling free() validation");
} else if (s_previous_allocations != 0) {
SDL_Log("SDLTest_TrackAllocations(): There are %d previous allocations, disabling free() validation", s_previous_allocations);
}
}
void SDLTest_RandFillAllocations(void)