diff options
Diffstat (limited to 'src/contrib/SDL-3.2.20/include/SDL3/SDL_assert.h')
-rw-r--r-- | src/contrib/SDL-3.2.20/include/SDL3/SDL_assert.h | 662 |
1 files changed, 662 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/include/SDL3/SDL_assert.h b/src/contrib/SDL-3.2.20/include/SDL3/SDL_assert.h new file mode 100644 index 0000000..053af13 --- /dev/null +++ b/src/contrib/SDL-3.2.20/include/SDL3/SDL_assert.h | |||
@@ -0,0 +1,662 @@ | |||
1 | /* | ||
2 | Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
4 | |||
5 | This software is provided 'as-is', without any express or implied | ||
6 | warranty. In no event will the authors be held liable for any damages | ||
7 | arising from the use of this software. | ||
8 | |||
9 | Permission is granted to anyone to use this software for any purpose, | ||
10 | including commercial applications, and to alter it and redistribute it | ||
11 | freely, subject to the following restrictions: | ||
12 | |||
13 | 1. The origin of this software must not be misrepresented; you must not | ||
14 | claim that you wrote the original software. If you use this software | ||
15 | in a product, an acknowledgment in the product documentation would be | ||
16 | appreciated but is not required. | ||
17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
18 | misrepresented as being the original software. | ||
19 | 3. This notice may not be removed or altered from any source distribution. | ||
20 | */ | ||
21 | |||
22 | /** | ||
23 | * # CategoryAssert | ||
24 | * | ||
25 | * A helpful assertion macro! | ||
26 | * | ||
27 | * SDL assertions operate like your usual `assert` macro, but with some added | ||
28 | * features: | ||
29 | * | ||
30 | * - It uses a trick with the `sizeof` operator, so disabled assertions | ||
31 | * vaporize out of the compiled code, but variables only referenced in the | ||
32 | * assertion won't trigger compiler warnings about being unused. | ||
33 | * - It is safe to use with a dangling-else: `if (x) SDL_assert(y); else | ||
34 | * do_something();` | ||
35 | * - It works the same everywhere, instead of counting on various platforms' | ||
36 | * compiler and C runtime to behave. | ||
37 | * - It provides multiple levels of assertion (SDL_assert, SDL_assert_release, | ||
38 | * SDL_assert_paranoid) instead of a single all-or-nothing option. | ||
39 | * - It offers a variety of responses when an assertion fails (retry, trigger | ||
40 | * the debugger, abort the program, ignore the failure once, ignore it for | ||
41 | * the rest of the program's run). | ||
42 | * - It tries to show the user a dialog by default, if possible, but the app | ||
43 | * can provide a callback to handle assertion failures however they like. | ||
44 | * - It lets failed assertions be retried. Perhaps you had a network failure | ||
45 | * and just want to retry the test after plugging your network cable back | ||
46 | * in? You can. | ||
47 | * - It lets the user ignore an assertion failure, if there's a harmless | ||
48 | * problem that one can continue past. | ||
49 | * - It lets the user mark an assertion as ignored for the rest of the | ||
50 | * program's run; if there's a harmless problem that keeps popping up. | ||
51 | * - It provides statistics and data on all failed assertions to the app. | ||
52 | * - It allows the default assertion handler to be controlled with environment | ||
53 | * variables, in case an automated script needs to control it. | ||
54 | * - It can be used as an aid to Clang's static analysis; it will treat SDL | ||
55 | * assertions as universally true (under the assumption that you are serious | ||
56 | * about the asserted claims and that your debug builds will detect when | ||
57 | * these claims were wrong). This can help the analyzer avoid false | ||
58 | * positives. | ||
59 | * | ||
60 | * To use it: compile a debug build and just sprinkle around tests to check | ||
61 | * your code! | ||
62 | */ | ||
63 | |||
64 | #ifndef SDL_assert_h_ | ||
65 | #define SDL_assert_h_ | ||
66 | |||
67 | #include <SDL3/SDL_stdinc.h> | ||
68 | |||
69 | #include <SDL3/SDL_begin_code.h> | ||
70 | /* Set up for C function definitions, even when using C++ */ | ||
71 | #ifdef __cplusplus | ||
72 | extern "C" { | ||
73 | #endif | ||
74 | |||
75 | #ifdef SDL_WIKI_DOCUMENTATION_SECTION | ||
76 | |||
77 | /** | ||
78 | * The level of assertion aggressiveness. | ||
79 | * | ||
80 | * This value changes depending on compiler options and other preprocessor | ||
81 | * defines. | ||
82 | * | ||
83 | * It is currently one of the following values, but future SDL releases might | ||
84 | * add more: | ||
85 | * | ||
86 | * - 0: All SDL assertion macros are disabled. | ||
87 | * - 1: Release settings: SDL_assert disabled, SDL_assert_release enabled. | ||
88 | * - 2: Debug settings: SDL_assert and SDL_assert_release enabled. | ||
89 | * - 3: Paranoid settings: All SDL assertion macros enabled, including | ||
90 | * SDL_assert_paranoid. | ||
91 | * | ||
92 | * \since This macro is available since SDL 3.2.0. | ||
93 | */ | ||
94 | #define SDL_ASSERT_LEVEL SomeNumberBasedOnVariousFactors | ||
95 | |||
96 | #elif !defined(SDL_ASSERT_LEVEL) | ||
97 | #ifdef SDL_DEFAULT_ASSERT_LEVEL | ||
98 | #define SDL_ASSERT_LEVEL SDL_DEFAULT_ASSERT_LEVEL | ||
99 | #elif defined(_DEBUG) || defined(DEBUG) || \ | ||
100 | (defined(__GNUC__) && !defined(__OPTIMIZE__)) | ||
101 | #define SDL_ASSERT_LEVEL 2 | ||
102 | #else | ||
103 | #define SDL_ASSERT_LEVEL 1 | ||
104 | #endif | ||
105 | #endif | ||
106 | |||
107 | #ifdef SDL_WIKI_DOCUMENTATION_SECTION | ||
108 | |||
109 | /** | ||
110 | * Attempt to tell an attached debugger to pause. | ||
111 | * | ||
112 | * This allows an app to programmatically halt ("break") the debugger as if it | ||
113 | * had hit a breakpoint, allowing the developer to examine program state, etc. | ||
114 | * | ||
115 | * This is a macro--not a function--so that the debugger breaks on the source | ||
116 | * code line that used SDL_TriggerBreakpoint and not in some random guts of | ||
117 | * SDL. SDL_assert uses this macro for the same reason. | ||
118 | * | ||
119 | * If the program is not running under a debugger, SDL_TriggerBreakpoint will | ||
120 | * likely terminate the app, possibly without warning. If the current platform | ||
121 | * isn't supported, this macro is left undefined. | ||
122 | * | ||
123 | * \threadsafety It is safe to call this macro from any thread. | ||
124 | * | ||
125 | * \since This macro is available since SDL 3.2.0. | ||
126 | */ | ||
127 | #define SDL_TriggerBreakpoint() TriggerABreakpointInAPlatformSpecificManner | ||
128 | |||
129 | #elif defined(_MSC_VER) && _MSC_VER >= 1310 | ||
130 | /* Don't include intrin.h here because it contains C++ code */ | ||
131 | extern void __cdecl __debugbreak(void); | ||
132 | #define SDL_TriggerBreakpoint() __debugbreak() | ||
133 | #elif defined(_MSC_VER) && defined(_M_IX86) | ||
134 | #define SDL_TriggerBreakpoint() { _asm { int 0x03 } } | ||
135 | #elif defined(ANDROID) | ||
136 | #include <assert.h> | ||
137 | #define SDL_TriggerBreakpoint() assert(0) | ||
138 | #elif SDL_HAS_BUILTIN(__builtin_debugtrap) | ||
139 | #define SDL_TriggerBreakpoint() __builtin_debugtrap() | ||
140 | #elif SDL_HAS_BUILTIN(__builtin_trap) | ||
141 | #define SDL_TriggerBreakpoint() __builtin_trap() | ||
142 | #elif (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__)) | ||
143 | #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "int $3\n\t" ) | ||
144 | #elif (defined(__GNUC__) || defined(__clang__)) && defined(__riscv) | ||
145 | #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "ebreak\n\t" ) | ||
146 | #elif ( defined(SDL_PLATFORM_APPLE) && (defined(__arm64__) || defined(__aarch64__)) ) /* this might work on other ARM targets, but this is a known quantity... */ | ||
147 | #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #22\n\t" ) | ||
148 | #elif defined(SDL_PLATFORM_APPLE) && defined(__arm__) | ||
149 | #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "bkpt #22\n\t" ) | ||
150 | #elif defined(_WIN32) && ((defined(__GNUC__) || defined(__clang__)) && (defined(__arm64__) || defined(__aarch64__)) ) | ||
151 | #define SDL_TriggerBreakpoint() __asm__ __volatile__ ( "brk #0xF000\n\t" ) | ||
152 | #elif defined(__GNUC__) || defined(__clang__) | ||
153 | #define SDL_TriggerBreakpoint() __builtin_trap() /* older gcc may not support SDL_HAS_BUILTIN(__builtin_trap) above */ | ||
154 | #elif defined(__386__) && defined(__WATCOMC__) | ||
155 | #define SDL_TriggerBreakpoint() { _asm { int 0x03 } } | ||
156 | #elif defined(HAVE_SIGNAL_H) && !defined(__WATCOMC__) | ||
157 | #include <signal.h> | ||
158 | #define SDL_TriggerBreakpoint() raise(SIGTRAP) | ||
159 | #else | ||
160 | /* SDL_TriggerBreakpoint is intentionally left undefined on unknown platforms. */ | ||
161 | #endif | ||
162 | |||
163 | #ifdef SDL_WIKI_DOCUMENTATION_SECTION | ||
164 | |||
165 | /** | ||
166 | * A macro that reports the current function being compiled. | ||
167 | * | ||
168 | * If SDL can't figure how the compiler reports this, it will use "???". | ||
169 | * | ||
170 | * \since This macro is available since SDL 3.2.0. | ||
171 | */ | ||
172 | #define SDL_FUNCTION __FUNCTION__ | ||
173 | |||
174 | #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 supports __func__ as a standard. */ | ||
175 | # define SDL_FUNCTION __func__ | ||
176 | #elif ((defined(__GNUC__) && (__GNUC__ >= 2)) || defined(_MSC_VER) || defined (__WATCOMC__)) | ||
177 | # define SDL_FUNCTION __FUNCTION__ | ||
178 | #else | ||
179 | # define SDL_FUNCTION "???" | ||
180 | #endif | ||
181 | |||
182 | /** | ||
183 | * A macro that reports the current file being compiled. | ||
184 | * | ||
185 | * \since This macro is available since SDL 3.2.0. | ||
186 | */ | ||
187 | #define SDL_FILE __FILE__ | ||
188 | |||
189 | /** | ||
190 | * A macro that reports the current line number of the file being compiled. | ||
191 | * | ||
192 | * \since This macro is available since SDL 3.2.0. | ||
193 | */ | ||
194 | #define SDL_LINE __LINE__ | ||
195 | |||
196 | /* | ||
197 | sizeof (x) makes the compiler still parse the expression even without | ||
198 | assertions enabled, so the code is always checked at compile time, but | ||
199 | doesn't actually generate code for it, so there are no side effects or | ||
200 | expensive checks at run time, just the constant size of what x WOULD be, | ||
201 | which presumably gets optimized out as unused. | ||
202 | This also solves the problem of... | ||
203 | |||
204 | int somevalue = blah(); | ||
205 | SDL_assert(somevalue == 1); | ||
206 | |||
207 | ...which would cause compiles to complain that somevalue is unused if we | ||
208 | disable assertions. | ||
209 | */ | ||
210 | |||
211 | #ifdef SDL_WIKI_DOCUMENTATION_SECTION | ||
212 | |||
213 | /** | ||
214 | * A macro for wrapping code in `do {} while (0);` without compiler warnings. | ||
215 | * | ||
216 | * Visual Studio with really aggressive warnings enabled needs this to avoid | ||
217 | * compiler complaints. | ||
218 | * | ||
219 | * the `do {} while (0);` trick is useful for wrapping code in a macro that | ||
220 | * may or may not be a single statement, to avoid various C language | ||
221 | * accidents. | ||
222 | * | ||
223 | * To use: | ||
224 | * | ||
225 | * ```c | ||
226 | * do { SomethingOnce(); } while (SDL_NULL_WHILE_LOOP_CONDITION (0)); | ||
227 | * ``` | ||
228 | * | ||
229 | * \since This macro is available since SDL 3.2.0. | ||
230 | */ | ||
231 | #define SDL_NULL_WHILE_LOOP_CONDITION (0) | ||
232 | |||
233 | #elif defined(_MSC_VER) /* Avoid /W4 warnings. */ | ||
234 | /* "while (0,0)" fools Microsoft's compiler's /W4 warning level into thinking | ||
235 | this condition isn't constant. And looks like an owl's face! */ | ||
236 | #define SDL_NULL_WHILE_LOOP_CONDITION (0,0) | ||
237 | #else | ||
238 | #define SDL_NULL_WHILE_LOOP_CONDITION (0) | ||
239 | #endif | ||
240 | |||
241 | /** | ||
242 | * The macro used when an assertion is disabled. | ||
243 | * | ||
244 | * This isn't for direct use by apps, but this is the code that is inserted | ||
245 | * when an SDL_assert is disabled (perhaps in a release build). | ||
246 | * | ||
247 | * The code does nothing, but wraps `condition` in a sizeof operator, which | ||
248 | * generates no code and has no side effects, but avoid compiler warnings | ||
249 | * about unused variables. | ||
250 | * | ||
251 | * \param condition the condition to assert (but not actually run here). | ||
252 | * | ||
253 | * \since This macro is available since SDL 3.2.0. | ||
254 | */ | ||
255 | #define SDL_disabled_assert(condition) \ | ||
256 | do { (void) sizeof ((condition)); } while (SDL_NULL_WHILE_LOOP_CONDITION) | ||
257 | |||
258 | /** | ||
259 | * Possible outcomes from a triggered assertion. | ||
260 | * | ||
261 | * When an enabled assertion triggers, it may call the assertion handler | ||
262 | * (possibly one provided by the app via SDL_SetAssertionHandler), which will | ||
263 | * return one of these values, possibly after asking the user. | ||
264 | * | ||
265 | * Then SDL will respond based on this outcome (loop around to retry the | ||
266 | * condition, try to break in a debugger, kill the program, or ignore the | ||
267 | * problem). | ||
268 | * | ||
269 | * \since This enum is available since SDL 3.2.0. | ||
270 | */ | ||
271 | typedef enum SDL_AssertState | ||
272 | { | ||
273 | SDL_ASSERTION_RETRY, /**< Retry the assert immediately. */ | ||
274 | SDL_ASSERTION_BREAK, /**< Make the debugger trigger a breakpoint. */ | ||
275 | SDL_ASSERTION_ABORT, /**< Terminate the program. */ | ||
276 | SDL_ASSERTION_IGNORE, /**< Ignore the assert. */ | ||
277 | SDL_ASSERTION_ALWAYS_IGNORE /**< Ignore the assert from now on. */ | ||
278 | } SDL_AssertState; | ||
279 | |||
280 | /** | ||
281 | * Information about an assertion failure. | ||
282 | * | ||
283 | * This structure is filled in with information about a triggered assertion, | ||
284 | * used by the assertion handler, then added to the assertion report. This is | ||
285 | * returned as a linked list from SDL_GetAssertionReport(). | ||
286 | * | ||
287 | * \since This struct is available since SDL 3.2.0. | ||
288 | */ | ||
289 | typedef struct SDL_AssertData | ||
290 | { | ||
291 | bool always_ignore; /**< true if app should always continue when assertion is triggered. */ | ||
292 | unsigned int trigger_count; /**< Number of times this assertion has been triggered. */ | ||
293 | const char *condition; /**< A string of this assert's test code. */ | ||
294 | const char *filename; /**< The source file where this assert lives. */ | ||
295 | int linenum; /**< The line in `filename` where this assert lives. */ | ||
296 | const char *function; /**< The name of the function where this assert lives. */ | ||
297 | const struct SDL_AssertData *next; /**< next item in the linked list. */ | ||
298 | } SDL_AssertData; | ||
299 | |||
300 | /** | ||
301 | * Never call this directly. | ||
302 | * | ||
303 | * Use the SDL_assert macros instead. | ||
304 | * | ||
305 | * \param data assert data structure. | ||
306 | * \param func function name. | ||
307 | * \param file file name. | ||
308 | * \param line line number. | ||
309 | * \returns assert state. | ||
310 | * | ||
311 | * \threadsafety It is safe to call this function from any thread. | ||
312 | * | ||
313 | * \since This function is available since SDL 3.2.0. | ||
314 | */ | ||
315 | extern SDL_DECLSPEC SDL_AssertState SDLCALL SDL_ReportAssertion(SDL_AssertData *data, | ||
316 | const char *func, | ||
317 | const char *file, int line) SDL_ANALYZER_NORETURN; | ||
318 | |||
319 | |||
320 | #ifdef SDL_WIKI_DOCUMENTATION_SECTION | ||
321 | |||
322 | /** | ||
323 | * The macro used when an assertion triggers a breakpoint. | ||
324 | * | ||
325 | * This isn't for direct use by apps; use SDL_assert or SDL_TriggerBreakpoint | ||
326 | * instead. | ||
327 | * | ||
328 | * \since This macro is available since SDL 3.2.0. | ||
329 | */ | ||
330 | #define SDL_AssertBreakpoint() SDL_TriggerBreakpoint() | ||
331 | |||
332 | #elif !defined(SDL_AssertBreakpoint) | ||
333 | # if defined(ANDROID) && defined(assert) | ||
334 | /* Define this as empty in case assert() is defined as SDL_assert */ | ||
335 | # define SDL_AssertBreakpoint() | ||
336 | # else | ||
337 | # define SDL_AssertBreakpoint() SDL_TriggerBreakpoint() | ||
338 | # endif | ||
339 | #endif /* !SDL_AssertBreakpoint */ | ||
340 | |||
341 | /** | ||
342 | * The macro used when an assertion is enabled. | ||
343 | * | ||
344 | * This isn't for direct use by apps, but this is the code that is inserted | ||
345 | * when an SDL_assert is enabled. | ||
346 | * | ||
347 | * The `do {} while(0)` avoids dangling else problems: | ||
348 | * | ||
349 | * ```c | ||
350 | * if (x) SDL_assert(y); else blah(); | ||
351 | * ``` | ||
352 | * | ||
353 | * ... without the do/while, the "else" could attach to this macro's "if". We | ||
354 | * try to handle just the minimum we need here in a macro...the loop, the | ||
355 | * static vars, and break points. The heavy lifting is handled in | ||
356 | * SDL_ReportAssertion(). | ||
357 | * | ||
358 | * \param condition the condition to assert. | ||
359 | * | ||
360 | * \since This macro is available since SDL 3.2.0. | ||
361 | */ | ||
362 | #define SDL_enabled_assert(condition) \ | ||
363 | do { \ | ||
364 | while ( !(condition) ) { \ | ||
365 | static struct SDL_AssertData sdl_assert_data = { false, 0, #condition, NULL, 0, NULL, NULL }; \ | ||
366 | const SDL_AssertState sdl_assert_state = SDL_ReportAssertion(&sdl_assert_data, SDL_FUNCTION, SDL_FILE, SDL_LINE); \ | ||
367 | if (sdl_assert_state == SDL_ASSERTION_RETRY) { \ | ||
368 | continue; /* go again. */ \ | ||
369 | } else if (sdl_assert_state == SDL_ASSERTION_BREAK) { \ | ||
370 | SDL_AssertBreakpoint(); \ | ||
371 | } \ | ||
372 | break; /* not retrying. */ \ | ||
373 | } \ | ||
374 | } while (SDL_NULL_WHILE_LOOP_CONDITION) | ||
375 | |||
376 | #ifdef SDL_WIKI_DOCUMENTATION_SECTION | ||
377 | |||
378 | /** | ||
379 | * An assertion test that is normally performed only in debug builds. | ||
380 | * | ||
381 | * This macro is enabled when the SDL_ASSERT_LEVEL is >= 2, otherwise it is | ||
382 | * disabled. This is meant to only do these tests in debug builds, so they can | ||
383 | * tend to be more expensive, and they are meant to bring everything to a halt | ||
384 | * when they fail, with the programmer there to assess the problem. | ||
385 | * | ||
386 | * In short: you can sprinkle these around liberally and assume they will | ||
387 | * evaporate out of the build when building for end-users. | ||
388 | * | ||
389 | * When assertions are disabled, this wraps `condition` in a `sizeof` | ||
390 | * operator, which means any function calls and side effects will not run, but | ||
391 | * the compiler will not complain about any otherwise-unused variables that | ||
392 | * are only referenced in the assertion. | ||
393 | * | ||
394 | * One can set the environment variable "SDL_ASSERT" to one of several strings | ||
395 | * ("abort", "break", "retry", "ignore", "always_ignore") to force a default | ||
396 | * behavior, which may be desirable for automation purposes. If your platform | ||
397 | * requires GUI interfaces to happen on the main thread but you're debugging | ||
398 | * an assertion in a background thread, it might be desirable to set this to | ||
399 | * "break" so that your debugger takes control as soon as assert is triggered, | ||
400 | * instead of risking a bad UI interaction (deadlock, etc) in the application. | ||
401 | * | ||
402 | * \param condition boolean value to test. | ||
403 | * | ||
404 | * \threadsafety It is safe to call this macro from any thread. | ||
405 | * | ||
406 | * \since This macro is available since SDL 3.2.0. | ||
407 | */ | ||
408 | #define SDL_assert(condition) if (assertion_enabled && (condition)) { trigger_assertion; } | ||
409 | |||
410 | /** | ||
411 | * An assertion test that is performed even in release builds. | ||
412 | * | ||
413 | * This macro is enabled when the SDL_ASSERT_LEVEL is >= 1, otherwise it is | ||
414 | * disabled. This is meant to be for tests that are cheap to make and | ||
415 | * extremely unlikely to fail; generally it is frowned upon to have an | ||
416 | * assertion failure in a release build, so these assertions generally need to | ||
417 | * be of more than life-and-death importance if there's a chance they might | ||
418 | * trigger. You should almost always consider handling these cases more | ||
419 | * gracefully than an assert allows. | ||
420 | * | ||
421 | * When assertions are disabled, this wraps `condition` in a `sizeof` | ||
422 | * operator, which means any function calls and side effects will not run, but | ||
423 | * the compiler will not complain about any otherwise-unused variables that | ||
424 | * are only referenced in the assertion. | ||
425 | * | ||
426 | * One can set the environment variable "SDL_ASSERT" to one of several strings | ||
427 | * ("abort", "break", "retry", "ignore", "always_ignore") to force a default | ||
428 | * behavior, which may be desirable for automation purposes. If your platform | ||
429 | * requires GUI interfaces to happen on the main thread but you're debugging | ||
430 | * an assertion in a background thread, it might be desirable to set this to | ||
431 | * "break" so that your debugger takes control as soon as assert is triggered, | ||
432 | * instead of risking a bad UI interaction (deadlock, etc) in the application. | ||
433 | * * | ||
434 | * | ||
435 | * \param condition boolean value to test. | ||
436 | * | ||
437 | * \threadsafety It is safe to call this macro from any thread. | ||
438 | * | ||
439 | * \since This macro is available since SDL 3.2.0. | ||
440 | */ | ||
441 | #define SDL_assert_release(condition) SDL_disabled_assert(condition) | ||
442 | |||
443 | /** | ||
444 | * An assertion test that is performed only when built with paranoid settings. | ||
445 | * | ||
446 | * This macro is enabled when the SDL_ASSERT_LEVEL is >= 3, otherwise it is | ||
447 | * disabled. This is a higher level than both release and debug, so these | ||
448 | * tests are meant to be expensive and only run when specifically looking for | ||
449 | * extremely unexpected failure cases in a special build. | ||
450 | * | ||
451 | * When assertions are disabled, this wraps `condition` in a `sizeof` | ||
452 | * operator, which means any function calls and side effects will not run, but | ||
453 | * the compiler will not complain about any otherwise-unused variables that | ||
454 | * are only referenced in the assertion. | ||
455 | * | ||
456 | * One can set the environment variable "SDL_ASSERT" to one of several strings | ||
457 | * ("abort", "break", "retry", "ignore", "always_ignore") to force a default | ||
458 | * behavior, which may be desirable for automation purposes. If your platform | ||
459 | * requires GUI interfaces to happen on the main thread but you're debugging | ||
460 | * an assertion in a background thread, it might be desirable to set this to | ||
461 | * "break" so that your debugger takes control as soon as assert is triggered, | ||
462 | * instead of risking a bad UI interaction (deadlock, etc) in the application. | ||
463 | * | ||
464 | * \param condition boolean value to test. | ||
465 | * | ||
466 | * \threadsafety It is safe to call this macro from any thread. | ||
467 | * | ||
468 | * \since This macro is available since SDL 3.2.0. | ||
469 | */ | ||
470 | #define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) | ||
471 | |||
472 | /* Enable various levels of assertions. */ | ||
473 | #elif SDL_ASSERT_LEVEL == 0 /* assertions disabled */ | ||
474 | # define SDL_assert(condition) SDL_disabled_assert(condition) | ||
475 | # define SDL_assert_release(condition) SDL_disabled_assert(condition) | ||
476 | # define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) | ||
477 | #elif SDL_ASSERT_LEVEL == 1 /* release settings. */ | ||
478 | # define SDL_assert(condition) SDL_disabled_assert(condition) | ||
479 | # define SDL_assert_release(condition) SDL_enabled_assert(condition) | ||
480 | # define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) | ||
481 | #elif SDL_ASSERT_LEVEL == 2 /* debug settings. */ | ||
482 | # define SDL_assert(condition) SDL_enabled_assert(condition) | ||
483 | # define SDL_assert_release(condition) SDL_enabled_assert(condition) | ||
484 | # define SDL_assert_paranoid(condition) SDL_disabled_assert(condition) | ||
485 | #elif SDL_ASSERT_LEVEL == 3 /* paranoid settings. */ | ||
486 | # define SDL_assert(condition) SDL_enabled_assert(condition) | ||
487 | # define SDL_assert_release(condition) SDL_enabled_assert(condition) | ||
488 | # define SDL_assert_paranoid(condition) SDL_enabled_assert(condition) | ||
489 | #else | ||
490 | # error Unknown assertion level. | ||
491 | #endif | ||
492 | |||
493 | /** | ||
494 | * An assertion test that is always performed. | ||
495 | * | ||
496 | * This macro is always enabled no matter what SDL_ASSERT_LEVEL is set to. You | ||
497 | * almost never want to use this, as it could trigger on an end-user's system, | ||
498 | * crashing your program. | ||
499 | * | ||
500 | * One can set the environment variable "SDL_ASSERT" to one of several strings | ||
501 | * ("abort", "break", "retry", "ignore", "always_ignore") to force a default | ||
502 | * behavior, which may be desirable for automation purposes. If your platform | ||
503 | * requires GUI interfaces to happen on the main thread but you're debugging | ||
504 | * an assertion in a background thread, it might be desirable to set this to | ||
505 | * "break" so that your debugger takes control as soon as assert is triggered, | ||
506 | * instead of risking a bad UI interaction (deadlock, etc) in the application. | ||
507 | * | ||
508 | * \param condition boolean value to test. | ||
509 | * | ||
510 | * \threadsafety It is safe to call this macro from any thread. | ||
511 | * | ||
512 | * \since This macro is available since SDL 3.2.0. | ||
513 | */ | ||
514 | #define SDL_assert_always(condition) SDL_enabled_assert(condition) | ||
515 | |||
516 | |||
517 | /** | ||
518 | * A callback that fires when an SDL assertion fails. | ||
519 | * | ||
520 | * \param data a pointer to the SDL_AssertData structure corresponding to the | ||
521 | * current assertion. | ||
522 | * \param userdata what was passed as `userdata` to SDL_SetAssertionHandler(). | ||
523 | * \returns an SDL_AssertState value indicating how to handle the failure. | ||
524 | * | ||
525 | * \threadsafety This callback may be called from any thread that triggers an | ||
526 | * assert at any time. | ||
527 | * | ||
528 | * \since This datatype is available since SDL 3.2.0. | ||
529 | */ | ||
530 | typedef SDL_AssertState (SDLCALL *SDL_AssertionHandler)( | ||
531 | const SDL_AssertData *data, void *userdata); | ||
532 | |||
533 | /** | ||
534 | * Set an application-defined assertion handler. | ||
535 | * | ||
536 | * This function allows an application to show its own assertion UI and/or | ||
537 | * force the response to an assertion failure. If the application doesn't | ||
538 | * provide this, SDL will try to do the right thing, popping up a | ||
539 | * system-specific GUI dialog, and probably minimizing any fullscreen windows. | ||
540 | * | ||
541 | * This callback may fire from any thread, but it runs wrapped in a mutex, so | ||
542 | * it will only fire from one thread at a time. | ||
543 | * | ||
544 | * This callback is NOT reset to SDL's internal handler upon SDL_Quit()! | ||
545 | * | ||
546 | * \param handler the SDL_AssertionHandler function to call when an assertion | ||
547 | * fails or NULL for the default handler. | ||
548 | * \param userdata a pointer that is passed to `handler`. | ||
549 | * | ||
550 | * \threadsafety It is safe to call this function from any thread. | ||
551 | * | ||
552 | * \since This function is available since SDL 3.2.0. | ||
553 | * | ||
554 | * \sa SDL_GetAssertionHandler | ||
555 | */ | ||
556 | extern SDL_DECLSPEC void SDLCALL SDL_SetAssertionHandler( | ||
557 | SDL_AssertionHandler handler, | ||
558 | void *userdata); | ||
559 | |||
560 | /** | ||
561 | * Get the default assertion handler. | ||
562 | * | ||
563 | * This returns the function pointer that is called by default when an | ||
564 | * assertion is triggered. This is an internal function provided by SDL, that | ||
565 | * is used for assertions when SDL_SetAssertionHandler() hasn't been used to | ||
566 | * provide a different function. | ||
567 | * | ||
568 | * \returns the default SDL_AssertionHandler that is called when an assert | ||
569 | * triggers. | ||
570 | * | ||
571 | * \threadsafety It is safe to call this function from any thread. | ||
572 | * | ||
573 | * \since This function is available since SDL 3.2.0. | ||
574 | * | ||
575 | * \sa SDL_GetAssertionHandler | ||
576 | */ | ||
577 | extern SDL_DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetDefaultAssertionHandler(void); | ||
578 | |||
579 | /** | ||
580 | * Get the current assertion handler. | ||
581 | * | ||
582 | * This returns the function pointer that is called when an assertion is | ||
583 | * triggered. This is either the value last passed to | ||
584 | * SDL_SetAssertionHandler(), or if no application-specified function is set, | ||
585 | * is equivalent to calling SDL_GetDefaultAssertionHandler(). | ||
586 | * | ||
587 | * The parameter `puserdata` is a pointer to a void*, which will store the | ||
588 | * "userdata" pointer that was passed to SDL_SetAssertionHandler(). This value | ||
589 | * will always be NULL for the default handler. If you don't care about this | ||
590 | * data, it is safe to pass a NULL pointer to this function to ignore it. | ||
591 | * | ||
592 | * \param puserdata pointer which is filled with the "userdata" pointer that | ||
593 | * was passed to SDL_SetAssertionHandler(). | ||
594 | * \returns the SDL_AssertionHandler that is called when an assert triggers. | ||
595 | * | ||
596 | * \threadsafety It is safe to call this function from any thread. | ||
597 | * | ||
598 | * \since This function is available since SDL 3.2.0. | ||
599 | * | ||
600 | * \sa SDL_SetAssertionHandler | ||
601 | */ | ||
602 | extern SDL_DECLSPEC SDL_AssertionHandler SDLCALL SDL_GetAssertionHandler(void **puserdata); | ||
603 | |||
604 | /** | ||
605 | * Get a list of all assertion failures. | ||
606 | * | ||
607 | * This function gets all assertions triggered since the last call to | ||
608 | * SDL_ResetAssertionReport(), or the start of the program. | ||
609 | * | ||
610 | * The proper way to examine this data looks something like this: | ||
611 | * | ||
612 | * ```c | ||
613 | * const SDL_AssertData *item = SDL_GetAssertionReport(); | ||
614 | * while (item) { | ||
615 | * printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n", | ||
616 | * item->condition, item->function, item->filename, | ||
617 | * item->linenum, item->trigger_count, | ||
618 | * item->always_ignore ? "yes" : "no"); | ||
619 | * item = item->next; | ||
620 | * } | ||
621 | * ``` | ||
622 | * | ||
623 | * \returns a list of all failed assertions or NULL if the list is empty. This | ||
624 | * memory should not be modified or freed by the application. This | ||
625 | * pointer remains valid until the next call to SDL_Quit() or | ||
626 | * SDL_ResetAssertionReport(). | ||
627 | * | ||
628 | * \threadsafety This function is not thread safe. Other threads calling | ||
629 | * SDL_ResetAssertionReport() simultaneously, may render the | ||
630 | * returned pointer invalid. | ||
631 | * | ||
632 | * \since This function is available since SDL 3.2.0. | ||
633 | * | ||
634 | * \sa SDL_ResetAssertionReport | ||
635 | */ | ||
636 | extern SDL_DECLSPEC const SDL_AssertData * SDLCALL SDL_GetAssertionReport(void); | ||
637 | |||
638 | /** | ||
639 | * Clear the list of all assertion failures. | ||
640 | * | ||
641 | * This function will clear the list of all assertions triggered up to that | ||
642 | * point. Immediately following this call, SDL_GetAssertionReport will return | ||
643 | * no items. In addition, any previously-triggered assertions will be reset to | ||
644 | * a trigger_count of zero, and their always_ignore state will be false. | ||
645 | * | ||
646 | * \threadsafety This function is not thread safe. Other threads triggering an | ||
647 | * assertion, or simultaneously calling this function may cause | ||
648 | * memory leaks or crashes. | ||
649 | * | ||
650 | * \since This function is available since SDL 3.2.0. | ||
651 | * | ||
652 | * \sa SDL_GetAssertionReport | ||
653 | */ | ||
654 | extern SDL_DECLSPEC void SDLCALL SDL_ResetAssertionReport(void); | ||
655 | |||
656 | /* Ends C function definitions when using C++ */ | ||
657 | #ifdef __cplusplus | ||
658 | } | ||
659 | #endif | ||
660 | #include <SDL3/SDL_close_code.h> | ||
661 | |||
662 | #endif /* SDL_assert_h_ */ | ||