annotate SDL3/SDL_assert.h @ 1:20d02a178406 default tip

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