Skip to main content

rs_teststand/station/
debug_options.rs

1//! Engine debugging option flags.
2
3bitflags::bitflags! {
4    /// Station debugging options (`DebugOption_*`).
5    ///
6    /// A bitmask read and written whole via
7    /// [`StationOptions::debug_options`](crate::StationOptions::debug_options)
8    /// and its setter, so changing one option means editing a mask rather than
9    /// assigning a value, always read, modify the bits, write back.
10    ///
11    /// ```
12    /// use rs_teststand::DebugOptions;
13    ///
14    /// // Turn off just the dialog-raising bits, preserving everything else.
15    /// let current = DebugOptions::STACK_CHECKING | DebugOptions::REPORT_OBJECT_LEAKS;
16    /// let quiet = current.difference(DebugOptions::MODAL_ON_SHUTDOWN);
17    /// assert!(quiet.contains(DebugOptions::STACK_CHECKING));
18    /// assert!(!quiet.contains(DebugOptions::REPORT_OBJECT_LEAKS));
19    /// ```
20    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
21    pub struct DebugOptions: i32 {
22        /// No debugging options (`DebugOption_NoOptions`).
23        const NONE = 0;
24        /// Validate the stack around code-module calls (`DebugOption_StackChecking`).
25        const STACK_CHECKING = 1;
26        /// Validate buffers around code-module calls (`DebugOption_BufferChecking`).
27        const BUFFER_CHECKING = 2;
28        /// Report leaked objects at shutdown (`DebugOption_ReportObjectLeaks`).
29        ///
30        /// The report is a modal dialog, so this bit blocks an unattended host
31        /// at exit. Leak *detection* is separate, clearing this suppresses
32        /// only the dialog.
33        const REPORT_OBJECT_LEAKS = 4;
34        /// Send output messages to an attached debugger
35        /// (`DebugOption_SendOutputMessagesToDebugger`).
36        const SEND_OUTPUT_MESSAGES_TO_DEBUGGER = 8;
37        /// Report known OS and component problems
38        /// (`DebugOption_ReportKnownOSandComponentProblems`).
39        ///
40        /// Also a modal dialog raised during shutdown.
41        const REPORT_KNOWN_OS_AND_COMPONENT_PROBLEMS = 16;
42
43        /// The bits that raise a modal dialog while the engine shuts down.
44        ///
45        /// Not an engine constant: the union this crate clears so that a host
46        /// with no one at the keyboard cannot wedge at exit.
47        const MODAL_ON_SHUTDOWN =
48            Self::REPORT_OBJECT_LEAKS.bits() | Self::REPORT_KNOWN_OS_AND_COMPONENT_PROBLEMS.bits();
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::DebugOptions;
55
56    #[test]
57    fn modal_bits_are_exactly_the_two_shutdown_dialogs() {
58        assert_eq!(DebugOptions::MODAL_ON_SHUTDOWN.bits(), 4 | 16);
59    }
60
61    #[test]
62    fn clearing_modal_bits_preserves_unrelated_options() {
63        // The engine hands back one mask for every debug setting, so the
64        // hardening step must subtract bits rather than overwrite the value.
65        let current = DebugOptions::STACK_CHECKING
66            | DebugOptions::BUFFER_CHECKING
67            | DebugOptions::SEND_OUTPUT_MESSAGES_TO_DEBUGGER
68            | DebugOptions::MODAL_ON_SHUTDOWN;
69
70        let quiet = current.difference(DebugOptions::MODAL_ON_SHUTDOWN);
71
72        assert!(quiet.contains(DebugOptions::STACK_CHECKING));
73        assert!(quiet.contains(DebugOptions::BUFFER_CHECKING));
74        assert!(quiet.contains(DebugOptions::SEND_OUTPUT_MESSAGES_TO_DEBUGGER));
75        assert!(!quiet.contains(DebugOptions::REPORT_OBJECT_LEAKS));
76        assert!(!quiet.contains(DebugOptions::REPORT_KNOWN_OS_AND_COMPONENT_PROBLEMS));
77    }
78
79    #[test]
80    fn unknown_bits_from_a_newer_engine_survive_a_round_trip() {
81        // A future engine may define debug bits this build does not name;
82        // clearing the modal ones must not discard them.
83        let unknown = DebugOptions::from_bits_retain(1 << 20);
84        let current = unknown | DebugOptions::MODAL_ON_SHUTDOWN;
85        let quiet = current.difference(DebugOptions::MODAL_ON_SHUTDOWN);
86        assert_eq!(quiet.bits(), 1 << 20);
87    }
88}