capstone_git/
constants.rs1use capstone_sys::cs_arch::*;
2use capstone_sys::cs_opt_value::*;
3use capstone_sys::*;
4use core::convert::From;
5use core::fmt::{self, Display};
6use core::str::FromStr;
7
8pub trait EnumList
10where
11 Self: Sized,
12{
13 fn variants() -> &'static [Self];
15}
16
17macro_rules! define_cs_rust_enum {
19 ( [
20 $( #[$enum_attr:meta] )*
21 => $rust_enum:ident = $cs_enum:ty
22 ]
23 $( $( #[$attr:meta] )*
24 => $rust_variant:ident = $cs_variant:tt; )* ) => {
25 $( #[$enum_attr] )*
26 #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
27 pub enum $rust_enum {
28 $(
29 $( #[$attr] )*
30 $rust_variant,
31 )*
32 }
33 }
34}
35
36macro_rules! define_cs_enum_wrapper {
40 ( [
41 $( #[$enum_attr:meta] )*
42 => $rust_enum:ident = $cs_enum:ty
43 ]
44 $( $( #[$attr:meta] )*
45 => $rust_variant:ident = $cs_variant:tt; )* ) => {
46
47 define_cs_rust_enum!(
48 [
49 $( #[$enum_attr] )*
50 => $rust_enum = $cs_enum
51 ]
52 $( $( #[$attr] )*
53 => $rust_variant = $cs_variant; )*
54 );
55
56 impl ::core::convert::From<$rust_enum> for $cs_enum {
57 fn from(other: $rust_enum) -> Self {
58 match other {
59 $(
60 $rust_enum::$rust_variant => $cs_variant,
61 )*
62 }
63 }
64 }
65
66 impl EnumList for $rust_enum {
67 fn variants() -> &'static [Self] {
68 &[
69 $(
70 $rust_enum::$rust_variant,
71 )*
72 ]
73 }
74 }
75
76 impl FromStr for $rust_enum {
77 type Err = &'static str;
78
79 fn from_str(s: &str) -> Result<Self, Self::Err> {
80 let s = s.to_lowercase();
81
82 $(
83 if s == stringify!($rust_variant).to_lowercase() {
84 return Ok($rust_enum::$rust_variant);
85 }
86 )*
87 Err(concat!("Failed to parse ", stringify!($rust_enum)))
88 }
89 }
90
91 impl Display for $rust_enum {
92 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
93 match *self {
94 $(
95 $rust_enum::$rust_variant => write!(f, "{}", stringify!($rust_variant)),
96 )*
97 }
98
99 }
100 }
101 }
102}
103
104#[macro_export]
106macro_rules! define_cs_enum_wrapper_reverse {
107 ( [
108 $( #[$enum_attr:meta] )*
109 => $rust_enum:ident = $cs_enum:ident,
110 $( from_u32 = $gen_from_u32:ident,)*
111 ]
112 $( $( #[$attr:meta] )*
113 => $rust_variant:ident = $cs_variant:tt; )* ) => {
114
115 define_cs_rust_enum!(
116 [
117 $( #[$enum_attr] )*
118 => $rust_enum = $cs_enum
119 ]
120 $( $( #[$attr] )*
121 => $rust_variant = $cs_variant; )*
122 );
123
124 impl ::core::convert::From<$cs_enum> for $rust_enum {
125 fn from(other: $cs_enum) -> Self {
126 match other {
127 $(
128 $cs_enum::$cs_variant => $rust_enum::$rust_variant,
129 )*
130 }
131 }
132 }
133
134 impl $rust_enum {
135 #[allow(dead_code)]
137 pub(crate) fn from_u32(other: u32) -> Option<$rust_enum> {
138 match other {
139 $(
140 x if x == ($cs_enum::$cs_variant as u32) => Some($rust_enum::$rust_variant),
141 )*
142 _ => None,
143 }
144 }
145 }
146 }
147}
148
149#[macro_export]
153macro_rules! define_impl_bitmask {
154 (
155 impl $struct:ident < $($impl_lifetime:lifetime),* > ;
156 $mask_getter:ident : $mask_getter_ty:ty = { $get_mask:expr }
157 test_mod = $test_mod:ident;
158 $(
159 $( #[$attr:meta] )*
160 => $getter:ident = $mask_constant:ident;
161 )*
162 ) => {
163 #[allow(clippy::redundant_closure_call)]
164 impl < $($impl_lifetime),* > $struct < $($impl_lifetime),* > {
165 pub(crate) fn $mask_getter(&self) -> $mask_getter_ty {
167 $get_mask(self)
168 }
169
170 $(
171 $( #[$attr] )*
172 pub fn $getter(&self) -> bool {
173 ($get_mask(self) & $mask_constant) != 0
174 }
175 )*
176 }
177
178 #[allow(non_snake_case)]
180 #[cfg(test)]
181 mod $test_mod {
182 use super::*;
183
184 $(
185 #[test]
186 fn $getter() {
187 assert_eq!($mask_constant.count_ones(), 1);
188 }
189 )*
190 }
191 }
192}
193
194define_cs_enum_wrapper!(
195 [
196 => Arch = cs_arch
198 ]
199 => ARM = CS_ARCH_ARM;
201 => ARM64 = CS_ARCH_ARM64;
203 => MIPS = CS_ARCH_MIPS;
205 => X86 = CS_ARCH_X86;
207 => PPC = CS_ARCH_PPC;
209 => SH = CS_ARCH_SH;
211 => SPARC = CS_ARCH_SPARC;
213 => SYSZ = CS_ARCH_SYSZ;
215 => XCORE = CS_ARCH_XCORE;
217 => M68K = CS_ARCH_M68K;
219 => MOS65XX = CS_ARCH_MOS65XX;
221 => TMS320C64X = CS_ARCH_TMS320C64X;
223 => TRICORE = CS_ARCH_TRICORE;
225 => M680X = CS_ARCH_M680X;
227 => EVM = CS_ARCH_EVM;
229 => RISCV = CS_ARCH_RISCV;
231 => BPF = CS_ARCH_BPF;
233);
234
235define_cs_enum_wrapper!(
236 [
237 => Mode = cs_mode
239 ]
240 => Arm = { cs_mode::CS_MODE_ARM };
242 => Mode16 = { cs_mode::CS_MODE_16 };
244 => Mode32 = { cs_mode::CS_MODE_32 };
246 => Mode64 = { cs_mode::CS_MODE_64 };
248 => Thumb = { cs_mode::CS_MODE_THUMB };
250 => Mips2 = { cs_mode::CS_MODE_MIPS2 };
252 => Mips3 = { cs_mode::CS_MODE_MIPS3 };
254 => Mips32R6 = { cs_mode::CS_MODE_MIPS32R6 };
256 => Mips32 = { cs_mode::CS_MODE_MIPS32 };
258 => Mips64 = { cs_mode::CS_MODE_MIPS64 };
260 => V9 = { cs_mode::CS_MODE_V9 };
262 => Qpx = { cs_mode::CS_MODE_QPX };
264 => M68k000 = { cs_mode::CS_MODE_M68K_000 };
266 => M68k010 = { cs_mode::CS_MODE_M68K_010 };
268 => M68k020 = { cs_mode::CS_MODE_M68K_020 };
270 => M68k030 = { cs_mode::CS_MODE_M68K_030 };
272 => M68k040 = { cs_mode::CS_MODE_M68K_040 };
274 => M680x6301 = { cs_mode::CS_MODE_M680X_6301 };
276 => M680x6309 = { cs_mode::CS_MODE_M680X_6309 };
278 => M680x6800 = { cs_mode::CS_MODE_M680X_6800 };
280 => M680x6801 = { cs_mode::CS_MODE_M680X_6801 };
282 => M680x6805 = { cs_mode::CS_MODE_M680X_6805 };
284 => M680x6808 = { cs_mode::CS_MODE_M680X_6808 };
286 => M680x6809 = { cs_mode::CS_MODE_M680X_6809 };
288 => M680x6811 = { cs_mode::CS_MODE_M680X_6811 };
290 => M680xCpu12 = { cs_mode::CS_MODE_M680X_CPU12 };
292 => M680xHcs08 = { cs_mode::CS_MODE_M680X_HCS08 };
294 => Mos65xx6502 = { cs_mode::CS_MODE_MOS65XX_6502 };
296 => Mos65xx65c02 = { cs_mode::CS_MODE_MOS65XX_65C02 };
298 => Mos65xxW65c02 = { cs_mode::CS_MODE_MOS65XX_W65C02 };
300 => Mos65xx65816 = { cs_mode::CS_MODE_MOS65XX_65816 };
302 => Mos65xx65816LongM = { cs_mode::CS_MODE_MOS65XX_65816_LONG_M };
304 => Mos65xx65816LongX = { cs_mode::CS_MODE_MOS65XX_65816_LONG_M };
306 => Mos65xx65816LongMx = { cs_mode::CS_MODE_MOS65XX_65816_LONG_MX };
308 => Sh2 = { cs_mode::CS_MODE_SH2 };
310 => Sh2a = { cs_mode::CS_MODE_SH2A };
312 => Sh3 = { cs_mode::CS_MODE_SH3 };
314 => Sh4 = { cs_mode::CS_MODE_SH4 };
316 => Sh4a = { cs_mode::CS_MODE_SH4A };
318 => ShFpu = { cs_mode::CS_MODE_SHFPU };
320 => ShDsp = { cs_mode::CS_MODE_SHDSP };
322 => RiscV32 = { cs_mode::CS_MODE_RISCV32 };
324 => RiscV64 = { cs_mode::CS_MODE_RISCV64 };
326 => Cbpf = { cs_mode::CS_MODE_BPF_CLASSIC };
328 => Ebpf = { cs_mode::CS_MODE_BPF_EXTENDED };
330 => TriCore110 = { cs_mode::CS_MODE_TRICORE_110 };
332 => TriCore120 = { cs_mode::CS_MODE_TRICORE_120 };
334 => TriCore130 = { cs_mode::CS_MODE_TRICORE_130 };
336 => TriCore131 = { cs_mode::CS_MODE_TRICORE_131 };
338 => TriCore160 = { cs_mode::CS_MODE_TRICORE_160 };
340 => TriCore161 = { cs_mode::CS_MODE_TRICORE_161 };
342 => TriCore162 = { cs_mode::CS_MODE_TRICORE_162 };
344 => Default = { cs_mode::CS_MODE_LITTLE_ENDIAN };
346);
347
348define_cs_enum_wrapper!(
349 [
350 => ExtraMode = cs_mode
352 ]
353 => MClass = { cs_mode::CS_MODE_MCLASS };
355 => V8 = { cs_mode::CS_MODE_V8 };
357 => Micro = { cs_mode::CS_MODE_MICRO };
359 => RiscVC = { cs_mode::CS_MODE_RISCVC };
361);
362
363define_cs_enum_wrapper!(
364 [
365 => Endian = cs_mode
367 ]
368 => Little = { cs_mode::CS_MODE_LITTLE_ENDIAN };
370 => Big = { cs_mode::CS_MODE_BIG_ENDIAN };
372);
373
374define_cs_enum_wrapper!(
375 [
376 => Syntax = cs_opt_value::Type
378 ]
379 => Intel = CS_OPT_SYNTAX_INTEL;
381 => Att = CS_OPT_SYNTAX_ATT;
383 => Masm = CS_OPT_SYNTAX_MASM;
385 => NoRegName = CS_OPT_SYNTAX_NOREGNAME;
387);
388
389pub(crate) struct OptValue(pub cs_opt_value::Type);
390
391impl From<bool> for OptValue {
392 fn from(value: bool) -> Self {
393 if value {
394 OptValue(cs_opt_value::CS_OPT_ON)
395 } else {
396 OptValue(cs_opt_value::CS_OPT_OFF)
397 }
398 }
399}
400
401#[cfg(test)]
402mod test {
403 use super::*;
404
405 #[test]
406 fn parse_arch() {
407 assert_eq!(Arch::from_str("x86"), Ok(Arch::X86));
408 assert_eq!(Arch::from_str("X86"), Ok(Arch::X86));
409 }
410}