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 prelude {
71 #[allow(unused_imports)]
73 pub(crate) use ::core::clone::Clone;
74 #[allow(unused_imports)]
75 pub(crate) use ::core::marker::{Copy, Send, Sync};
76 #[allow(unused_imports)]
77 pub(crate) use ::core::option::Option;
78 #[allow(unused_imports)]
79 pub(crate) use ::core::{fmt, hash, iter, mem};
80 #[allow(unused_imports)]
81 pub(crate) use mem::{align_of, align_of_val, size_of, size_of_val};
82
83 #[allow(unused_imports)]
85 pub(crate) use crate::{
86 c_char, c_double, c_float, c_int, c_long, c_longlong, c_short, c_uchar, c_uint,
87 c_ulong, c_ulonglong, c_ushort, c_void, intptr_t, size_t, ssize_t, uintptr_t,
88 };
89 }
90 };
91}
92
93macro_rules! s {
99 ($(
100 $(#[$attr:meta])*
101 pub $t:ident $i:ident { $($field:tt)* }
102 )*) => ($(
103 s!(it: $(#[$attr])* pub $t $i { $($field)* });
104 )*);
105
106 (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => (
107 compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead");
108 );
109
110 (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => (
111 __item! {
112 #[repr(C)]
113 #[cfg_attr(
114 feature = "extra_traits",
115 ::core::prelude::v1::derive(Debug, Eq, Hash, PartialEq)
116 )]
117 #[::core::prelude::v1::derive(::core::clone::Clone, ::core::marker::Copy)]
118 #[allow(deprecated)]
119 $(#[$attr])*
120 pub struct $i { $($field)* }
121 }
122 );
123}
124
125macro_rules! s_paren {
130 ($(
131 $(#[$attr:meta])*
132 pub struct $i:ident ( $($field:tt)* );
133 )*) => ($(
134 __item! {
135 #[cfg_attr(
136 feature = "extra_traits",
137 ::core::prelude::v1::derive(Debug, Eq, Hash, PartialEq)
138 )]
139 #[::core::prelude::v1::derive(::core::clone::Clone, ::core::marker::Copy)]
140 $(#[$attr])*
141 pub struct $i ( $($field)* );
142 }
143 )*);
144}
145
146macro_rules! s_no_extra_traits {
151 ($(
152 $(#[$attr:meta])*
153 pub $t:ident $i:ident { $($field:tt)* }
154 )*) => ($(
155 s_no_extra_traits!(it: $(#[$attr])* pub $t $i { $($field)* });
156 )*);
157
158 (it: $(#[$attr:meta])* pub union $i:ident { $($field:tt)* }) => (
159 __item! {
160 #[repr(C)]
161 #[::core::prelude::v1::derive(::core::clone::Clone, ::core::marker::Copy)]
162 $(#[$attr])*
163 pub union $i { $($field)* }
164 }
165
166 #[cfg(feature = "extra_traits")]
167 impl ::core::fmt::Debug for $i {
168 fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
169 f.debug_struct(::core::stringify!($i)).finish_non_exhaustive()
170 }
171 }
172 );
173
174 (it: $(#[$attr:meta])* pub struct $i:ident { $($field:tt)* }) => (
175 __item! {
176 #[repr(C)]
177 #[::core::prelude::v1::derive(::core::clone::Clone, ::core::marker::Copy)]
178 #[cfg_attr(feature = "extra_traits", ::core::prelude::v1::derive(Debug))]
179 $(#[$attr])*
180 pub struct $i { $($field)* }
181 }
182 );
183}
184
185macro_rules! missing {
188 ($(
189 $(#[$attr:meta])*
190 pub enum $i:ident {}
191 )*) => ($(
192 $(#[$attr])*
193 #[allow(missing_copy_implementations)]
194 pub enum $i { }
195 )*);
196}
197
198macro_rules! e {
202 ($(
203 $(#[$attr:meta])*
204 pub enum $i:ident { $($field:tt)* }
205 )*) => ($(
206 __item! {
207 #[cfg_attr(
208 feature = "extra_traits",
209 ::core::prelude::v1::derive(Debug, Eq, Hash, PartialEq)
210 )]
211 #[::core::prelude::v1::derive(::core::clone::Clone, ::core::marker::Copy)]
212 $(#[$attr])*
213 pub enum $i { $($field)* }
214 }
215 )*);
216}
217
218macro_rules! c_enum {
226 ($(
227 $(#[repr($repr:ty)])?
228 pub enum $ty_name:ident {
229 $($variant:ident $(= $value:expr)?,)+
230 }
231 )+) => {
232 $(c_enum!(@expand;
233 $(#[repr($repr)])?
234 pub enum $ty_name {
235 $($variant $(= $value)?,)+
236 }
237 );)+
238 };
239
240 (@expand;
241 $(#[repr($repr:ty)])?
242 pub enum $ty_name:ident {
243 $($variant:ident $(= $value:expr)?,)+
244 }
245 ) => {
246 pub type $ty_name = c_enum!(@ty $($repr)?);
247 c_enum!(@one; $ty_name; 0; $($variant $(= $value)?,)+);
248 };
249
250 (@one; $_ty_name:ident; $_idx:expr;) => {};
252 (
253 @one; $ty_name:ident; $default_val:expr;
254 $variant:ident $(= $value:expr)?,
255 $($tail:tt)*
256 ) => {
257 pub const $variant: $ty_name = {
258 #[allow(unused_variables)]
259 let r = $default_val;
260 $(let r = $value;)?
261 r
262 };
263
264 c_enum!(@one; $ty_name; $variant + 1; $($tail)*);
267 };
268
269 (@ty $repr:ty) => { $repr };
271 (@ty) => { $crate::c_uint };
272}
273
274cfg_if! {
297 if #[cfg(libc_const_extern_fn)] {
298 macro_rules! f {
300 ($(
301 $(#[$attr:meta])*
302 pub $({$constness:ident})* fn $i:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
303 $body:block
304 )*) => ($(
305 #[inline]
306 $(#[$attr])*
307 pub $($constness)* unsafe extern "C" fn $i($($arg: $argty),*) -> $ret
308 $body
309 )*)
310 }
311
312 macro_rules! safe_f {
314 ($(
315 $(#[$attr:meta])*
316 pub $({$constness:ident})* fn $i:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
317 $body:block
318 )*) => ($(
319 #[inline]
320 $(#[$attr])*
321 pub $($constness)* extern "C" fn $i($($arg: $argty),*) -> $ret
322 $body
323 )*)
324 }
325
326 macro_rules! const_fn {
328 ($(
329 $(#[$attr:meta])*
330 $({$constness:ident})* fn $i:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
331 $body:block
332 )*) => ($(
333 #[inline]
334 $(#[$attr])*
335 $($constness)* fn $i($($arg: $argty),*) -> $ret
336 $body
337 )*)
338 }
339 } else {
340 macro_rules! f {
342 ($(
343 $(#[$attr:meta])*
344 pub $({$constness:ident})* fn $i:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
345 $body:block
346 )*) => ($(
347 #[inline]
348 $(#[$attr])*
349 pub unsafe extern "C" fn $i($($arg: $argty),*) -> $ret
350 $body
351 )*)
352 }
353
354 macro_rules! safe_f {
356 ($(
357 $(#[$attr:meta])*
358 pub $({$constness:ident})* fn $i:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
359 $body:block
360 )*) => ($(
361 #[inline]
362 $(#[$attr])*
363 pub extern "C" fn $i($($arg: $argty),*) -> $ret
364 $body
365 )*)
366 }
367
368 macro_rules! const_fn {
370 ($(
371 $(#[$attr:meta])*
372 $({$constness:ident})* fn $i:ident($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
373 $body:block
374 )*) => ($(
375 #[inline]
376 $(#[$attr])*
377 fn $i($($arg: $argty),*) -> $ret
378 $body
379 )*)
380 }
381 }
382}
383
384macro_rules! __item {
385 ($i:item) => {
386 $i
387 };
388}
389
390macro_rules! deprecated_mach {
392 (pub const $id:ident: $ty:ty = $expr:expr;) => {
393 #[deprecated(
394 since = "0.2.55",
395 note = "Use the `mach2` crate instead",
396 )]
397 #[allow(deprecated)]
398 pub const $id: $ty = $expr;
399 };
400 ($(pub const $id:ident: $ty:ty = $expr:expr;)*) => {
401 $(
402 deprecated_mach!(
403 pub const $id: $ty = $expr;
404 );
405 )*
406 };
407 (pub type $id:ident = $ty:ty;) => {
408 #[deprecated(
409 since = "0.2.55",
410 note = "Use the `mach2` crate instead",
411 )]
412 #[allow(deprecated)]
413 pub type $id = $ty;
414 };
415 ($(pub type $id:ident = $ty:ty;)*) => {
416 $(
417 deprecated_mach!(
418 pub type $id = $ty;
419 );
420 )*
421 }
422}
423
424#[cfg(test)]
425mod tests {
426 #[test]
427 fn c_enumbasic() {
428 c_enum! {
430 pub enum e {
431 VAR0,
432 VAR1,
433 VAR2,
434 }
435 }
436
437 assert_eq!(VAR0, 0_u32);
438 assert_eq!(VAR1, 1_u32);
439 assert_eq!(VAR2, 2_u32);
440 }
441
442 #[test]
443 fn c_enumrepr() {
444 c_enum! {
446 #[repr(u16)]
447 pub enum e {
448 VAR0,
449 }
450 }
451
452 assert_eq!(VAR0, 0_u16);
453 }
454
455 #[test]
456 fn c_enumset_value() {
457 c_enum! {
459 pub enum e {
460 VAR2 = 2,
461 VAR3,
462 VAR4,
463 }
464 }
465
466 assert_eq!(VAR2, 2_u32);
467 assert_eq!(VAR3, 3_u32);
468 assert_eq!(VAR4, 4_u32);
469 }
470
471 #[test]
472 fn c_enummultiple_set_value() {
473 c_enum! {
476 pub enum e {
477 VAR0,
478 VAR2_0 = 2,
479 VAR3_0,
480 VAR4_0,
481 VAR2_1 = 2,
482 VAR3_1,
483 VAR4_1,
484 }
485 }
486
487 assert_eq!(VAR0, 0_u32);
488 assert_eq!(VAR2_0, 2_u32);
489 assert_eq!(VAR3_0, 3_u32);
490 assert_eq!(VAR4_0, 4_u32);
491 assert_eq!(VAR2_1, 2_u32);
492 assert_eq!(VAR3_1, 3_u32);
493 assert_eq!(VAR4_1, 4_u32);
494 }
495}