Skip to main content

sdl3_sys/generated/
assert.rs

1//! A helpful assertion macro!
2//!
3//! SDL assertions operate like your usual `assert` macro, but with some added
4//! features:
5//!
6//! - It uses a trick with the `sizeof` operator, so disabled assertions
7//!   vaporize out of the compiled code, but variables only referenced in the
8//!   assertion won't trigger compiler warnings about being unused.
9//! - It is safe to use with a dangling-else: `if (x) SDL_assert(y); else
10//!   do_something();`
11//! - It works the same everywhere, instead of counting on various platforms'
12//!   compiler and C runtime to behave.
13//! - It provides multiple levels of assertion ([`SDL_assert`], [`SDL_assert_release`],
14//!   [`SDL_assert_paranoid`]) instead of a single all-or-nothing option.
15//! - It offers a variety of responses when an assertion fails (retry, trigger
16//!   the debugger, abort the program, ignore the failure once, ignore it for
17//!   the rest of the program's run).
18//! - It tries to show the user a dialog by default, if possible, but the app
19//!   can provide a callback to handle assertion failures however they like.
20//! - It lets failed assertions be retried. Perhaps you had a network failure
21//!   and just want to retry the test after plugging your network cable back
22//!   in? You can.
23//! - It lets the user ignore an assertion failure, if there's a harmless
24//!   problem that one can continue past.
25//! - It lets the user mark an assertion as ignored for the rest of the
26//!   program's run; if there's a harmless problem that keeps popping up.
27//! - It provides statistics and data on all failed assertions to the app.
28//! - It allows the default assertion handler to be controlled with environment
29//!   variables, in case an automated script needs to control it.
30//! - It can be used as an aid to Clang's static analysis; it will treat SDL
31//!   assertions as universally true (under the assumption that you are serious
32//!   about the asserted claims and that your debug builds will detect when
33//!   these claims were wrong). This can help the analyzer avoid false
34//!   positives.
35//!
36//! To use it: compile a debug build and just sprinkle around tests to check
37//! your code!
38
39use super::stdinc::*;
40
41apply_cfg!(#[cfg(doc)] => {
42    /// The level of assertion aggressiveness.
43    ///
44    /// This value changes depending on compiler options and other preprocessor
45    /// defines.
46    ///
47    /// It is currently one of the following values, but future SDL releases might
48    /// add more:
49    ///
50    /// - 0: All SDL assertion macros are disabled.
51    /// - 1: Release settings: [`SDL_assert`] disabled, [`SDL_assert_release`] enabled.
52    /// - 2: Debug settings: [`SDL_assert`] and [`SDL_assert_release`] enabled.
53    /// - 3: Paranoid settings: All SDL assertion macros enabled, including
54    ///   [`SDL_assert_paranoid`].
55    ///
56    /// ## Availability
57    /// This macro is available since SDL 3.2.0.
58    pub const SDL_ASSERT_LEVEL: ::core::primitive::i32 = 1;
59
60});
61
62apply_cfg!(#[cfg(not(doc))] => {
63    apply_cfg!(#[cfg(any(all(not(not(debug_assertions)), any(/* always disabled: __GNUC__ */)), debug_assertions, debug_assertions))] => {
64    });
65
66    apply_cfg!(#[cfg(not(any(all(not(not(debug_assertions)), any(/* always disabled: __GNUC__ */)), debug_assertions, debug_assertions)))] => {
67    });
68
69});
70
71apply_cfg!(#[cfg(doc)] => {
72    /// Attempt to tell an attached debugger to pause.
73    ///
74    /// This allows an app to programmatically halt ("break") the debugger as if it
75    /// had hit a breakpoint, allowing the developer to examine program state, etc.
76    ///
77    /// This is a macro--not a function--so that the debugger breaks on the source
78    /// code line that used [`SDL_TriggerBreakpoint`] and not in some random guts of
79    /// SDL. [`SDL_assert`] uses this macro for the same reason.
80    ///
81    /// If the program is not running under a debugger, [`SDL_TriggerBreakpoint`] will
82    /// likely terminate the app, possibly without warning. If the current platform
83    /// isn't supported, this macro is left undefined.
84    ///
85    /// ## Thread safety
86    /// It is safe to call this macro from any thread.
87    ///
88    /// ## Availability
89    /// This macro is available since SDL 3.2.0.
90    #[inline(always)]
91    pub unsafe fn SDL_TriggerBreakpoint() {
92        crate::breakpoint()
93    }
94});
95
96apply_cfg!(#[cfg(not(doc))] => {
97    apply_cfg!(#[cfg(any(all(windows, target_env = "msvc"), all(windows, target_env = "gnu")))] => {
98        #[inline(always)]
99        pub unsafe fn SDL_TriggerBreakpoint() {
100            crate::breakpoint()
101        }
102    });
103
104    apply_cfg!(#[cfg(not(any(all(windows, target_env = "msvc"), all(windows, target_env = "gnu"))))] => {
105        #[inline(always)]
106        pub unsafe fn SDL_TriggerBreakpoint() {
107            crate::breakpoint()
108        }
109    });
110
111});
112
113apply_cfg!(#[cfg(doc)] => {
114});
115
116apply_cfg!(#[cfg(not(doc))] => {
117});
118
119apply_cfg!(#[cfg(doc)] => {
120});
121
122apply_cfg!(#[cfg(not(doc))] => {
123});
124
125apply_cfg!(#[cfg(doc)] => {
126    // [sdl3-sys-gen] skipped constant value define `SDL_ASSERT_FILE`
127
128});
129
130apply_cfg!(#[cfg(not(doc))] => {
131    // [sdl3-sys-gen] skipped constant value define `SDL_ASSERT_FILE`
132
133});
134
135apply_cfg!(#[cfg(doc)] => {
136});
137
138apply_cfg!(#[cfg(not(doc))] => {
139    apply_cfg!(#[cfg(all(windows, target_env = "msvc"))] => {
140    });
141
142    apply_cfg!(#[cfg(not(all(windows, target_env = "msvc")))] => {
143    });
144
145});
146
147#[cfg(all(not(doc), feature = "assert-level-disabled"))]
148pub const SDL_ASSERT_LEVEL: ::core::primitive::i32 = 0;
149#[cfg(all(
150    not(any(doc, feature = "assert-level-disabled")),
151    feature = "assert-level-release"
152))]
153pub const SDL_ASSERT_LEVEL: ::core::primitive::i32 = 1;
154#[cfg(all(
155    not(any(
156        doc,
157        feature = "assert-level-disabled",
158        feature = "assert-level-release"
159    )),
160    feature = "assert-level-debug"
161))]
162pub const SDL_ASSERT_LEVEL: ::core::primitive::i32 = 2;
163#[cfg(all(
164    not(any(
165        doc,
166        feature = "assert-level-disabled",
167        feature = "assert-level-release",
168        feature = "assert-level-debug"
169    )),
170    feature = "assert-level-paranoid"
171))]
172pub const SDL_ASSERT_LEVEL: ::core::primitive::i32 = 3;
173
174/// The macro used when an assertion is disabled.
175///
176/// This isn't for direct use by apps, but this is the code that is inserted
177/// when an [`SDL_assert`] is disabled (perhaps in a release build).
178///
179/// The code does nothing, but wraps `condition` in a sizeof operator, which
180/// generates no code and has no side effects, but avoid compiler warnings
181/// about unused variables.
182///
183/// ## Parameters
184/// - `condition`: the condition to assert (but not actually run here).
185///
186/// ## Availability
187/// This macro is available since SDL 3.2.0.
188#[doc(hidden)]
189#[macro_export]
190macro_rules! SDL_disabled_assert {
191    ($condition:expr) => {{
192        if false {
193            let _ = $condition;
194        }
195    }};
196}
197#[doc(inline)]
198pub use SDL_disabled_assert;
199
200/// Possible outcomes from a triggered assertion.
201///
202/// When an enabled assertion triggers, it may call the assertion handler
203/// (possibly one provided by the app via [`SDL_SetAssertionHandler`]), which will
204/// return one of these values, possibly after asking the user.
205///
206/// Then SDL will respond based on this outcome (loop around to retry the
207/// condition, try to break in a debugger, kill the program, or ignore the
208/// problem).
209///
210/// ## Availability
211/// This enum is available since SDL 3.2.0.
212///
213/// ## Known values (`sdl3-sys`)
214/// | Associated constant | Global constant | Description |
215/// | ------------------- | --------------- | ----------- |
216/// | [`RETRY`](SDL_AssertState::RETRY) | [`SDL_ASSERTION_RETRY`] | Retry the assert immediately. |
217/// | [`BREAK`](SDL_AssertState::BREAK) | [`SDL_ASSERTION_BREAK`] | Make the debugger trigger a breakpoint. |
218/// | [`ABORT`](SDL_AssertState::ABORT) | [`SDL_ASSERTION_ABORT`] | Terminate the program. |
219/// | [`IGNORE`](SDL_AssertState::IGNORE) | [`SDL_ASSERTION_IGNORE`] | Ignore the assert. |
220/// | [`ALWAYS_IGNORE`](SDL_AssertState::ALWAYS_IGNORE) | [`SDL_ASSERTION_ALWAYS_IGNORE`] | Ignore the assert from now on. |
221#[repr(transparent)]
222#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
223pub struct SDL_AssertState(pub ::core::ffi::c_int);
224
225impl ::core::cmp::PartialEq<::core::ffi::c_int> for SDL_AssertState {
226    #[inline(always)]
227    fn eq(&self, other: &::core::ffi::c_int) -> bool {
228        &self.0 == other
229    }
230}
231
232impl ::core::cmp::PartialEq<SDL_AssertState> for ::core::ffi::c_int {
233    #[inline(always)]
234    fn eq(&self, other: &SDL_AssertState) -> bool {
235        self == &other.0
236    }
237}
238
239impl From<SDL_AssertState> for ::core::ffi::c_int {
240    #[inline(always)]
241    fn from(value: SDL_AssertState) -> Self {
242        value.0
243    }
244}
245
246#[cfg(feature = "debug-impls")]
247impl ::core::fmt::Debug for SDL_AssertState {
248    fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
249        #[allow(unreachable_patterns)]
250        f.write_str(match *self {
251            Self::RETRY => "SDL_ASSERTION_RETRY",
252            Self::BREAK => "SDL_ASSERTION_BREAK",
253            Self::ABORT => "SDL_ASSERTION_ABORT",
254            Self::IGNORE => "SDL_ASSERTION_IGNORE",
255            Self::ALWAYS_IGNORE => "SDL_ASSERTION_ALWAYS_IGNORE",
256
257            _ => return write!(f, "SDL_AssertState({})", self.0),
258        })
259    }
260}
261
262impl SDL_AssertState {
263    /// Retry the assert immediately.
264    pub const RETRY: Self = Self((0 as ::core::ffi::c_int));
265    /// Make the debugger trigger a breakpoint.
266    pub const BREAK: Self = Self((1 as ::core::ffi::c_int));
267    /// Terminate the program.
268    pub const ABORT: Self = Self((2 as ::core::ffi::c_int));
269    /// Ignore the assert.
270    pub const IGNORE: Self = Self((3 as ::core::ffi::c_int));
271    /// Ignore the assert from now on.
272    pub const ALWAYS_IGNORE: Self = Self((4 as ::core::ffi::c_int));
273}
274
275/// Retry the assert immediately.
276pub const SDL_ASSERTION_RETRY: SDL_AssertState = SDL_AssertState::RETRY;
277/// Make the debugger trigger a breakpoint.
278pub const SDL_ASSERTION_BREAK: SDL_AssertState = SDL_AssertState::BREAK;
279/// Terminate the program.
280pub const SDL_ASSERTION_ABORT: SDL_AssertState = SDL_AssertState::ABORT;
281/// Ignore the assert.
282pub const SDL_ASSERTION_IGNORE: SDL_AssertState = SDL_AssertState::IGNORE;
283/// Ignore the assert from now on.
284pub const SDL_ASSERTION_ALWAYS_IGNORE: SDL_AssertState = SDL_AssertState::ALWAYS_IGNORE;
285
286impl SDL_AssertState {
287    /// Initialize a `SDL_AssertState` from a raw value.
288    #[inline(always)]
289    pub const fn new(value: ::core::ffi::c_int) -> Self {
290        Self(value)
291    }
292}
293
294impl SDL_AssertState {
295    /// Get a copy of the inner raw value.
296    #[inline(always)]
297    pub const fn value(&self) -> ::core::ffi::c_int {
298        self.0
299    }
300}
301
302#[cfg(feature = "metadata")]
303impl sdl3_sys::metadata::GroupMetadata for SDL_AssertState {
304    const GROUP_METADATA: &'static sdl3_sys::metadata::Group =
305        &crate::metadata::assert::METADATA_SDL_AssertState;
306}
307
308/// Information about an assertion failure.
309///
310/// This structure is filled in with information about a triggered assertion,
311/// used by the assertion handler, then added to the assertion report. This is
312/// returned as a linked list from [`SDL_GetAssertionReport()`].
313///
314/// ## Availability
315/// This struct is available since SDL 3.2.0.
316#[repr(C)]
317#[derive(Clone, Copy)]
318#[cfg_attr(feature = "debug-impls", derive(Debug))]
319pub struct SDL_AssertData {
320    /// true if app should always continue when assertion is triggered.
321    pub always_ignore: ::core::primitive::bool,
322    /// Number of times this assertion has been triggered.
323    pub trigger_count: ::core::ffi::c_uint,
324    /// A string of this assert's test code.
325    pub condition: *const ::core::ffi::c_char,
326    /// The source file where this assert lives.
327    pub filename: *const ::core::ffi::c_char,
328    /// The line in `filename` where this assert lives.
329    pub linenum: ::core::ffi::c_int,
330    /// The name of the function where this assert lives.
331    pub function: *const ::core::ffi::c_char,
332    /// next item in the linked list.
333    pub next: *const SDL_AssertData,
334}
335
336impl ::core::default::Default for SDL_AssertData {
337    /// Initialize all fields to zero
338    #[inline(always)]
339    fn default() -> Self {
340        unsafe { ::core::mem::MaybeUninit::<Self>::zeroed().assume_init() }
341    }
342}
343
344unsafe extern "C" {
345    /// Never call this directly.
346    ///
347    /// Use the [`SDL_assert`] macros instead.
348    ///
349    /// ## Parameters
350    /// - `data`: assert data structure.
351    /// - `func`: function name.
352    /// - `file`: file name.
353    /// - `line`: line number.
354    ///
355    /// ## Return value
356    /// Returns assert state.
357    ///
358    /// ## Thread safety
359    /// It is safe to call this function from any thread.
360    ///
361    /// ## Availability
362    /// This function is available since SDL 3.2.0.
363    pub fn SDL_ReportAssertion(
364        data: *mut SDL_AssertData,
365        func: *const ::core::ffi::c_char,
366        file: *const ::core::ffi::c_char,
367        line: ::core::ffi::c_int,
368    ) -> SDL_AssertState;
369}
370
371apply_cfg!(#[cfg(doc)] => {
372    /// The macro used when an assertion triggers a breakpoint.
373    ///
374    /// This isn't for direct use by apps; use [`SDL_assert`] or [`SDL_TriggerBreakpoint`]
375    /// instead.
376    ///
377    /// ## Availability
378    /// This macro is available since SDL 3.2.0.
379    #[inline(always)]
380    pub unsafe fn SDL_AssertBreakpoint() {
381        unsafe { SDL_TriggerBreakpoint() }
382    }
383});
384
385apply_cfg!(#[cfg(not(doc))] => {
386    #[inline(always)]
387    pub unsafe fn SDL_AssertBreakpoint() {
388        unsafe { SDL_TriggerBreakpoint() }
389    }
390
391});
392
393/// The macro used when an assertion is enabled.
394///
395/// This isn't for direct use by apps, but this is the code that is inserted
396/// when an [`SDL_assert`] is enabled.
397///
398/// The `do {} while(0)` avoids dangling else problems:
399///
400/// ```c
401/// if (x) SDL_assert(y); else blah();
402/// ```
403///
404/// ... without the do/while, the "else" could attach to this macro's "if". We
405/// try to handle just the minimum we need here in a macro...the loop, the
406/// static vars, and break points. The heavy lifting is handled in
407/// [`SDL_ReportAssertion()`].
408///
409/// ## Parameters
410/// - `condition`: the condition to assert.
411///
412/// ## Availability
413/// This macro is available since SDL 3.2.0.
414#[doc(hidden)]
415#[macro_export]
416macro_rules! SDL_enabled_assert {
417    ($condition:expr) => {{
418        while !$condition {
419            // Yes, this is wildly unsafe, but it's fine! :thisisfine:
420            // - SDL uses a mutex to protect access to SDL_AssertData
421            // - The static mut can only be accessed through the pointer that's passed to SDL
422            let assert_data = {
423                $crate::__const_c_str!(CONDITION = ::core::stringify!($condition));
424                static mut SDL_ASSERT_DATA: $crate::assert::SDL_AssertData =
425                    $crate::assert::SDL_AssertData {
426                        always_ignore: false,
427                        trigger_count: 0,
428                        condition: CONDITION.as_ptr(),
429                        filename: ::core::ptr::null(),
430                        linenum: 0,
431                        function: ::core::ptr::null(),
432                        next: ::core::ptr::null(),
433                    };
434                &raw mut SDL_ASSERT_DATA
435            };
436            const LOCATION: &::core::panic::Location = ::core::panic::Location::caller();
437            $crate::__const_c_str!(FILENAME = LOCATION.file());
438            match unsafe {
439                $crate::assert::SDL_ReportAssertion(
440                    assert_data,
441                    b"???\0".as_ptr().cast::<::core::ffi::c_char>(),
442                    FILENAME.as_ptr(),
443                    LOCATION.line() as ::core::ffi::c_int,
444                )
445            } {
446                $crate::assert::SDL_ASSERTION_RETRY => continue,
447                $crate::assert::SDL_ASSERTION_BREAK => unsafe {
448                    $crate::assert::SDL_AssertBreakpoint()
449                },
450                _ => (),
451            }
452            break;
453        }
454    }};
455}
456#[doc(inline)]
457pub use SDL_enabled_assert;
458
459apply_cfg!(#[cfg(doc)] => {
460    /// An assertion test that is normally performed only in debug builds.
461    ///
462    /// This macro is enabled when the [`SDL_ASSERT_LEVEL`] is >= 2, otherwise it is
463    /// disabled. This is meant to only do these tests in debug builds, so they can
464    /// tend to be more expensive, and they are meant to bring everything to a halt
465    /// when they fail, with the programmer there to assess the problem.
466    ///
467    /// In short: you can sprinkle these around liberally and assume they will
468    /// evaporate out of the build when building for end-users.
469    ///
470    /// When assertions are disabled, this wraps `condition` in a `sizeof`
471    /// operator, which means any function calls and side effects will not run, but
472    /// the compiler will not complain about any otherwise-unused variables that
473    /// are only referenced in the assertion.
474    ///
475    /// One can set the environment variable "SDL_ASSERT" to one of several strings
476    /// ("abort", "break", "retry", "ignore", "always_ignore") to force a default
477    /// behavior, which may be desirable for automation purposes. If your platform
478    /// requires GUI interfaces to happen on the main thread but you're debugging
479    /// an assertion in a background thread, it might be desirable to set this to
480    /// "break" so that your debugger takes control as soon as assert is triggered,
481    /// instead of risking a bad UI interaction (deadlock, etc) in the application.
482    ///
483    /// ## Parameters
484    /// - `condition`: boolean value to test.
485    ///
486    /// ## Thread safety
487    /// It is safe to call this macro from any thread.
488    ///
489    /// ## Availability
490    /// This macro is available since SDL 3.2.0.
491    #[doc(hidden)]
492    #[macro_export]
493    macro_rules! SDL_assert {
494        ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
495    }
496    #[doc(inline)]
497    pub use SDL_assert;
498
499    /// An assertion test that is performed even in release builds.
500    ///
501    /// This macro is enabled when the [`SDL_ASSERT_LEVEL`] is >= 1, otherwise it is
502    /// disabled. This is meant to be for tests that are cheap to make and
503    /// extremely unlikely to fail; generally it is frowned upon to have an
504    /// assertion failure in a release build, so these assertions generally need to
505    /// be of more than life-and-death importance if there's a chance they might
506    /// trigger. You should almost always consider handling these cases more
507    /// gracefully than an assert allows.
508    ///
509    /// When assertions are disabled, this wraps `condition` in a `sizeof`
510    /// operator, which means any function calls and side effects will not run, but
511    /// the compiler will not complain about any otherwise-unused variables that
512    /// are only referenced in the assertion.
513    ///
514    /// One can set the environment variable "SDL_ASSERT" to one of several strings
515    /// ("abort", "break", "retry", "ignore", "always_ignore") to force a default
516    /// behavior, which may be desirable for automation purposes. If your platform
517    /// requires GUI interfaces to happen on the main thread but you're debugging
518    /// an assertion in a background thread, it might be desirable to set this to
519    /// "break" so that your debugger takes control as soon as assert is triggered,
520    /// instead of risking a bad UI interaction (deadlock, etc) in the application.
521    /// *
522    ///
523    /// ## Parameters
524    /// - `condition`: boolean value to test.
525    ///
526    /// ## Thread safety
527    /// It is safe to call this macro from any thread.
528    ///
529    /// ## Availability
530    /// This macro is available since SDL 3.2.0.
531    #[doc(hidden)]
532    #[macro_export]
533    macro_rules! SDL_assert_release {
534        ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
535    }
536    #[doc(inline)]
537    pub use SDL_assert_release;
538
539    /// An assertion test that is performed only when built with paranoid settings.
540    ///
541    /// This macro is enabled when the [`SDL_ASSERT_LEVEL`] is >= 3, otherwise it is
542    /// disabled. This is a higher level than both release and debug, so these
543    /// tests are meant to be expensive and only run when specifically looking for
544    /// extremely unexpected failure cases in a special build.
545    ///
546    /// When assertions are disabled, this wraps `condition` in a `sizeof`
547    /// operator, which means any function calls and side effects will not run, but
548    /// the compiler will not complain about any otherwise-unused variables that
549    /// are only referenced in the assertion.
550    ///
551    /// One can set the environment variable "SDL_ASSERT" to one of several strings
552    /// ("abort", "break", "retry", "ignore", "always_ignore") to force a default
553    /// behavior, which may be desirable for automation purposes. If your platform
554    /// requires GUI interfaces to happen on the main thread but you're debugging
555    /// an assertion in a background thread, it might be desirable to set this to
556    /// "break" so that your debugger takes control as soon as assert is triggered,
557    /// instead of risking a bad UI interaction (deadlock, etc) in the application.
558    ///
559    /// ## Parameters
560    /// - `condition`: boolean value to test.
561    ///
562    /// ## Thread safety
563    /// It is safe to call this macro from any thread.
564    ///
565    /// ## Availability
566    /// This macro is available since SDL 3.2.0.
567    #[doc(hidden)]
568    #[macro_export]
569    macro_rules! SDL_assert_paranoid {
570        ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
571    }
572    #[doc(inline)]
573    pub use SDL_assert_paranoid;
574});
575
576apply_cfg!(#[cfg(not(doc))] => {
577    apply_cfg!(#[cfg(feature = "assert-level-disabled")] => {
578        #[doc(hidden)]
579        #[macro_export]
580        macro_rules! SDL_assert {
581            ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
582        }
583        #[doc(inline)]
584        pub use SDL_assert;
585
586        #[doc(hidden)]
587        #[macro_export]
588        macro_rules! SDL_assert_release {
589            ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
590        }
591        #[doc(inline)]
592        pub use SDL_assert_release;
593
594        #[doc(hidden)]
595        #[macro_export]
596        macro_rules! SDL_assert_paranoid {
597            ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
598        }
599        #[doc(inline)]
600        pub use SDL_assert_paranoid;
601    });
602
603    apply_cfg!(#[cfg(not(feature = "assert-level-disabled"))] => {
604        apply_cfg!(#[cfg(feature = "assert-level-release")] => {
605            #[doc(hidden)]
606            #[macro_export]
607            macro_rules! SDL_assert {
608                ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
609            }
610            #[doc(inline)]
611            pub use SDL_assert;
612
613            #[doc(hidden)]
614            #[macro_export]
615            macro_rules! SDL_assert_release {
616                ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
617            }
618            #[doc(inline)]
619            pub use SDL_assert_release;
620
621            #[doc(hidden)]
622            #[macro_export]
623            macro_rules! SDL_assert_paranoid {
624                ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
625            }
626            #[doc(inline)]
627            pub use SDL_assert_paranoid;
628        });
629
630        apply_cfg!(#[cfg(not(feature = "assert-level-release"))] => {
631            apply_cfg!(#[cfg(feature = "assert-level-debug")] => {
632                #[doc(hidden)]
633                #[macro_export]
634                macro_rules! SDL_assert {
635                    ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
636                }
637                #[doc(inline)]
638                pub use SDL_assert;
639
640                #[doc(hidden)]
641                #[macro_export]
642                macro_rules! SDL_assert_release {
643                    ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
644                }
645                #[doc(inline)]
646                pub use SDL_assert_release;
647
648                #[doc(hidden)]
649                #[macro_export]
650                macro_rules! SDL_assert_paranoid {
651                    ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
652                }
653                #[doc(inline)]
654                pub use SDL_assert_paranoid;
655            });
656
657            apply_cfg!(#[cfg(not(feature = "assert-level-debug"))] => {
658                apply_cfg!(#[cfg(feature = "assert-level-paranoid")] => {
659                    #[doc(hidden)]
660                    #[macro_export]
661                    macro_rules! SDL_assert {
662                        ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
663                    }
664                    #[doc(inline)]
665                    pub use SDL_assert;
666
667                    #[doc(hidden)]
668                    #[macro_export]
669                    macro_rules! SDL_assert_release {
670                        ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
671                    }
672                    #[doc(inline)]
673                    pub use SDL_assert_release;
674
675                    #[doc(hidden)]
676                    #[macro_export]
677                    macro_rules! SDL_assert_paranoid {
678                        ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
679                    }
680                    #[doc(inline)]
681                    pub use SDL_assert_paranoid;
682                });
683
684                apply_cfg!(#[cfg(not(feature = "assert-level-paranoid"))] => {
685                    ::core::compile_error!("Unknown assertion level.");
686                });
687
688            });
689
690        });
691
692    });
693
694});
695
696/// An assertion test that is always performed.
697///
698/// This macro is always enabled no matter what [`SDL_ASSERT_LEVEL`] is set to. You
699/// almost never want to use this, as it could trigger on an end-user's system,
700/// crashing your program.
701///
702/// One can set the environment variable "SDL_ASSERT" to one of several strings
703/// ("abort", "break", "retry", "ignore", "always_ignore") to force a default
704/// behavior, which may be desirable for automation purposes. If your platform
705/// requires GUI interfaces to happen on the main thread but you're debugging
706/// an assertion in a background thread, it might be desirable to set this to
707/// "break" so that your debugger takes control as soon as assert is triggered,
708/// instead of risking a bad UI interaction (deadlock, etc) in the application.
709///
710/// ## Parameters
711/// - `condition`: boolean value to test.
712///
713/// ## Thread safety
714/// It is safe to call this macro from any thread.
715///
716/// ## Availability
717/// This macro is available since SDL 3.2.0.
718#[doc(hidden)]
719#[macro_export]
720macro_rules! SDL_assert_always {
721    ($condition:expr) => {
722        $crate::assert::SDL_enabled_assert!($condition)
723    };
724}
725#[doc(inline)]
726pub use SDL_assert_always;
727
728/// A callback that fires when an SDL assertion fails.
729///
730/// ## Parameters
731/// - `data`: a pointer to the [`SDL_AssertData`] structure corresponding to the
732///   current assertion.
733/// - `userdata`: what was passed as `userdata` to [`SDL_SetAssertionHandler()`].
734///
735/// ## Return value
736/// Returns an [`SDL_AssertState`] value indicating how to handle the failure.
737///
738/// ## Thread safety
739/// This callback may be called from any thread that triggers an
740///   assert at any time.
741///
742/// ## Availability
743/// This datatype is available since SDL 3.2.0.
744pub type SDL_AssertionHandler = ::core::option::Option<
745    unsafe extern "C" fn(
746        data: *const SDL_AssertData,
747        userdata: *mut ::core::ffi::c_void,
748    ) -> SDL_AssertState,
749>;
750
751unsafe extern "C" {
752    /// Set an application-defined assertion handler.
753    ///
754    /// This function allows an application to show its own assertion UI and/or
755    /// force the response to an assertion failure. If the application doesn't
756    /// provide this, SDL will try to do the right thing, popping up a
757    /// system-specific GUI dialog, and probably minimizing any fullscreen windows.
758    ///
759    /// This callback may fire from any thread, but it runs wrapped in a mutex, so
760    /// it will only fire from one thread at a time.
761    ///
762    /// This callback is NOT reset to SDL's internal handler upon [`SDL_Quit()`]!
763    ///
764    /// ## Parameters
765    /// - `handler`: the [`SDL_AssertionHandler`] function to call when an assertion
766    ///   fails or NULL for the default handler.
767    /// - `userdata`: a pointer that is passed to `handler`.
768    ///
769    /// ## Thread safety
770    /// It is safe to call this function from any thread.
771    ///
772    /// ## Availability
773    /// This function is available since SDL 3.2.0.
774    ///
775    /// ## See also
776    /// - [`SDL_GetAssertionHandler`]
777    pub fn SDL_SetAssertionHandler(
778        handler: SDL_AssertionHandler,
779        userdata: *mut ::core::ffi::c_void,
780    );
781}
782
783unsafe extern "C" {
784    /// Get the default assertion handler.
785    ///
786    /// This returns the function pointer that is called by default when an
787    /// assertion is triggered. This is an internal function provided by SDL, that
788    /// is used for assertions when [`SDL_SetAssertionHandler()`] hasn't been used to
789    /// provide a different function.
790    ///
791    /// ## Return value
792    /// Returns the default [`SDL_AssertionHandler`] that is called when an assert
793    ///   triggers.
794    ///
795    /// ## Thread safety
796    /// It is safe to call this function from any thread.
797    ///
798    /// ## Availability
799    /// This function is available since SDL 3.2.0.
800    ///
801    /// ## See also
802    /// - [`SDL_GetAssertionHandler`]
803    pub fn SDL_GetDefaultAssertionHandler() -> SDL_AssertionHandler;
804}
805
806unsafe extern "C" {
807    /// Get the current assertion handler.
808    ///
809    /// This returns the function pointer that is called when an assertion is
810    /// triggered. This is either the value last passed to
811    /// [`SDL_SetAssertionHandler()`], or if no application-specified function is set,
812    /// is equivalent to calling [`SDL_GetDefaultAssertionHandler()`].
813    ///
814    /// The parameter `puserdata` is a pointer to a void*, which will store the
815    /// "userdata" pointer that was passed to [`SDL_SetAssertionHandler()`]. This value
816    /// will always be NULL for the default handler. If you don't care about this
817    /// data, it is safe to pass a NULL pointer to this function to ignore it.
818    ///
819    /// ## Parameters
820    /// - `puserdata`: pointer which is filled with the "userdata" pointer that
821    ///   was passed to [`SDL_SetAssertionHandler()`].
822    ///
823    /// ## Return value
824    /// Returns the [`SDL_AssertionHandler`] that is called when an assert triggers.
825    ///
826    /// ## Thread safety
827    /// It is safe to call this function from any thread.
828    ///
829    /// ## Availability
830    /// This function is available since SDL 3.2.0.
831    ///
832    /// ## See also
833    /// - [`SDL_SetAssertionHandler`]
834    pub fn SDL_GetAssertionHandler(
835        puserdata: *mut *mut ::core::ffi::c_void,
836    ) -> SDL_AssertionHandler;
837}
838
839unsafe extern "C" {
840    /// Get a list of all assertion failures.
841    ///
842    /// This function gets all assertions triggered since the last call to
843    /// [`SDL_ResetAssertionReport()`], or the start of the program.
844    ///
845    /// The proper way to examine this data looks something like this:
846    ///
847    /// ```c
848    /// const SDL_AssertData *item = SDL_GetAssertionReport();
849    /// while (item) {
850    ///    printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n",
851    ///           item->condition, item->function, item->filename,
852    ///           item->linenum, item->trigger_count,
853    ///           item->always_ignore ? "yes" : "no");
854    ///    item = item->next;
855    /// }
856    /// ```
857    ///
858    /// ## Return value
859    /// Returns a list of all failed assertions or NULL if the list is empty. This
860    ///   memory should not be modified or freed by the application. This
861    ///   pointer remains valid until the next call to [`SDL_Quit()`] or
862    ///   [`SDL_ResetAssertionReport()`].
863    ///
864    /// ## Thread safety
865    /// This function is not thread safe. Other threads calling
866    ///   [`SDL_ResetAssertionReport()`] simultaneously, may render the
867    ///   returned pointer invalid.
868    ///
869    /// ## Availability
870    /// This function is available since SDL 3.2.0.
871    ///
872    /// ## See also
873    /// - [`SDL_ResetAssertionReport`]
874    pub fn SDL_GetAssertionReport() -> *const SDL_AssertData;
875}
876
877unsafe extern "C" {
878    /// Clear the list of all assertion failures.
879    ///
880    /// This function will clear the list of all assertions triggered up to that
881    /// point. Immediately following this call, [`SDL_GetAssertionReport`] will return
882    /// no items. In addition, any previously-triggered assertions will be reset to
883    /// a trigger_count of zero, and their always_ignore state will be false.
884    ///
885    /// ## Thread safety
886    /// This function is not thread safe. Other threads triggering an
887    ///   assertion, or simultaneously calling this function may cause
888    ///   memory leaks or crashes.
889    ///
890    /// ## Availability
891    /// This function is available since SDL 3.2.0.
892    ///
893    /// ## See also
894    /// - [`SDL_GetAssertionReport`]
895    pub fn SDL_ResetAssertionReport();
896}
897
898#[cfg(doc)]
899use crate::everything::*;