1macro_rules! cfg_if {
10 ($(
12 if #[cfg($($meta:meta),*)] { $($it:item)* }
13 ) else * else {
14 $($it2:item)*
15 }) => {
16 cfg_if! {
17 @__items
18 () ;
19 $( ( ($($meta),*) ($($it)*) ), )*
20 ( () ($($it2)*) ),
21 }
22 };
23
24 (
26 if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
27 $(
28 else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
29 )*
30 ) => {
31 cfg_if! {
32 @__items
33 () ;
34 ( ($($i_met),*) ($($i_it)*) ),
35 $( ( ($($e_met),*) ($($e_it)*) ), )*
36 ( () () ),
37 }
38 };
39
40 (@__items ($($not:meta,)*) ; ) => {};
45 (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ),
46 $($rest:tt)*) => {
47 cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
51
52 cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
56 };
57
58 (@__apply $m:meta, $($it:item)*) => {
60 $(#[$m] $it)*
61 };
62}
63
64macro_rules! prelude {
66 () => {
67 mod types;
68
69 mod prelude {
73 #[allow(unused_imports)]
75 pub(crate) use core::clone::Clone;
76 #[allow(unused_imports)]
77 pub(crate) use core::default::Default;
78 #[allow(unused_imports)]
79 pub(crate) use core::marker::{
80 Copy,
81 Send,
82 Sync,
83 };
84 #[allow(unused_imports)]
85 pub(crate) use core::option::Option;
86 #[allow(unused_imports)]
87 pub(crate) use core::prelude::v1::derive;
88 #[allow(unused_imports)]
89 pub(crate) use core::{
90 assert,
91 cfg,
92 debug_assert,
93 fmt,
94 hash,
95 iter,
96 mem,
97 ptr,
98 };
99
100 #[allow(unused_imports)]
101 pub(crate) use fmt::Debug;
102 #[allow(unused_imports)]
103 pub(crate) use mem::{
104 align_of,
105 align_of_val,
106 size_of,
107 size_of_val,
108 };
109
110 #[allow(unused_imports)]
111 #[cfg(any(target_os = "linux", target_os = "android", target_os = "l4re"))]
112 pub(crate) use crate::types::u32_cast_ioctl;
113 #[allow(unused_imports)]
114 pub(crate) use crate::types::{
115 replace_array_items,
116 u16_cast_short,
117 u32_cast_int,
118 u32_cast_long,
119 u8_slice_cast_char_slice,
120 ulong_cast_int,
121 ulong_cast_uint,
122 CEnumRepr,
123 Padding,
124 };
125 #[allow(unused_imports)]
127 pub(crate) use crate::{
128 c_char,
129 c_double,
130 c_float,
131 c_int,
132 c_long,
133 c_longlong,
134 c_short,
135 c_uchar,
136 c_uint,
137 c_ulong,
138 c_ulonglong,
139 c_ushort,
140 c_void,
141 intptr_t,
142 size_t,
143 ssize_t,
144 uintptr_t,
145 };
146 }
147 };
148}
149
150macro_rules! s {
158 ($(
159 $(#[$attr:meta])*
160 $pub:vis $t:ident $i:ident { $($field:tt)* }
161 )*) => ($(
162 s!(it: $(#[$attr])* $pub $t $i { $($field)* });
163 )*);
164
165 (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => (
166 compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead");
167 );
168
169 (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => (
170 #[repr(C)]
171 #[::core::prelude::v1::derive(
172 ::core::clone::Clone,
173 ::core::marker::Copy,
174 ::core::fmt::Debug,
175 )]
176 #[cfg_attr(
177 feature = "extra_traits",
178 ::core::prelude::v1::derive(PartialEq, Eq, Hash)
179 )]
180 #[allow(deprecated)]
181 $(#[$attr])*
182 $pub struct $i { $($field)* }
183 );
184}
185
186macro_rules! s_paren {
192 ($(
193 $(#[$attr:meta])*
194 $pub:vis struct $i:ident ( $($field:tt)* );
195 )*) => ($(
196 #[::core::prelude::v1::derive(
197 ::core::clone::Clone,
198 ::core::marker::Copy,
199 ::core::fmt::Debug,
200 )]
201 #[cfg_attr(
202 feature = "extra_traits",
203 ::core::prelude::v1::derive(PartialEq, Eq, Hash)
204 )]
205 $(#[$attr])*
206 $pub struct $i ( $($field)* );
207 )*);
208}
209
210macro_rules! s_no_extra_traits {
217 ($(
218 $(#[$attr:meta])*
219 $pub:vis $t:ident $i:ident { $($field:tt)* }
220 )*) => ($(
221 s_no_extra_traits!(it: $(#[$attr])* $pub $t $i { $($field)* });
222 )*);
223
224 (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => (
225 #[repr(C)]
226 #[::core::prelude::v1::derive(
227 ::core::clone::Clone,
228 ::core::marker::Copy,
229 )]
230 $(#[$attr])*
231 $pub union $i { $($field)* }
232
233 impl ::core::fmt::Debug for $i {
234 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
235 f.debug_struct(::core::stringify!($i)).finish_non_exhaustive()
236 }
237 }
238 );
239
240 (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => (
241 #[repr(C)]
242 #[::core::prelude::v1::derive(
243 ::core::clone::Clone,
244 ::core::marker::Copy,
245 ::core::fmt::Debug,
246 )]
247 $(#[$attr])*
248 $pub struct $i { $($field)* }
249 );
250}
251
252macro_rules! extern_ty {
259 ($(
260 $(#[$attr:meta])*
261 $vis:vis type $i:ident;
262 )*) => ($(
263 $(#[$attr])*
264 #[::core::prelude::v1::derive(
282 ::core::clone::Clone,
283 ::core::marker::Copy,
284 ::core::fmt::Debug,
285 )]
286 #[repr(C)]
287 $vis struct $i {
288 _data: (),
289 _marker: ::core::marker::PhantomData<(*mut u8, ::core::marker::PhantomPinned)>,
290 }
291 )*);
292}
293
294macro_rules! e {
298 ($(
299 $(#[$attr:meta])*
300 pub enum $i:ident { $($field:tt)* }
301 )*) => ($(
302 #[cfg_attr(
303 feature = "extra_traits",
304 ::core::prelude::v1::derive(Eq, Hash, PartialEq)
305 )]
306 #[::core::prelude::v1::derive(
307 ::core::clone::Clone,
308 ::core::marker::Copy,
309 ::core::fmt::Debug,
310 )]
311 $(#[$attr])*
312 pub enum $i { $($field)* }
313 )*);
314}
315
316macro_rules! c_enum {
326 ($(
328 $(#[repr($repr:ty)])?
329 $vis:vis enum $($ty_name:ident)? $(#$anon:ident)? {
330 $($field_vis:vis $variant:ident $(= $value:expr)?,)+
331 }
332 )+) => {
333 $(c_enum!(@single;
334 $(#[repr($repr)])?
335 $vis enum $($ty_name)? $(#$anon)? {
336 $($field_vis $variant $(= $value)?,)+
337 }
338 );)+
339 };
340
341 (@single;
343 $(#[repr($repr:ty)])?
344 $vis:vis enum $ty_name:ident {
345 $($field_vis:vis $variant:ident $(= $value:expr)?,)+
346 }
347 ) => {
348 $vis type $ty_name = c_enum!(@ty $($repr)?);
349 c_enum! {
350 @variant;
351 ty: $ty_name;
352 default: 0;
353 variants: [$($field_vis $variant $(= $value)?,)+]
354 }
355 };
356
357 (@single;
359 $(#[repr($repr:ty)])?
360 $vis:vis enum #anon {
361 $($field_vis:vis $variant:ident $(= $value:expr)?,)+
362 }
363 ) => {
364 c_enum! {
365 @variant;
366 ty: c_enum!(@ty $($repr)?);
367 default: 0;
368 variants: [$($field_vis $variant $(= $value)?,)+]
369 }
370 };
371
372 (@variant; ty: $_ty_name:ty; default: $_idx:expr; variants: []) => { };
374 (
375 @variant;
376 ty: $ty_name:ty;
377 default: $default_val:expr;
378 variants: [
379 $field_vis:vis $variant:ident $(= $value:expr)?,
380 $($tail:tt)*
381 ]
382 ) => {
383 $field_vis const $variant: $ty_name = {
384 #[allow(unused_variables)]
385 let r = $default_val;
386 $(let r = $value;)?
387 r
388 };
389
390 c_enum! {
393 @variant;
394 ty: $ty_name;
395 default: $variant + 1;
396 variants: [$($tail)*]
397 }
398 };
399
400 (@ty $repr:ty) => { $repr };
402 (@ty) => { $crate::prelude::CEnumRepr };
403}
404
405macro_rules! f {
407 ($(
408 $(#[$attr:meta])*
409 pub $(const $($const_dummy:literal)?)? unsafe
410 fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty
411 $body:block
412 )+) => {$(
413 #[inline]
414 $(#[$attr])*
415 pub $(const $($const_dummy)?)? unsafe extern "C"
416 fn $i ($($arg: $argty),*) -> $ret
417 $body
418 )+};
419}
420
421macro_rules! safe_f {
423 ($(
424 $(#[$attr:meta])*
425 pub $(const $($const_dummy:literal)?)? safe
426 fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty
427 $body:block
428 )+) => {$(
429 #[inline]
430 $(#[$attr])*
431 pub $(const $($const_dummy)?)? extern "C"
432 fn $i ($($arg: $argty),*) -> $ret
433 $body
434 )+};
435}
436
437macro_rules! deprecated_mach {
439 (pub const $id:ident: $ty:ty = $expr:expr;) => {
440 #[deprecated(
441 since = "0.2.55",
442 note = "Use the `mach2` crate instead",
443 )]
444 #[allow(deprecated)]
445 pub const $id: $ty = $expr;
446 };
447 ($(pub const $id:ident: $ty:ty = $expr:expr;)*) => {
448 $(
449 deprecated_mach!(
450 pub const $id: $ty = $expr;
451 );
452 )*
453 };
454 (pub type $id:ident = $ty:ty;) => {
455 #[deprecated(
456 since = "0.2.55",
457 note = "Use the `mach2` crate instead",
458 )]
459 #[allow(deprecated)]
460 pub type $id = $ty;
461 };
462 ($(pub type $id:ident = $ty:ty;)*) => {
463 $(
464 deprecated_mach!(
465 pub type $id = $ty;
466 );
467 )*
468 }
469}
470
471macro_rules! offset_of {
474 ($Ty:path, $field:ident) => {{
475 #[allow(clippy::unneeded_wildcard_pattern)]
477 let $Ty { $field: _, .. };
478 let data = core::mem::MaybeUninit::<$Ty>::uninit();
479 let ptr = data.as_ptr();
480 #[allow(unused_unsafe)]
482 let fptr = unsafe { core::ptr::addr_of!((*ptr).$field) };
484 let off = (fptr as usize).checked_sub(ptr as usize).unwrap();
485 core::assert!(off <= core::mem::size_of::<$Ty>());
486 off
487 }};
488}
489
490#[cfg(test)]
491mod tests {
492 use core::any::TypeId;
493
494 use crate::types::CEnumRepr;
495
496 #[test]
497 fn c_enum_basic() {
498 c_enum! {
500 pub enum e {
501 VAR0,
502 VAR1,
503 VAR2,
504 }
505
506 pub enum #anon {
508 ANON0,
509 ANON1,
510 ANON2,
511 }
512
513 enum #anon {
515 ANON3,
516 ANON4,
517 ANON5,
518 }
519 }
520
521 assert_eq!(TypeId::of::<e>(), TypeId::of::<CEnumRepr>());
522 assert_eq!(VAR0, 0 as CEnumRepr);
523 assert_eq!(VAR1, 1 as CEnumRepr);
524 assert_eq!(VAR2, 2 as CEnumRepr);
525
526 assert_eq!(type_id_of_val(&ANON0), TypeId::of::<CEnumRepr>());
527 assert_eq!(ANON0, 0 as CEnumRepr);
528 assert_eq!(ANON1, 1 as CEnumRepr);
529 assert_eq!(ANON2, 2 as CEnumRepr);
530
531 assert_eq!(type_id_of_val(&ANON3), TypeId::of::<CEnumRepr>());
532 assert_eq!(ANON3, 0 as CEnumRepr);
533 assert_eq!(ANON4, 1 as CEnumRepr);
534 assert_eq!(ANON5, 2 as CEnumRepr);
535 }
536
537 #[test]
538 fn c_enum_repr() {
539 c_enum! {
541 #[repr(u16)]
542 pub enum e {
543 VAR0,
544 }
545
546 #[repr(u16)]
547 pub enum #anon {
548 ANON0,
549 }
550 }
551
552 assert_eq!(TypeId::of::<e>(), TypeId::of::<u16>());
553 assert_eq!(VAR0, 0_u16);
554
555 assert_eq!(type_id_of_val(&ANON0), TypeId::of::<u16>());
556 assert_eq!(ANON0, 0_u16);
557 }
558
559 #[test]
560 fn c_enum_set_value() {
561 c_enum! {
563 pub enum e {
564 VAR2 = 2,
565 VAR3,
566 VAR4,
567 }
568 }
569
570 assert_eq!(VAR2, 2 as CEnumRepr);
571 assert_eq!(VAR3, 3 as CEnumRepr);
572 assert_eq!(VAR4, 4 as CEnumRepr);
573 }
574
575 #[test]
576 fn c_enum_multiple_set_value() {
577 c_enum! {
580 pub enum e {
581 VAR0,
582 VAR2_0 = 2,
583 VAR3_0,
584 VAR4_0,
585 VAR2_1 = 2,
586 VAR3_1,
587 VAR4_1,
588 }
589 }
590
591 assert_eq!(VAR0, 0 as CEnumRepr);
592 assert_eq!(VAR2_0, 2 as CEnumRepr);
593 assert_eq!(VAR3_0, 3 as CEnumRepr);
594 assert_eq!(VAR4_0, 4 as CEnumRepr);
595 assert_eq!(VAR2_1, 2 as CEnumRepr);
596 assert_eq!(VAR3_1, 3 as CEnumRepr);
597 assert_eq!(VAR4_1, 4 as CEnumRepr);
598 }
599
600 #[test]
601 fn c_enum_vis() {
602 mod priv1 {
603 c_enum! {
604 #[repr(u8)]
605 pub enum e1 {
606 PRIV_ON_1 = 10,
607 pub PUB1 = PRIV_ON_1 * 2,
609 }
610 }
611 }
612 mod priv2 {
613 c_enum! {
614 #[repr(u16)]
615 pub enum e2 {
616 pub PRIV_ON_1 = 42,
617 pub PUB2 = PRIV_ON_1 * 2,
618 }
619 }
620 }
621
622 use priv1::*;
623 use priv2::*;
624
625 assert_eq!(TypeId::of::<e1>(), TypeId::of::<u8>());
626 assert_eq!(TypeId::of::<e2>(), TypeId::of::<u16>());
627 assert_eq!(PUB1, 10u8 * 2);
628 assert_eq!(PUB2, 42u16 * 2);
629 assert_eq!(PRIV_ON_1, 42u16);
632 }
633
634 fn type_id_of_val<T: 'static>(_: &T) -> TypeId {
635 TypeId::of::<T>()
636 }
637
638 #[test]
639 fn test_offset_of() {
640 #[repr(C)]
641 struct Off1 {
642 a: u8,
643 b: u32,
644 c: Off2,
645 d: u64,
646 }
647
648 #[repr(C)]
649 #[repr(align(128))]
650 struct Off2 {}
651
652 assert_eq!(core::mem::offset_of!(Off1, a), offset_of!(Off1, a));
653 assert_eq!(core::mem::offset_of!(Off1, b), offset_of!(Off1, b));
654 assert_eq!(core::mem::offset_of!(Off1, c), offset_of!(Off1, c));
655 assert_eq!(core::mem::offset_of!(Off1, d), offset_of!(Off1, d));
656 }
657}
658
659#[cfg(test)]
660#[allow(unused)]
661mod macro_checks {
662 s! {
663 pub struct S1 {
664 pub a: u32,
665 b: u32,
666 }
667
668 struct S1Priv {
669 pub a: u32,
670 b: u32,
671 }
672 }
673
674 s_no_extra_traits! {
675 pub struct S2 {
676 pub a: u32,
677 b: u32,
678 }
679
680 struct S2Priv {
681 pub a: u32,
682 b: u32,
683 }
684
685 pub union U2 {
686 pub a: u32,
687 b: f32,
688 }
689
690 union U2Priv {
691 pub a: u32,
692 b: f32,
693 }
694 }
695
696 extern_ty! {
697 type Foo;
698 pub type Bar;
699 }
700}