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::*;