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
286#[cfg(feature = "metadata")]
287impl sdl3_sys::metadata::GroupMetadata for SDL_AssertState {
288    const GROUP_METADATA: &'static sdl3_sys::metadata::Group =
289        &crate::metadata::assert::METADATA_SDL_AssertState;
290}
291
292/// Information about an assertion failure.
293///
294/// This structure is filled in with information about a triggered assertion,
295/// used by the assertion handler, then added to the assertion report. This is
296/// returned as a linked list from [`SDL_GetAssertionReport()`].
297///
298/// ## Availability
299/// This struct is available since SDL 3.2.0.
300#[repr(C)]
301#[derive(Clone, Copy)]
302#[cfg_attr(feature = "debug-impls", derive(Debug))]
303pub struct SDL_AssertData {
304    /// true if app should always continue when assertion is triggered.
305    pub always_ignore: ::core::primitive::bool,
306    /// Number of times this assertion has been triggered.
307    pub trigger_count: ::core::ffi::c_uint,
308    /// A string of this assert's test code.
309    pub condition: *const ::core::ffi::c_char,
310    /// The source file where this assert lives.
311    pub filename: *const ::core::ffi::c_char,
312    /// The line in `filename` where this assert lives.
313    pub linenum: ::core::ffi::c_int,
314    /// The name of the function where this assert lives.
315    pub function: *const ::core::ffi::c_char,
316    /// next item in the linked list.
317    pub next: *const SDL_AssertData,
318}
319
320impl ::core::default::Default for SDL_AssertData {
321    /// Initialize all fields to zero
322    #[inline(always)]
323    fn default() -> Self {
324        unsafe { ::core::mem::MaybeUninit::<Self>::zeroed().assume_init() }
325    }
326}
327
328unsafe extern "C" {
329    /// Never call this directly.
330    ///
331    /// Use the [`SDL_assert`] macros instead.
332    ///
333    /// ## Parameters
334    /// - `data`: assert data structure.
335    /// - `func`: function name.
336    /// - `file`: file name.
337    /// - `line`: line number.
338    ///
339    /// ## Return value
340    /// Returns assert state.
341    ///
342    /// ## Thread safety
343    /// It is safe to call this function from any thread.
344    ///
345    /// ## Availability
346    /// This function is available since SDL 3.2.0.
347    pub fn SDL_ReportAssertion(
348        data: *mut SDL_AssertData,
349        func: *const ::core::ffi::c_char,
350        file: *const ::core::ffi::c_char,
351        line: ::core::ffi::c_int,
352    ) -> SDL_AssertState;
353}
354
355apply_cfg!(#[cfg(doc)] => {
356    /// The macro used when an assertion triggers a breakpoint.
357    ///
358    /// This isn't for direct use by apps; use [`SDL_assert`] or [`SDL_TriggerBreakpoint`]
359    /// instead.
360    ///
361    /// ## Availability
362    /// This macro is available since SDL 3.2.0.
363    #[inline(always)]
364    pub unsafe fn SDL_AssertBreakpoint() {
365        unsafe { SDL_TriggerBreakpoint() }
366    }
367});
368
369apply_cfg!(#[cfg(not(doc))] => {
370    #[inline(always)]
371    pub unsafe fn SDL_AssertBreakpoint() {
372        unsafe { SDL_TriggerBreakpoint() }
373    }
374
375});
376
377/// The macro used when an assertion is enabled.
378///
379/// This isn't for direct use by apps, but this is the code that is inserted
380/// when an [`SDL_assert`] is enabled.
381///
382/// The `do {} while(0)` avoids dangling else problems:
383///
384/// ```c
385/// if (x) SDL_assert(y); else blah();
386/// ```
387///
388/// ... without the do/while, the "else" could attach to this macro's "if". We
389/// try to handle just the minimum we need here in a macro...the loop, the
390/// static vars, and break points. The heavy lifting is handled in
391/// [`SDL_ReportAssertion()`].
392///
393/// ## Parameters
394/// - `condition`: the condition to assert.
395///
396/// ## Availability
397/// This macro is available since SDL 3.2.0.
398#[doc(hidden)]
399#[macro_export]
400macro_rules! SDL_enabled_assert {
401    ($condition:expr) => {{
402        while !$condition {
403            // Yes, this is wildly unsafe, but it's fine! :thisisfine:
404            // - SDL uses a mutex to protect access to SDL_AssertData
405            // - The static mut can only be accessed through the pointer that's passed to SDL
406            let assert_data = {
407                $crate::__const_c_str!(CONDITION = ::core::stringify!($condition));
408                static mut SDL_ASSERT_DATA: $crate::assert::SDL_AssertData =
409                    $crate::assert::SDL_AssertData {
410                        always_ignore: false,
411                        trigger_count: 0,
412                        condition: CONDITION.as_ptr(),
413                        filename: ::core::ptr::null(),
414                        linenum: 0,
415                        function: ::core::ptr::null(),
416                        next: ::core::ptr::null(),
417                    };
418                &raw mut SDL_ASSERT_DATA
419            };
420            const LOCATION: &::core::panic::Location = ::core::panic::Location::caller();
421            $crate::__const_c_str!(FILENAME = LOCATION.file());
422            match unsafe {
423                $crate::assert::SDL_ReportAssertion(
424                    assert_data,
425                    b"???\0".as_ptr().cast::<::core::ffi::c_char>(),
426                    FILENAME.as_ptr(),
427                    LOCATION.line() as ::core::ffi::c_int,
428                )
429            } {
430                $crate::assert::SDL_ASSERTION_RETRY => continue,
431                $crate::assert::SDL_ASSERTION_BREAK => unsafe {
432                    $crate::assert::SDL_AssertBreakpoint()
433                },
434                _ => (),
435            }
436            break;
437        }
438    }};
439}
440#[doc(inline)]
441pub use SDL_enabled_assert;
442
443apply_cfg!(#[cfg(doc)] => {
444    /// An assertion test that is normally performed only in debug builds.
445    ///
446    /// This macro is enabled when the [`SDL_ASSERT_LEVEL`] is >= 2, otherwise it is
447    /// disabled. This is meant to only do these tests in debug builds, so they can
448    /// tend to be more expensive, and they are meant to bring everything to a halt
449    /// when they fail, with the programmer there to assess the problem.
450    ///
451    /// In short: you can sprinkle these around liberally and assume they will
452    /// evaporate out of the build when building for end-users.
453    ///
454    /// When assertions are disabled, this wraps `condition` in a `sizeof`
455    /// operator, which means any function calls and side effects will not run, but
456    /// the compiler will not complain about any otherwise-unused variables that
457    /// are only referenced in the assertion.
458    ///
459    /// One can set the environment variable "SDL_ASSERT" to one of several strings
460    /// ("abort", "break", "retry", "ignore", "always_ignore") to force a default
461    /// behavior, which may be desirable for automation purposes. If your platform
462    /// requires GUI interfaces to happen on the main thread but you're debugging
463    /// an assertion in a background thread, it might be desirable to set this to
464    /// "break" so that your debugger takes control as soon as assert is triggered,
465    /// instead of risking a bad UI interaction (deadlock, etc) in the application.
466    ///
467    /// ## Parameters
468    /// - `condition`: boolean value to test.
469    ///
470    /// ## Thread safety
471    /// It is safe to call this macro from any thread.
472    ///
473    /// ## Availability
474    /// This macro is available since SDL 3.2.0.
475    #[doc(hidden)]
476    #[macro_export]
477    macro_rules! SDL_assert {
478        ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
479    }
480    #[doc(inline)]
481    pub use SDL_assert;
482
483    /// An assertion test that is performed even in release builds.
484    ///
485    /// This macro is enabled when the [`SDL_ASSERT_LEVEL`] is >= 1, otherwise it is
486    /// disabled. This is meant to be for tests that are cheap to make and
487    /// extremely unlikely to fail; generally it is frowned upon to have an
488    /// assertion failure in a release build, so these assertions generally need to
489    /// be of more than life-and-death importance if there's a chance they might
490    /// trigger. You should almost always consider handling these cases more
491    /// gracefully than an assert allows.
492    ///
493    /// When assertions are disabled, this wraps `condition` in a `sizeof`
494    /// operator, which means any function calls and side effects will not run, but
495    /// the compiler will not complain about any otherwise-unused variables that
496    /// are only referenced in the assertion.
497    ///
498    /// One can set the environment variable "SDL_ASSERT" to one of several strings
499    /// ("abort", "break", "retry", "ignore", "always_ignore") to force a default
500    /// behavior, which may be desirable for automation purposes. If your platform
501    /// requires GUI interfaces to happen on the main thread but you're debugging
502    /// an assertion in a background thread, it might be desirable to set this to
503    /// "break" so that your debugger takes control as soon as assert is triggered,
504    /// instead of risking a bad UI interaction (deadlock, etc) in the application.
505    /// *
506    ///
507    /// ## Parameters
508    /// - `condition`: boolean value to test.
509    ///
510    /// ## Thread safety
511    /// It is safe to call this macro from any thread.
512    ///
513    /// ## Availability
514    /// This macro is available since SDL 3.2.0.
515    #[doc(hidden)]
516    #[macro_export]
517    macro_rules! SDL_assert_release {
518        ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
519    }
520    #[doc(inline)]
521    pub use SDL_assert_release;
522
523    /// An assertion test that is performed only when built with paranoid settings.
524    ///
525    /// This macro is enabled when the [`SDL_ASSERT_LEVEL`] is >= 3, otherwise it is
526    /// disabled. This is a higher level than both release and debug, so these
527    /// tests are meant to be expensive and only run when specifically looking for
528    /// extremely unexpected failure cases in a special build.
529    ///
530    /// When assertions are disabled, this wraps `condition` in a `sizeof`
531    /// operator, which means any function calls and side effects will not run, but
532    /// the compiler will not complain about any otherwise-unused variables that
533    /// are only referenced in the assertion.
534    ///
535    /// One can set the environment variable "SDL_ASSERT" to one of several strings
536    /// ("abort", "break", "retry", "ignore", "always_ignore") to force a default
537    /// behavior, which may be desirable for automation purposes. If your platform
538    /// requires GUI interfaces to happen on the main thread but you're debugging
539    /// an assertion in a background thread, it might be desirable to set this to
540    /// "break" so that your debugger takes control as soon as assert is triggered,
541    /// instead of risking a bad UI interaction (deadlock, etc) in the application.
542    ///
543    /// ## Parameters
544    /// - `condition`: boolean value to test.
545    ///
546    /// ## Thread safety
547    /// It is safe to call this macro from any thread.
548    ///
549    /// ## Availability
550    /// This macro is available since SDL 3.2.0.
551    #[doc(hidden)]
552    #[macro_export]
553    macro_rules! SDL_assert_paranoid {
554        ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
555    }
556    #[doc(inline)]
557    pub use SDL_assert_paranoid;
558});
559
560apply_cfg!(#[cfg(not(doc))] => {
561    apply_cfg!(#[cfg(feature = "assert-level-disabled")] => {
562        #[doc(hidden)]
563        #[macro_export]
564        macro_rules! SDL_assert {
565            ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
566        }
567        #[doc(inline)]
568        pub use SDL_assert;
569
570        #[doc(hidden)]
571        #[macro_export]
572        macro_rules! SDL_assert_release {
573            ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
574        }
575        #[doc(inline)]
576        pub use SDL_assert_release;
577
578        #[doc(hidden)]
579        #[macro_export]
580        macro_rules! SDL_assert_paranoid {
581            ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
582        }
583        #[doc(inline)]
584        pub use SDL_assert_paranoid;
585    });
586
587    apply_cfg!(#[cfg(not(feature = "assert-level-disabled"))] => {
588        apply_cfg!(#[cfg(feature = "assert-level-release")] => {
589            #[doc(hidden)]
590            #[macro_export]
591            macro_rules! SDL_assert {
592                ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
593            }
594            #[doc(inline)]
595            pub use SDL_assert;
596
597            #[doc(hidden)]
598            #[macro_export]
599            macro_rules! SDL_assert_release {
600                ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
601            }
602            #[doc(inline)]
603            pub use SDL_assert_release;
604
605            #[doc(hidden)]
606            #[macro_export]
607            macro_rules! SDL_assert_paranoid {
608                ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
609            }
610            #[doc(inline)]
611            pub use SDL_assert_paranoid;
612        });
613
614        apply_cfg!(#[cfg(not(feature = "assert-level-release"))] => {
615            apply_cfg!(#[cfg(feature = "assert-level-debug")] => {
616                #[doc(hidden)]
617                #[macro_export]
618                macro_rules! SDL_assert {
619                    ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
620                }
621                #[doc(inline)]
622                pub use SDL_assert;
623
624                #[doc(hidden)]
625                #[macro_export]
626                macro_rules! SDL_assert_release {
627                    ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
628                }
629                #[doc(inline)]
630                pub use SDL_assert_release;
631
632                #[doc(hidden)]
633                #[macro_export]
634                macro_rules! SDL_assert_paranoid {
635                    ($condition:expr) => { $crate::assert::SDL_disabled_assert!($condition) };
636                }
637                #[doc(inline)]
638                pub use SDL_assert_paranoid;
639            });
640
641            apply_cfg!(#[cfg(not(feature = "assert-level-debug"))] => {
642                apply_cfg!(#[cfg(feature = "assert-level-paranoid")] => {
643                    #[doc(hidden)]
644                    #[macro_export]
645                    macro_rules! SDL_assert {
646                        ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
647                    }
648                    #[doc(inline)]
649                    pub use SDL_assert;
650
651                    #[doc(hidden)]
652                    #[macro_export]
653                    macro_rules! SDL_assert_release {
654                        ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
655                    }
656                    #[doc(inline)]
657                    pub use SDL_assert_release;
658
659                    #[doc(hidden)]
660                    #[macro_export]
661                    macro_rules! SDL_assert_paranoid {
662                        ($condition:expr) => { $crate::assert::SDL_enabled_assert!($condition) };
663                    }
664                    #[doc(inline)]
665                    pub use SDL_assert_paranoid;
666                });
667
668                apply_cfg!(#[cfg(not(feature = "assert-level-paranoid"))] => {
669                    ::core::compile_error!("Unknown assertion level.");
670                });
671
672            });
673
674        });
675
676    });
677
678});
679
680/// An assertion test that is always performed.
681///
682/// This macro is always enabled no matter what [`SDL_ASSERT_LEVEL`] is set to. You
683/// almost never want to use this, as it could trigger on an end-user's system,
684/// crashing your program.
685///
686/// One can set the environment variable "SDL_ASSERT" to one of several strings
687/// ("abort", "break", "retry", "ignore", "always_ignore") to force a default
688/// behavior, which may be desirable for automation purposes. If your platform
689/// requires GUI interfaces to happen on the main thread but you're debugging
690/// an assertion in a background thread, it might be desirable to set this to
691/// "break" so that your debugger takes control as soon as assert is triggered,
692/// instead of risking a bad UI interaction (deadlock, etc) in the application.
693///
694/// ## Parameters
695/// - `condition`: boolean value to test.
696///
697/// ## Thread safety
698/// It is safe to call this macro from any thread.
699///
700/// ## Availability
701/// This macro is available since SDL 3.2.0.
702#[doc(hidden)]
703#[macro_export]
704macro_rules! SDL_assert_always {
705    ($condition:expr) => {
706        $crate::assert::SDL_enabled_assert!($condition)
707    };
708}
709#[doc(inline)]
710pub use SDL_assert_always;
711
712/// A callback that fires when an SDL assertion fails.
713///
714/// ## Parameters
715/// - `data`: a pointer to the [`SDL_AssertData`] structure corresponding to the
716///   current assertion.
717/// - `userdata`: what was passed as `userdata` to [`SDL_SetAssertionHandler()`].
718///
719/// ## Return value
720/// Returns an [`SDL_AssertState`] value indicating how to handle the failure.
721///
722/// ## Thread safety
723/// This callback may be called from any thread that triggers an
724///   assert at any time.
725///
726/// ## Availability
727/// This datatype is available since SDL 3.2.0.
728pub type SDL_AssertionHandler = ::core::option::Option<
729    unsafe extern "C" fn(
730        data: *const SDL_AssertData,
731        userdata: *mut ::core::ffi::c_void,
732    ) -> SDL_AssertState,
733>;
734
735unsafe extern "C" {
736    /// Set an application-defined assertion handler.
737    ///
738    /// This function allows an application to show its own assertion UI and/or
739    /// force the response to an assertion failure. If the application doesn't
740    /// provide this, SDL will try to do the right thing, popping up a
741    /// system-specific GUI dialog, and probably minimizing any fullscreen windows.
742    ///
743    /// This callback may fire from any thread, but it runs wrapped in a mutex, so
744    /// it will only fire from one thread at a time.
745    ///
746    /// This callback is NOT reset to SDL's internal handler upon [`SDL_Quit()`]!
747    ///
748    /// ## Parameters
749    /// - `handler`: the [`SDL_AssertionHandler`] function to call when an assertion
750    ///   fails or NULL for the default handler.
751    /// - `userdata`: a pointer that is passed to `handler`.
752    ///
753    /// ## Thread safety
754    /// It is safe to call this function from any thread.
755    ///
756    /// ## Availability
757    /// This function is available since SDL 3.2.0.
758    ///
759    /// ## See also
760    /// - [`SDL_GetAssertionHandler`]
761    pub fn SDL_SetAssertionHandler(
762        handler: SDL_AssertionHandler,
763        userdata: *mut ::core::ffi::c_void,
764    );
765}
766
767unsafe extern "C" {
768    /// Get the default assertion handler.
769    ///
770    /// This returns the function pointer that is called by default when an
771    /// assertion is triggered. This is an internal function provided by SDL, that
772    /// is used for assertions when [`SDL_SetAssertionHandler()`] hasn't been used to
773    /// provide a different function.
774    ///
775    /// ## Return value
776    /// Returns the default [`SDL_AssertionHandler`] that is called when an assert
777    ///   triggers.
778    ///
779    /// ## Thread safety
780    /// It is safe to call this function from any thread.
781    ///
782    /// ## Availability
783    /// This function is available since SDL 3.2.0.
784    ///
785    /// ## See also
786    /// - [`SDL_GetAssertionHandler`]
787    pub fn SDL_GetDefaultAssertionHandler() -> SDL_AssertionHandler;
788}
789
790unsafe extern "C" {
791    /// Get the current assertion handler.
792    ///
793    /// This returns the function pointer that is called when an assertion is
794    /// triggered. This is either the value last passed to
795    /// [`SDL_SetAssertionHandler()`], or if no application-specified function is set,
796    /// is equivalent to calling [`SDL_GetDefaultAssertionHandler()`].
797    ///
798    /// The parameter `puserdata` is a pointer to a void*, which will store the
799    /// "userdata" pointer that was passed to [`SDL_SetAssertionHandler()`]. This value
800    /// will always be NULL for the default handler. If you don't care about this
801    /// data, it is safe to pass a NULL pointer to this function to ignore it.
802    ///
803    /// ## Parameters
804    /// - `puserdata`: pointer which is filled with the "userdata" pointer that
805    ///   was passed to [`SDL_SetAssertionHandler()`].
806    ///
807    /// ## Return value
808    /// Returns the [`SDL_AssertionHandler`] that is called when an assert triggers.
809    ///
810    /// ## Thread safety
811    /// It is safe to call this function from any thread.
812    ///
813    /// ## Availability
814    /// This function is available since SDL 3.2.0.
815    ///
816    /// ## See also
817    /// - [`SDL_SetAssertionHandler`]
818    pub fn SDL_GetAssertionHandler(
819        puserdata: *mut *mut ::core::ffi::c_void,
820    ) -> SDL_AssertionHandler;
821}
822
823unsafe extern "C" {
824    /// Get a list of all assertion failures.
825    ///
826    /// This function gets all assertions triggered since the last call to
827    /// [`SDL_ResetAssertionReport()`], or the start of the program.
828    ///
829    /// The proper way to examine this data looks something like this:
830    ///
831    /// ```c
832    /// const SDL_AssertData *item = SDL_GetAssertionReport();
833    /// while (item) {
834    ///    printf("'%s', %s (%s:%d), triggered %u times, always ignore: %s.\\n",
835    ///           item->condition, item->function, item->filename,
836    ///           item->linenum, item->trigger_count,
837    ///           item->always_ignore ? "yes" : "no");
838    ///    item = item->next;
839    /// }
840    /// ```
841    ///
842    /// ## Return value
843    /// Returns a list of all failed assertions or NULL if the list is empty. This
844    ///   memory should not be modified or freed by the application. This
845    ///   pointer remains valid until the next call to [`SDL_Quit()`] or
846    ///   [`SDL_ResetAssertionReport()`].
847    ///
848    /// ## Thread safety
849    /// This function is not thread safe. Other threads calling
850    ///   [`SDL_ResetAssertionReport()`] simultaneously, may render the
851    ///   returned pointer invalid.
852    ///
853    /// ## Availability
854    /// This function is available since SDL 3.2.0.
855    ///
856    /// ## See also
857    /// - [`SDL_ResetAssertionReport`]
858    pub fn SDL_GetAssertionReport() -> *const SDL_AssertData;
859}
860
861unsafe extern "C" {
862    /// Clear the list of all assertion failures.
863    ///
864    /// This function will clear the list of all assertions triggered up to that
865    /// point. Immediately following this call, [`SDL_GetAssertionReport`] will return
866    /// no items. In addition, any previously-triggered assertions will be reset to
867    /// a trigger_count of zero, and their always_ignore state will be false.
868    ///
869    /// ## Thread safety
870    /// This function is not thread safe. Other threads triggering an
871    ///   assertion, or simultaneously calling this function may cause
872    ///   memory leaks or crashes.
873    ///
874    /// ## Availability
875    /// This function is available since SDL 3.2.0.
876    ///
877    /// ## See also
878    /// - [`SDL_GetAssertionReport`]
879    pub fn SDL_ResetAssertionReport();
880}
881
882#[cfg(doc)]
883use crate::everything::*;