1macro_rules! cfg_if {
9 ($(
11 if #[cfg($($meta:meta),*)] { $($it:item)* }
12 ) else * else {
13 $($it2:item)*
14 }) => {
15 cfg_if! {
16 @__items
17 () ;
18 $( ( ($($meta),*) ($($it)*) ), )*
19 ( () ($($it2)*) ),
20 }
21 };
22
23 (
25 if #[cfg($($i_met:meta),*)] { $($i_it:item)* }
26 $(
27 else if #[cfg($($e_met:meta),*)] { $($e_it:item)* }
28 )*
29 ) => {
30 cfg_if! {
31 @__items
32 () ;
33 ( ($($i_met),*) ($($i_it)*) ),
34 $( ( ($($e_met),*) ($($e_it)*) ), )*
35 ( () () ),
36 }
37 };
38
39 (@__items ($($not:meta,)*) ; ) => {};
44 (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ),
45 $($rest:tt)*) => {
46 cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
50
51 cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
55 };
56
57 (@__apply $m:meta, $($it:item)*) => {
59 $(#[$m] $it)*
60 };
61}
62
63macro_rules! prelude {
65 () => {
66 mod types;
67
68 mod prelude {
72 #[allow(unused_imports)]
74 pub(crate) use core::clone::Clone;
75 #[allow(unused_imports)]
76 pub(crate) use core::cmp::{
77 Eq,
78 PartialEq,
79 };
80 #[allow(unused_imports)]
81 pub(crate) use core::default::Default;
82 #[allow(unused_imports)]
83 pub(crate) use core::iter::Iterator;
84 #[allow(unused_imports)]
85 pub(crate) use core::marker::{
86 Copy,
87 Send,
88 Sync,
89 };
90 #[allow(unused_imports)]
91 pub(crate) use core::option::Option::{
92 self,
93 None,
94 Some,
95 };
96 #[allow(unused_imports)]
97 pub(crate) use core::prelude::v1::derive;
98 #[allow(unused_imports)]
99 pub(crate) use core::{
100 assert,
101 cfg,
102 compile_error,
103 debug_assert,
104 fmt,
105 hash,
106 iter,
107 mem,
108 panic,
109 ptr,
110 unimplemented,
111 };
112
113 #[allow(unused_imports)]
114 pub(crate) use fmt::Debug;
115 #[allow(unused_imports)]
116 pub(crate) use mem::{
117 align_of,
118 align_of_val,
119 size_of,
120 size_of_val,
121 };
122
123 #[allow(unused_imports)]
124 #[cfg(any(target_os = "linux", target_os = "android", target_os = "l4re"))]
125 pub(crate) use crate::types::u32_cast_ioctl;
126 #[allow(unused_imports)]
127 pub(crate) use crate::types::{
128 cstr,
129 replace_array_items,
130 u16_cast_short,
131 u32_cast_int,
132 u32_cast_long,
133 u8_slice_cast_char_slice,
134 ulong_cast_int,
135 ulong_cast_uint,
136 CEnumRepr,
137 Padding,
138 };
139 #[allow(unused_imports)]
141 pub(crate) use crate::{
142 c_char,
143 c_double,
144 c_float,
145 c_int,
146 c_long,
147 c_longlong,
148 c_short,
149 c_uchar,
150 c_uint,
151 c_ulong,
152 c_ulonglong,
153 c_ushort,
154 c_void,
155 intptr_t,
156 size_t,
157 ssize_t,
158 uintptr_t,
159 };
160 }
161 };
162}
163
164macro_rules! s {
172 ($(
173 $(#[$attr:meta])*
174 $pub:vis $t:ident $i:ident { $($field:tt)* }
175 )*) => ($(
176 s!(it: $(#[$attr])* $pub $t $i { $($field)* });
177 )*);
178
179 (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => (
180 compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead");
181 );
182
183 (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => (
184 #[repr(C)]
185 #[::core::prelude::v1::derive(
186 ::core::clone::Clone,
187 ::core::marker::Copy,
188 ::core::fmt::Debug,
189 )]
190 #[cfg_attr(
191 feature = "extra_traits",
192 ::core::prelude::v1::derive(
193 ::core::cmp::PartialEq,
194 ::core::cmp::Eq,
195 ::core::hash::Hash,
196 )
197 )]
198 #[allow(deprecated)]
199 $(#[$attr])*
200 $pub struct $i { $($field)* }
201 );
202}
203
204macro_rules! s_paren {
210 ($(
211 $(#[$attr:meta])*
212 $pub:vis struct $i:ident ( $($field:tt)* );
213 )*) => ($(
214 #[::core::prelude::v1::derive(
215 ::core::clone::Clone,
216 ::core::marker::Copy,
217 ::core::fmt::Debug,
218 )]
219 #[cfg_attr(
220 feature = "extra_traits",
221 ::core::prelude::v1::derive(
222 ::core::cmp::PartialEq,
223 ::core::cmp::Eq,
224 ::core::hash::Hash,
225 )
226 )]
227 $(#[$attr])*
228 $pub struct $i ( $($field)* );
229 )*);
230}
231
232macro_rules! s_no_extra_traits {
239 ($(
240 $(#$attr:tt)*
241 $pub:vis $t:ident $i:ident { $($field:tt)* }
242 )*) => ($(
243 s_no_extra_traits!(it: $(#$attr)* $pub $t $i { $($field)* });
244 )*);
245
246 (it: $(#$attr:tt)* $pub:vis union $i:ident { $($field:tt)* }) => (
247 union_with_debug! {
248 $(#$attr)* $pub union $i { $($field)* }
249 }
250 );
251
252 (it: $(#$attr:tt)* $pub:vis struct $i:ident { $($field:tt)* }) => (
253 #[repr(C)]
254 #[::core::prelude::v1::derive(
255 ::core::clone::Clone,
256 ::core::marker::Copy,
257 ::core::fmt::Debug,
258 )]
259 $(#$attr)*
260 $pub struct $i { $($field)* }
261 );
262}
263
264macro_rules! s2 {
282 ($(
283 $(#$attr:tt)*
284 $pub:vis $t:ident $i:ident { $($field:tt)* }
285 )*) => ($(
286 s2!(it: $(#$attr)* $pub $t $i { $($field)* });
287 )*);
288
289 (it: $(#$attr:tt)* $pub:vis union $i:ident { $($field:tt)* }) => (
290 compile_error!(
291 "unions cannot derive extra traits, use `s_no_extra_traits2` \
292 instead"
293 );
294 );
295
296 (it: $(#$attr:tt)* $pub:vis struct $i:ident { $($field:tt)* }) => (
297 custom_struct! {
298 attrs: {
299 #[repr(C)]
300 #[::core::prelude::v1::derive(
301 ::core::clone::Clone,
302 ::core::marker::Copy,
303 ::core::fmt::Debug,
304 )]
305 #[cfg_attr(
306 feature = "extra_traits",
307 ::core::prelude::v1::derive(
308 ::core::cmp::PartialEq,
309 ::core::cmp::Eq,
310 ::core::hash::Hash,
311 )
312 )]
313 #[allow(deprecated)]
314 }
315 $(#$attr)* $pub struct $i { $($field)* }
316 }
317 );
318}
319
320macro_rules! s_no_extra_traits2 {
339 ($(
340 $(#$attr:tt)*
341 $pub:vis $t:ident $i:ident { $($field:tt)* }
342 )*) => ($(
343 s_no_extra_traits2!(it: $(#$attr)* $pub $t $i { $($field)* });
344 )*);
345
346 (it: $(#$attr:tt)* $pub:vis union $i:ident { $($field:tt)* }) => (
347 union_with_debug! {
348 $(#$attr)* $pub union $i { $($field)* }
349 }
350 );
351
352 (it: $(#$attr:tt)* $pub:vis struct $i:ident { $($field:tt)* }) => (
353 custom_struct! {
354 attrs: {
355 #[repr(C)]
356 #[::core::prelude::v1::derive(
357 ::core::clone::Clone,
358 ::core::marker::Copy,
359 ::core::fmt::Debug,
360 )]
361 }
362 $(#$attr)* $pub struct $i { $($field)* }
363 }
364 );
365}
366
367macro_rules! union_with_debug {
373 (
374 $(#$attr:tt)*
375 $vis:vis union $name:ident { $($body:tt)* }
376 ) => {
377 union_with_debug! {
378 @split_attrs,
379 cfg_attrs: { },
380 other_attrs: { },
381 remaining_attrs: { $(#$attr)* },
382 found_default_via_unsafe_zeroed: false,
383 vis: $vis,
384 name: $name,
385 body: { $($body)* },
386 }
387 };
388
389 (
391 @split_attrs,
392 cfg_attrs: { $($cfg_attrs:tt)* },
393 other_attrs: { $($other_attrs:tt)* },
394 remaining_attrs: {
395 #[cfg($($cfg:tt)*)]
396 $($tail:tt)*
397 },
398 found_default_via_unsafe_zeroed: $found_default:tt,
399 vis: $vis:vis,
400 name: $name:ident,
401 body: { $($body:tt)* },
402 ) => {
403 union_with_debug! {
404 @split_attrs,
405 cfg_attrs: { $($cfg_attrs)* #[cfg($($cfg)*)] },
406 other_attrs: { $($other_attrs)* },
407 remaining_attrs: { $($tail)* },
408 found_default_via_unsafe_zeroed: $found_default,
409 vis: $vis,
410 name: $name,
411 body: { $($body)* },
412 }
413 };
414
415 (
417 @split_attrs,
418 cfg_attrs: { $($cfg_attrs:tt)* },
419 other_attrs: { $($other_attrs:tt)* },
420 remaining_attrs: {
421 #[unsafe(union_default_via_zeroed)]
422 $($tail:tt)*
423 },
424 found_default_via_unsafe_zeroed: $found_default:tt,
425 vis: $vis:vis,
426 name: $name:ident,
427 body: { $($body:tt)* },
428 ) => {
429 union_with_debug! {
430 @split_attrs,
431 cfg_attrs: { $($cfg_attrs)* },
432 other_attrs: { $($other_attrs)* },
433 remaining_attrs: { $($tail)* },
434 found_default_via_unsafe_zeroed: true,
435 vis: $vis,
436 name: $name,
437 body: { $($body)* },
438 }
439 };
440
441 (
443 @split_attrs,
444 cfg_attrs: { $($cfg_attrs:tt)* },
445 other_attrs: { $($other_attrs:tt)* },
446 remaining_attrs: {
447 #$other:tt
448 $($tail:tt)*
449 },
450 found_default_via_unsafe_zeroed: $found_default:tt,
451 vis: $vis:vis,
452 name: $name:ident,
453 body: { $($body:tt)* },
454 ) => {
455 union_with_debug! {
456 @split_attrs,
457 cfg_attrs: { $($cfg_attrs)* },
458 other_attrs: { $($other_attrs)* #$other },
459 remaining_attrs: { $($tail)* },
460 found_default_via_unsafe_zeroed: $found_default,
461 vis: $vis,
462 name: $name,
463 body: { $($body)* },
464 }
465 };
466
467 (
469 @split_attrs,
470 cfg_attrs: { $($cfg_attrs:tt)* },
471 other_attrs: { $($other_attrs:tt)* },
472 remaining_attrs: { },
473 found_default_via_unsafe_zeroed: $found_default:tt,
474 vis: $vis:vis,
475 name: $name:ident,
476 body: { $($body:tt)* },
477 ) => {
478 #[repr(C)]
479 #[::core::prelude::v1::derive(
480 ::core::clone::Clone,
481 ::core::marker::Copy,
482 )]
483 $($other_attrs)*
484 $($cfg_attrs)*
485 $vis union $name { $($body)* }
486
487 $($cfg_attrs)*
488 #[allow(deprecated)]
489 impl ::core::fmt::Debug for $name {
490 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
491 f.debug_struct(::core::stringify!($name)).finish_non_exhaustive()
492 }
493 }
494
495 emit_union_default_via_unsafe_zeroed! {
496 found_default_via_unsafe_zeroed: $found_default,
497 cfg_attrs: { $($cfg_attrs)* },
498 name: $name,
499 }
500 };
501}
502
503macro_rules! emit_union_default_via_unsafe_zeroed {
505 (
506 found_default_via_unsafe_zeroed: false,
507 cfg_attrs: { $($cfg_attrs:tt)* },
508 name: $name:ident,
509 ) => {
510 };
511
512 (
513 found_default_via_unsafe_zeroed: true,
514 cfg_attrs: { $($cfg_attrs:tt)* },
515 name: $name:ident,
516 ) => {
517 $($cfg_attrs)*
518 impl ::core::default::Default for $name {
519 fn default() -> Self {
520 unsafe { ::core::mem::zeroed() }
521 }
522 }
523 };
524}
525
526macro_rules! custom_struct {
548 (
551 attrs: { $($attrs:tt)* }
552 $(#$attr:tt)*
553 $vis:vis struct $name:ident { $($body:tt)* }
554 ) => {
555 custom_struct! {
556 @split_attrs,
557 cfg_attrs: { },
558 other_attrs: { },
559 remaining_attrs: { $($attrs)* $(#$attr)* },
560 found_exhaustive_attr: false,
561 vis: $vis,
562 name: $name,
563 body: { $($body)* },
564 }
565 };
566
567 (
569 @split_attrs,
570 cfg_attrs: { $($cfg_attrs:tt)* },
571 other_attrs: { $($other_attrs:tt)* },
572 remaining_attrs: {
573 #[cfg($($cfg:tt)*)]
574 $($tail:tt)*
575 },
576 found_exhaustive_attr: $found_exhaustive:tt,
577 vis: $vis:vis,
578 name: $name:ident,
579 body: { $($body:tt)* },
580 ) => {
581 custom_struct! {
582 @split_attrs,
583 cfg_attrs: { $($cfg_attrs)* #[cfg($($cfg)*)] },
584 other_attrs: { $($other_attrs)* },
585 remaining_attrs: { $($tail)* },
586 found_exhaustive_attr: $found_exhaustive,
587 vis: $vis,
588 name: $name,
589 body: { $($body)* },
590 }
591 };
592
593 (
596 @split_attrs,
597 cfg_attrs: { $($cfg_attrs:tt)* },
598 other_attrs: { $($other_attrs:tt)* },
599 remaining_attrs: {
600 #[exhaustive]
601 $($tail:tt)*
602 },
603 found_exhaustive_attr: $_:tt,
604 vis: $vis:vis,
605 name: $name:ident,
606 body: { $($body:tt)* },
607 ) => {
608 custom_struct! {
609 @split_attrs,
610 cfg_attrs: { $($cfg_attrs)* },
611 other_attrs: { $($other_attrs)* },
612 remaining_attrs: { $($tail)* },
613 found_exhaustive_attr: true,
614 vis: $vis,
615 name: $name,
616 body: { $($body)* },
617 }
618 };
619
620 (
622 @split_attrs,
623 cfg_attrs: { $($cfg_attrs:tt)* },
624 other_attrs: { $($other_attrs:tt)* },
625 remaining_attrs: {
626 #$other:tt
627 $($tail:tt)*
628 },
629 found_exhaustive_attr: $found_exhaustive:tt,
630 vis: $vis:vis,
631 name: $name:ident,
632 body: { $($body:tt)* },
633 ) => {
634 custom_struct! {
635 @split_attrs,
636 cfg_attrs: { $($cfg_attrs)* },
637 other_attrs: { $($other_attrs)* #$other },
638 remaining_attrs: { $($tail)* },
639 found_exhaustive_attr: $found_exhaustive,
640 vis: $vis,
641 name: $name,
642 body: { $($body)* },
643 }
644 };
645
646 (
648 @split_attrs,
649 cfg_attrs: { $($cfg_attrs:tt)* },
650 other_attrs: { $($other_attrs:tt)* },
651 remaining_attrs: { },
652 found_exhaustive_attr: $found_exhaustive:tt,
653 vis: $vis:vis,
654 name: $name:ident,
655 body: { $($body:tt)* },
656 ) => {
657 custom_struct! {
658 @struct,
659 cfg_attrs: { $($cfg_attrs)* },
660 other_attrs: { $($other_attrs)* },
661 found_exhaustive_attr: $found_exhaustive,
662 vis: $vis,
663 name: $name,
664 processed_fields: { },
665 processed_field_defaults: { },
666 remaining_fields: { $($body)* },
667 }
668 };
669
670 (
672 @struct,
673 cfg_attrs: { $($cfg_attrs:tt)* },
674 other_attrs: { $($other_attrs:tt)* },
675 found_exhaustive_attr: $found_exhaustive:tt,
676 vis: $vis:vis,
677 name: $name:ident,
678 processed_fields: { $($processed_fields:tt)* },
679 processed_field_defaults: { $($processed_field_defaults:tt)* },
680 remaining_fields: {
681 #[custom_default($default:expr)]
682 $(#[$fattr:meta])*
683 $fvis:vis $fname:ident: $fty:ty,
684 $($tail:tt)*
685 },
686 ) => {
687 custom_struct! {
688 @struct,
689 cfg_attrs: { $($cfg_attrs)* },
690 other_attrs: { $($other_attrs)* },
691 found_exhaustive_attr: $found_exhaustive,
692 vis: $vis,
693 name: $name,
694 processed_fields: { $($processed_fields)* $(#[$fattr])* $fvis $fname: $fty, },
695 processed_field_defaults: {
696 $($processed_field_defaults)*
697 $(#[$fattr])* $fname: $default,
698 },
699 remaining_fields: { $($tail)* },
700 }
701 };
702
703 (
705 @struct,
706 cfg_attrs: { $($cfg_attrs:tt)* },
707 other_attrs: { $($other_attrs:tt)* },
708 found_exhaustive_attr: $found_exhaustive:tt,
709 vis: $vis:vis,
710 name: $name:ident,
711 processed_fields: { $($processed_fields:tt)* },
712 processed_field_defaults: { $($processed_field_defaults:tt)* },
713 remaining_fields: {
714 $(#[$fattr:meta])*
715 $fvis:vis $fname:ident: $fty:ty,
716 $($tail:tt)*
717 },
718 ) => {
719 custom_struct! {
720 @struct,
721 cfg_attrs: { $($cfg_attrs)* },
722 other_attrs: { $($other_attrs)* },
723 found_exhaustive_attr: $found_exhaustive,
724 vis: $vis,
725 name: $name,
726 processed_fields: { $($processed_fields)* $(#[$fattr])* $fvis $fname: $fty, },
727 processed_field_defaults: {
728 $($processed_field_defaults)*
729 $(#[$fattr])* $fname: ::core::default::Default::default(),
730 },
731 remaining_fields: { $($tail)* },
732 }
733 };
734
735 (
737 @struct,
738 cfg_attrs: { $($cfg_attrs:tt)* },
739 other_attrs: { $($other_attrs:tt)* },
740 found_exhaustive_attr: $found_exhaustive:tt,
741 vis: $vis:vis,
742 name: $name:ident,
743 processed_fields: { $($processed_fields:tt)* },
744 processed_field_defaults: { $($processed_field_defaults:tt)* },
745 remaining_fields: { },
746 ) => {
747 emit_struct_definition! {
748 found_exhaustive_attr: $found_exhaustive,
749 body: {
750 $($other_attrs)*
751 $($cfg_attrs)*
752 $vis $name { $($processed_fields)* }
753 }
754 }
755
756 $($cfg_attrs)*
757 #[allow(deprecated)]
760 impl ::core::default::Default for $name {
761 #[allow(unused_doc_comments)]
765 fn default() -> Self {
766 emit_struct_default_body! {
767 found_exhaustive_attr: $found_exhaustive,
768 body: { $($processed_field_defaults)* }
769 }
770 }
771 }
772 };
773}
774
775macro_rules! emit_struct_definition {
778 (
779 found_exhaustive_attr: false,
780 body: { $(#[$attr:meta])* $vis:vis $name:ident { $($field:tt)* } }
781 ) => {
782 #[allow(clippy::manual_non_exhaustive)]
783 $(#[$attr])*
784 $vis struct $name { $($field)* __non_exhaustive: () }
785 };
786
787 (
788 found_exhaustive_attr: true,
789 body: { $(#[$attr:meta])* $vis:vis $name:ident { $($field:tt)* } }
790 ) => {
791 $(#[$attr])*
792 $vis struct $name { $($field)* }
793 };
794}
795
796macro_rules! emit_struct_default_body {
799 (
800 found_exhaustive_attr: false,
801 body: { $($field_default:tt)* }
802 ) => {
803 Self { $($field_default)* __non_exhaustive: () }
804 };
805
806 (
807 found_exhaustive_attr: true,
808 body: { $($field_default:tt)* }
809 ) => {
810 Self { $($field_default)* }
811 };
812}
813
814macro_rules! extern_ty {
820 ($(
821 $(#[$attr:meta])*
822 $vis:vis type $i:ident;
823 )*) => ($(
824 $(#[$attr])*
825 #[::core::prelude::v1::derive(
843 ::core::clone::Clone,
844 ::core::marker::Copy,
845 ::core::fmt::Debug,
846 )]
847 #[repr(C)]
848 $vis struct $i {
849 _data: (),
850 _marker: ::core::marker::PhantomData<(*mut u8, ::core::marker::PhantomPinned)>,
851 }
852 )*);
853}
854
855macro_rules! e {
859 ($(
860 $(#[$attr:meta])*
861 pub enum $i:ident { $($field:tt)* }
862 )*) => ($(
863 #[cfg_attr(
864 feature = "extra_traits",
865 ::core::prelude::v1::derive(Eq, Hash, PartialEq)
866 )]
867 #[::core::prelude::v1::derive(
868 ::core::clone::Clone,
869 ::core::marker::Copy,
870 ::core::fmt::Debug,
871 )]
872 $(#[$attr])*
873 pub enum $i { $($field)* }
874 )*);
875}
876
877macro_rules! c_enum {
887 ($(
889 $(#[repr($repr:ty)])?
890 $vis:vis enum $($ty_name:ident)? $(#$anon:ident)? {
891 $(
892 $(#[$meta:meta])*
893 $field_vis:vis $variant:ident $(= $value:expr)?,
894 )+
895 }
896 )+) => {
897 $(c_enum!(@single;
898 $(#[repr($repr)])?
899 $vis enum $($ty_name)? $(#$anon)? {
900 $(
901 $(#[$meta])*
902 $field_vis $variant $(= $value)?,
903 )+
904 }
905 );)+
906 };
907
908 (@single;
910 $(#[repr($repr:ty)])?
911 $vis:vis enum $ty_name:ident {
912 $(
913 $(#[$meta:meta])*
914 $field_vis:vis $variant:ident $(= $value:expr)?,
915 )+
916 }
917 ) => {
918 $vis type $ty_name = c_enum!(@ty $($repr)?);
919 c_enum! {
920 @variant;
921 ty: $ty_name;
922 default: 0;
923 variants: [$(
924 $(#[$meta])*
925 $field_vis $variant $(= $value)?,
926 )+]
927 }
928 };
929
930 (@single;
932 $(#[repr($repr:ty)])?
933 $vis:vis enum #anon {
934 $(
935 $(#[$meta:meta])*
936 $field_vis:vis $variant:ident $(= $value:expr)?,
937 )+
938 }
939 ) => {
940 c_enum! {
941 @variant;
942 ty: c_enum!(@ty $($repr)?);
943 default: 0;
944 variants: [$(
945 $(#[$meta])*
946 $field_vis $variant $(= $value)?,
947 )+]
948 }
949 };
950
951 (@variant;
953 ty: $_ty_name:ty;
954 default: $_idx:expr;
955 variants: []
956 ) => { };
957 (
958 @variant;
959 ty: $ty_name:ty;
960 default: $default_val:expr;
961 variants: [
962 $(#[$meta:meta])*
963 $field_vis:vis $variant:ident $(= $value:expr)?,
964 $($tail:tt)*
965 ]
966 ) => {
967 $(#[$meta])*
968 #[allow(deprecated)]
969 $field_vis const $variant: $ty_name = {
970 #[allow(unused_variables)]
971 let r = $default_val;
972 $(let r = $value;)?
973 r
974 };
975
976 c_enum! {
979 @variant;
980 ty: $ty_name;
981 default: $variant + 1;
982 variants: [$($tail)*]
983 }
984 };
985
986 (@ty $repr:ty) => { $repr };
988 (@ty) => { $crate::prelude::CEnumRepr };
989}
990
991macro_rules! f {
994 ($(
995 $(#[$attr:meta])*
996 pub $(const $($const_dummy:literal)?)?
997 $(unsafe $($unsafe_dummy:literal)?)? $(safe $($safe_dummy:literal)?)?
998 fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty
999 $body:block
1000 )+) => {$(
1001 f! {
1002 @single
1003 $(#[$attr])*
1004 pub $(const $($const_dummy)?)?
1005 $(unsafe $($unsafe_dummy)?)? $(safe $($safe_dummy)?)?
1006 fn $i ($($arg: $argty),*) -> $ret
1007 $body
1008 }
1009 )+};
1010
1011 (@single
1012 $(#[$attr:meta])*
1013 pub $(const $($const_dummy:literal)?)? unsafe
1014 fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty
1015 $body:block
1016 ) => {
1017 #[inline]
1018 $(#[$attr])*
1019 pub $(const $($const_dummy)?)? unsafe extern "C"
1020 fn $i ($($arg: $argty),*) -> $ret
1021 $body
1022 };
1023
1024 (@single
1025 $(#[$attr:meta])*
1026 pub $(const $($const_dummy:literal)?)? safe
1027 fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty
1028 $body:block
1029 ) => {
1030 #[inline]
1031 $(#[$attr])*
1032 pub $(const $($const_dummy)?)? extern "C"
1033 fn $i ($($arg: $argty),*) -> $ret
1034 $body
1035 };
1036
1037 (@single
1038 pub $(const $($const_dummy:literal)?)?
1039 fn $i:ident ($($arg:ident: $argty:ty),* $(,)?) -> $ret:ty
1040 $body:block
1041 ) => {
1042 compile_error!("either `safe` or `unsafe` must be specified");
1043 };
1044}
1045
1046macro_rules! deprecated_mach {
1048 (pub const $id:ident: $ty:ty = $expr:expr;) => {
1049 #[deprecated(
1050 since = "0.2.55",
1051 note = "Use the `mach2` crate instead",
1052 )]
1053 #[allow(deprecated)]
1054 pub const $id: $ty = $expr;
1055 };
1056 ($(pub const $id:ident: $ty:ty = $expr:expr;)*) => {
1057 $(
1058 deprecated_mach!(
1059 pub const $id: $ty = $expr;
1060 );
1061 )*
1062 };
1063 (pub type $id:ident = $ty:ty;) => {
1064 #[deprecated(
1065 since = "0.2.55",
1066 note = "Use the `mach2` crate instead",
1067 )]
1068 #[allow(deprecated)]
1069 pub type $id = $ty;
1070 };
1071 ($(pub type $id:ident = $ty:ty;)*) => {
1072 $(
1073 deprecated_mach!(
1074 pub type $id = $ty;
1075 );
1076 )*
1077 }
1078}
1079
1080macro_rules! offset_of {
1083 ($Ty:path, $field:ident) => {{
1084 #[allow(clippy::unneeded_wildcard_pattern)]
1086 let $Ty { $field: _, .. };
1087 let data = core::mem::MaybeUninit::<$Ty>::uninit();
1088 let ptr = data.as_ptr();
1089 #[allow(unused_unsafe)]
1091 let fptr = unsafe { core::ptr::addr_of!((*ptr).$field) };
1094 let off = (fptr as usize).checked_sub(ptr as usize).unwrap();
1095 core::assert!(off <= core::mem::size_of::<$Ty>());
1096 off
1097 }};
1098}
1099
1100#[cfg(test)]
1101mod tests {
1102 use core::any::TypeId;
1103 use core::prelude::v1::*;
1104
1105 use crate::types::CEnumRepr;
1106
1107 #[test]
1108 fn c_enum_basic() {
1109 c_enum! {
1111 pub enum e {
1112 VAR0,
1113 VAR1,
1114 VAR2,
1115 }
1116
1117 pub enum #anon {
1119 ANON0,
1120 ANON1,
1121 ANON2,
1122 }
1123
1124 enum #anon {
1126 ANON3,
1127 ANON4,
1128 ANON5,
1129 }
1130 }
1131
1132 assert_eq!(TypeId::of::<e>(), TypeId::of::<CEnumRepr>());
1133 assert_eq!(VAR0, 0 as CEnumRepr);
1134 assert_eq!(VAR1, 1 as CEnumRepr);
1135 assert_eq!(VAR2, 2 as CEnumRepr);
1136
1137 assert_eq!(type_id_of_val(&ANON0), TypeId::of::<CEnumRepr>());
1138 assert_eq!(ANON0, 0 as CEnumRepr);
1139 assert_eq!(ANON1, 1 as CEnumRepr);
1140 assert_eq!(ANON2, 2 as CEnumRepr);
1141
1142 assert_eq!(type_id_of_val(&ANON3), TypeId::of::<CEnumRepr>());
1143 assert_eq!(ANON3, 0 as CEnumRepr);
1144 assert_eq!(ANON4, 1 as CEnumRepr);
1145 assert_eq!(ANON5, 2 as CEnumRepr);
1146 }
1147
1148 #[test]
1149 fn c_enum_repr() {
1150 c_enum! {
1152 #[repr(u16)]
1153 pub enum e {
1154 VAR0,
1155 }
1156
1157 #[repr(u16)]
1158 pub enum #anon {
1159 ANON0,
1160 }
1161 }
1162
1163 assert_eq!(TypeId::of::<e>(), TypeId::of::<u16>());
1164 assert_eq!(VAR0, 0_u16);
1165
1166 assert_eq!(type_id_of_val(&ANON0), TypeId::of::<u16>());
1167 assert_eq!(ANON0, 0_u16);
1168 }
1169
1170 #[test]
1171 fn c_enum_set_value() {
1172 c_enum! {
1174 pub enum e {
1175 VAR2 = 2,
1176 VAR3,
1177 VAR4,
1178 }
1179 }
1180
1181 assert_eq!(VAR2, 2 as CEnumRepr);
1182 assert_eq!(VAR3, 3 as CEnumRepr);
1183 assert_eq!(VAR4, 4 as CEnumRepr);
1184 }
1185
1186 #[test]
1187 fn c_enum_multiple_set_value() {
1188 c_enum! {
1191 pub enum e {
1192 VAR0,
1193 VAR2_0 = 2,
1194 VAR3_0,
1195 VAR4_0,
1196 VAR2_1 = 2,
1197 VAR3_1,
1198 VAR4_1,
1199 }
1200 }
1201
1202 assert_eq!(VAR0, 0 as CEnumRepr);
1203 assert_eq!(VAR2_0, 2 as CEnumRepr);
1204 assert_eq!(VAR3_0, 3 as CEnumRepr);
1205 assert_eq!(VAR4_0, 4 as CEnumRepr);
1206 assert_eq!(VAR2_1, 2 as CEnumRepr);
1207 assert_eq!(VAR3_1, 3 as CEnumRepr);
1208 assert_eq!(VAR4_1, 4 as CEnumRepr);
1209 }
1210
1211 #[test]
1212 fn c_enum_vis() {
1213 mod priv1 {
1214 c_enum! {
1215 #[repr(u8)]
1216 pub enum e1 {
1217 PRIV_ON_1 = 10,
1218 pub PUB1 = PRIV_ON_1 * 2,
1220 }
1221 }
1222 }
1223 mod priv2 {
1224 c_enum! {
1225 #[repr(u16)]
1226 pub enum e2 {
1227 pub PRIV_ON_1 = 42,
1228 pub PUB2 = PRIV_ON_1 * 2,
1229 }
1230 }
1231 }
1232
1233 use priv1::*;
1234 use priv2::*;
1235
1236 assert_eq!(TypeId::of::<e1>(), TypeId::of::<u8>());
1237 assert_eq!(TypeId::of::<e2>(), TypeId::of::<u16>());
1238 assert_eq!(PUB1, 10u8 * 2);
1239 assert_eq!(PUB2, 42u16 * 2);
1240 assert_eq!(PRIV_ON_1, 42u16);
1244 }
1245
1246 #[test]
1247 fn c_enum_attrs() {
1248 c_enum! {
1250 pub enum e {
1251 VAR0,
1252 WITH_CFG = if cfg!(target_arch = "x86_64") { 86 } else { 1234 },
1253 #[deprecated]
1254 DEPRECATED,
1255 NOT_DEPRECATED,
1256 }
1257 }
1258
1259 if cfg!(target_arch = "x86_64") {
1260 assert_eq!(WITH_CFG, 86);
1261 } else {
1262 assert_eq!(WITH_CFG, 1234);
1263 }
1264
1265 #[expect(deprecated)]
1266 let _ = DEPRECATED;
1267 #[deny(deprecated)]
1268 let _ = NOT_DEPRECATED;
1269 }
1270
1271 #[test]
1272 #[deny(unused_unsafe)]
1273 fn f_safety() {
1274 f! {
1276 pub unsafe fn unsafe_foo() -> u32 { 100 }
1277 pub const unsafe fn const_unsafe_foo() -> u32 { 101 }
1278 pub safe fn safe_foo() -> u32 { 200 }
1279 pub const safe fn const_safe_foo() -> u32 { 201 }
1280 }
1281
1282 assert_eq!(unsafe { unsafe_foo() }, 100u32);
1283 assert_eq!(const { unsafe { const_unsafe_foo() } }, 101u32);
1284 assert_eq!(safe_foo(), 200u32);
1285 assert_eq!(const { const_safe_foo() }, 201u32);
1286
1287 let _: unsafe extern "C" fn() -> u32 = unsafe_foo;
1289 let _: unsafe extern "C" fn() -> u32 = const_unsafe_foo;
1290 let _: extern "C" fn() -> u32 = safe_foo;
1291 let _: extern "C" fn() -> u32 = const_safe_foo;
1292 }
1293
1294 fn type_id_of_val<T: 'static>(_: &T) -> TypeId {
1295 TypeId::of::<T>()
1296 }
1297
1298 #[test]
1299 fn test_offset_of() {
1300 #[repr(C)]
1301 struct Off1 {
1302 a: u8,
1303 b: u32,
1304 c: Off2,
1305 d: u64,
1306 }
1307
1308 #[repr(C)]
1309 #[repr(align(128))]
1310 struct Off2 {}
1311
1312 assert_eq!(core::mem::offset_of!(Off1, a), offset_of!(Off1, a));
1313 assert_eq!(core::mem::offset_of!(Off1, b), offset_of!(Off1, b));
1314 assert_eq!(core::mem::offset_of!(Off1, c), offset_of!(Off1, c));
1315 assert_eq!(core::mem::offset_of!(Off1, d), offset_of!(Off1, d));
1316 }
1317
1318 #[test]
1319 fn s2_is_non_exhaustive() {
1320 s2! {
1323 struct Something {
1324 a: u32,
1325 }
1326 }
1327
1328 let s = Something::default();
1329 assert_eq!(s.__non_exhaustive, ());
1330 }
1331
1332 #[test]
1333 fn s2_uses_exhaustive() {
1334 s2! {
1337 #[exhaustive]
1338 struct Something {
1339 a: u32,
1340 }
1341 }
1342
1343 #[allow(unused)]
1344 let s = Something {
1345 a: Default::default(),
1346 };
1347 }
1348
1349 #[test]
1350 fn s2_uses_mixed_exhaustive() {
1351 s2! {
1354 #[repr(align(8))]
1355 #[exhaustive]
1356 #[repr(align(2))]
1357 struct Something {
1358 a: u32,
1359 }
1360 }
1361
1362 #[allow(unused)]
1363 let s = Something {
1364 a: Default::default(),
1365 };
1366 }
1367
1368 #[test]
1369 fn s2_uses_custom_default() {
1370 s2! {
1373 struct CustomDefault {
1374 a: u32,
1375 #[custom_default([1; 64])]
1376 buf: [u8; 64],
1377 }
1378 }
1379
1380 let s = CustomDefault::default();
1381 assert_eq!(s.a, 0);
1382 assert_eq!(s.buf, [1u8; 64]);
1383 }
1384
1385 #[test]
1386 fn s2_keeps_field_attrs() {
1387 s2! {
1390 struct FieldAttrs {
1391 #[cfg(target_arch = "x86_64")]
1392 a: u8,
1393 #[cfg(not(target_arch = "x86_64"))]
1394 a: u64,
1395 }
1396 }
1397
1398 let s = FieldAttrs::default();
1399 #[cfg(target_arch = "x86_64")]
1400 assert_eq!(s.a, 0u8);
1401 #[cfg(not(target_arch = "x86_64"))]
1402 assert_eq!(s.a, 0u64);
1403 }
1404
1405 #[test]
1406 fn s2_single_cfg_field() {
1407 s2! {
1410 struct SingleCfg {
1411 common: u32,
1412 #[cfg(target_arch = "x86_64")]
1413 x86_only: u64,
1414 }
1415 }
1416
1417 let s = SingleCfg::default();
1418 assert_eq!(s.common, 0);
1419 #[cfg(target_arch = "x86_64")]
1420 assert_eq!(s.x86_only, 0);
1421 }
1422
1423 #[test]
1424 fn s_no_extra_traits2_zeroes_union() {
1425 s_no_extra_traits2! {
1428 union U {
1429 a: u32,
1430 b: f32,
1431 }
1432
1433 struct HasUnion {
1434 x: u16,
1435 #[custom_default(unsafe { ::core::mem::zeroed::<U>() })]
1436 u: U,
1437 }
1438 }
1439
1440 let s = HasUnion::default();
1441 assert_eq!(s.x, 0);
1442 assert_eq!(unsafe { s.u.a }, 0);
1443 }
1444
1445 #[test]
1446 fn s2_keeps_struct_cfg() {
1447 s2! {
1451 #[cfg(true)]
1452 #[repr(align(8))]
1453 struct EnabledCfg {
1455 a: u32,
1456 #[cfg(target_arch = "x86_64")]
1457 x86_only: u8,
1458 #[custom_default([1; 40])]
1459 buf: [u8; 40],
1460 }
1461 }
1462
1463 let s = EnabledCfg::default();
1464 assert_eq!(s.a, 0);
1465 assert_eq!(s.buf, [1u8; 40]);
1466 assert_eq!(align_of::<EnabledCfg>(), 8);
1467 #[cfg(target_arch = "x86_64")]
1468 assert_eq!(s.x86_only, 0);
1469 }
1470
1471 #[test]
1472 fn s2_union_default() {
1473 s_no_extra_traits2! {
1474 #[unsafe(union_default_via_zeroed)]
1475 union Foo {
1476 a: u32,
1477 b: u64
1478 }
1479
1480 #[expect(unused)]
1481 union Bar {
1482 a: u32,
1483 b: u64
1484 }
1485 }
1486
1487 let f: Foo = Foo::default();
1488 assert_eq!(unsafe { f.b }, 0);
1489
1490 impl Default for Bar {
1492 fn default() -> Self {
1493 unimplemented!()
1494 }
1495 }
1496 }
1497}
1498
1499#[cfg(test)]
1500#[allow(unused)]
1501mod macro_checks {
1502 use core::prelude::v1::*;
1503
1504 s! {
1505 pub struct S1 {
1506 pub a: u32,
1507 b: u32,
1508 }
1509
1510 struct S1Priv {
1511 pub a: u32,
1512 b: u32,
1513 }
1514 }
1515
1516 s_no_extra_traits! {
1517 pub struct S2 {
1518 pub a: u32,
1519 b: u32,
1520 }
1521
1522 struct S2Priv {
1523 pub a: u32,
1524 b: u32,
1525 }
1526
1527 pub union U2 {
1528 pub a: u32,
1529 b: f32,
1530 }
1531
1532 union U2Priv {
1533 pub a: u32,
1534 b: f32,
1535 }
1536 }
1537
1538 extern_ty! {
1539 type Foo;
1540 pub type Bar;
1541 }
1542
1543 s2! {
1544 pub struct S3 {
1545 pub a: u32,
1546 #[custom_default([1; 64])]
1547 pub buf: [u8; 64],
1548 }
1549
1550 struct S3Priv {
1551 pub a: u32,
1552 b: u32,
1553 }
1554 }
1555
1556 s_no_extra_traits2! {
1557 pub union U3 {
1558 pub a: u32,
1559 b: f32,
1560 }
1561
1562 pub struct S4 {
1563 pub a: u32,
1564 #[custom_default(unsafe { ::core::mem::zeroed::<U3>() })]
1565 pub u: U3,
1566 }
1567 }
1568
1569 fn assert_impls_default<T: Default>() {}
1570
1571 fn check_default() {
1572 assert_impls_default::<S3>();
1573 assert_impls_default::<S4>();
1574 }
1575
1576 s2! {
1580 #[cfg(false)]
1581 pub struct S5 {
1582 pub a: u32,
1583 #[custom_default([1; 64])]
1584 pub buf: [u8; 64],
1585 }
1586 }
1587
1588 s_no_extra_traits! {
1589 #[cfg(false)]
1590 pub union U4 {
1591 pub a: u32,
1592 b: f32,
1593 }
1594 }
1595
1596 s_no_extra_traits2! {
1597 #[cfg(false)]
1598 pub union U5 {
1599 pub a: u32,
1600 b: f32,
1601 }
1602
1603 #[cfg(false)]
1604 pub struct S6 {
1605 pub a: u32,
1606 }
1607 }
1608
1609 mod deprecated_checks {
1613 #![deny(deprecated)]
1614
1615 s2! {
1616 #[deprecated(since = "0.0.0", note = "check that generated impls don't warn")]
1617 pub struct S7 {
1618 pub a: u32,
1619 }
1620 }
1621
1622 s_no_extra_traits! {
1623 #[deprecated(since = "0.0.0", note = "check that generated impls don't warn")]
1624 pub union U6 {
1625 pub a: u32,
1626 b: f32,
1627 }
1628 }
1629
1630 s_no_extra_traits2! {
1631 #[deprecated(since = "0.0.0", note = "check that generated impls don't warn")]
1632 pub union U7 {
1633 pub a: u32,
1634 b: f32,
1635 }
1636 }
1637 }
1638}