Skip to main content

idakit_sys/
cfg_flags.rs

1//! The typed [`FlowChartFlags`] layer over `gdl.hpp`'s `FC_*` flow-chart build bits.
2
3use std::ffi::c_int;
4
5use bitflags::bitflags;
6
7bitflags! {
8    /// Flow-chart build flag bits from `gdl.hpp` (`FC_NOEXT`/`FC_CALL_ENDS`/`FC_NOPREDS`), passed
9    /// to `qflow_chart_t::qflow_chart_t`.
10    #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
11    #[doc(alias("FC_NOEXT", "FC_CALL_ENDS", "FC_NOPREDS"))]
12    pub struct FlowChartFlags: c_int {
13        /// Omit external blocks, jump targets outside the function (`FC_NOEXT`).
14        #[doc(alias("FC_NOEXT"))]
15        const NOEXT = 0x0002;
16        /// Call instructions terminate a basic block (`FC_CALL_ENDS`).
17        #[doc(alias("FC_CALL_ENDS"))]
18        const CALL_ENDS = 0x0020;
19        /// Skip predecessor-list computation (`FC_NOPREDS`).
20        #[doc(alias("FC_NOPREDS"))]
21        const NOPREDS = 0x0040;
22    }
23}
24
25#[cfg(test)]
26mod tests {
27    use assert2::assert;
28    use proptest::prelude::*;
29    use rstest::rstest;
30
31    use super::*;
32
33    #[rstest]
34    #[case::noext(FlowChartFlags::NOEXT, 0x0002)]
35    #[case::call_ends(FlowChartFlags::CALL_ENDS, 0x0020)]
36    #[case::nopreds(FlowChartFlags::NOPREDS, 0x0040)]
37    fn flags_pin_the_raw_sdk_values(#[case] flag: FlowChartFlags, #[case] raw: c_int) {
38        assert!(flag.bits() == raw);
39    }
40
41    #[test]
42    fn default_is_empty() {
43        assert!(FlowChartFlags::default().is_empty());
44    }
45
46    proptest! {
47        #[test]
48        fn from_bits_retain_round_trips_every_bit_pattern(raw: c_int) {
49            prop_assert_eq!(FlowChartFlags::from_bits_retain(raw).bits(), raw);
50        }
51
52        #[test]
53        fn union_and_intersection_are_raw_bitwise_ops(a: c_int, b: c_int) {
54            let (fa, fb) = (FlowChartFlags::from_bits_retain(a), FlowChartFlags::from_bits_retain(b));
55            prop_assert_eq!((fa | fb).bits(), a | b);
56            prop_assert_eq!((fa & fb).bits(), a & b);
57        }
58
59        #[test]
60        fn complement_truncates_to_the_known_flag_mask(a: c_int) {
61            let fa = FlowChartFlags::from_bits_retain(a);
62            prop_assert_eq!((!fa).bits(), !a & FlowChartFlags::all().bits());
63        }
64    }
65}