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