Coverage Report

Created: 2026-04-12 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/libc-0.2.184/src/macros.rs
Line
Count
Source
1
/// A macro for defining #[cfg] if-else statements.
2
///
3
/// This is similar to the `if/elif` C preprocessor macro by allowing definition
4
/// of a cascade of `#[cfg]` cases, emitting the implementation which matches
5
/// first.
6
///
7
/// This allows you to conveniently provide a long list #[cfg]'d blocks of code
8
/// without having to rewrite each clause multiple times.
9
macro_rules! cfg_if {
10
    // match if/else chains with a final `else`
11
    ($(
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
    // match if/else chains lacking a final `else`
25
    (
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
    // Internal and recursive macro to emit all the items
41
    //
42
    // Collects all the negated `cfg`s in a list at the beginning and after the
43
    // semicolon is all the remaining items
44
    (@__items ($($not:meta,)*) ; ) => {};
45
    (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ),
46
     $($rest:tt)*) => {
47
        // Emit all items within one block, applying an appropriate #[cfg]. The
48
        // #[cfg] will require all `$m` matchers specified and must also negate
49
        // all previous matchers.
50
        cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* }
51
52
        // Recurse to emit all other items in `$rest`, and when we do so add all
53
        // our `$m` matchers to the list of `$not` matchers as future emissions
54
        // will have to negate everything we just matched as well.
55
        cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* }
56
    };
57
58
    // Internal macro to Apply a cfg attribute to a list of items
59
    (@__apply $m:meta, $($it:item)*) => {
60
        $(#[$m] $it)*
61
    };
62
}
63
64
/// Create an internal crate prelude with `core` reexports and common types.
65
macro_rules! prelude {
66
    () => {
67
        mod types;
68
69
        /// Frequently-used types that are available on all platforms
70
        ///
71
        /// We need to reexport the core types so this works with `rust-dep-of-std`.
72
        mod prelude {
73
            // Exports from `core`
74
            #[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
                cfg,
91
                fmt,
92
                hash,
93
                iter,
94
                mem,
95
                ptr,
96
            };
97
98
            #[allow(unused_imports)]
99
            pub(crate) use fmt::Debug;
100
            #[allow(unused_imports)]
101
            pub(crate) use mem::{
102
                align_of,
103
                align_of_val,
104
                size_of,
105
                size_of_val,
106
            };
107
108
            #[allow(unused_imports)]
109
            pub(crate) use crate::types::{
110
                CEnumRepr,
111
                Padding,
112
            };
113
            // Commonly used types defined in this crate
114
            #[allow(unused_imports)]
115
            pub(crate) use crate::{
116
                c_char,
117
                c_double,
118
                c_float,
119
                c_int,
120
                c_long,
121
                c_longlong,
122
                c_short,
123
                c_uchar,
124
                c_uint,
125
                c_ulong,
126
                c_ulonglong,
127
                c_ushort,
128
                c_void,
129
                intptr_t,
130
                size_t,
131
                ssize_t,
132
                uintptr_t,
133
            };
134
        }
135
    };
136
}
137
138
/// Implement `Clone`, `Copy`, and `Debug` for one or more structs, as well as `PartialEq`, `Eq`,
139
/// and `Hash` if the `extra_traits` feature is enabled.
140
///
141
/// Also mark the type with `repr(C)`.
142
///
143
/// Use [`s_no_extra_traits`] for structs where the `extra_traits` feature does not
144
/// make sense, and for unions.
145
macro_rules! s {
146
    ($(
147
        $(#[$attr:meta])*
148
        $pub:vis $t:ident $i:ident { $($field:tt)* }
149
    )*) => ($(
150
        s!(it: $(#[$attr])* $pub $t $i { $($field)* });
151
    )*);
152
153
    (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => (
154
        compile_error!("unions cannot derive extra traits, use s_no_extra_traits instead");
155
    );
156
157
    (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => (
158
        #[repr(C)]
159
        #[::core::prelude::v1::derive(
160
            ::core::clone::Clone,
161
            ::core::marker::Copy,
162
            ::core::fmt::Debug,
163
        )]
164
        #[cfg_attr(
165
            feature = "extra_traits",
166
            ::core::prelude::v1::derive(PartialEq, Eq, Hash)
167
        )]
168
        #[allow(deprecated)]
169
        $(#[$attr])*
170
        $pub struct $i { $($field)* }
171
    );
172
}
173
174
/// Implement `Clone`, `Copy`, and `Debug` for a tuple struct, as well as `PartialEq`, `Eq`,
175
/// and `Hash` if the `extra_traits` feature is enabled.
176
///
177
/// Unlike `s!`, this does *not* mark the type with `repr(C)`. Users should provide their own
178
/// `repr` attribute via `$attr` as necessary.
179
macro_rules! s_paren {
180
    ($(
181
        $(#[$attr:meta])*
182
        $pub:vis struct $i:ident ( $($field:tt)* );
183
    )*) => ($(
184
        #[::core::prelude::v1::derive(
185
            ::core::clone::Clone,
186
            ::core::marker::Copy,
187
            ::core::fmt::Debug,
188
        )]
189
        #[cfg_attr(
190
            feature = "extra_traits",
191
            ::core::prelude::v1::derive(PartialEq, Eq, Hash)
192
        )]
193
        $(#[$attr])*
194
        $pub struct $i ( $($field)* );
195
    )*);
196
}
197
198
/// Implement `Clone`, `Copy`, and `Debug` for one or more structs/unions, but exclude `PartialEq`,
199
/// `Eq`, and `Hash`.
200
///
201
/// Also mark the type with `repr(C)`.
202
///
203
/// Most structs will prefer to use [`s`].
204
macro_rules! s_no_extra_traits {
205
    ($(
206
        $(#[$attr:meta])*
207
        $pub:vis $t:ident $i:ident { $($field:tt)* }
208
    )*) => ($(
209
        s_no_extra_traits!(it: $(#[$attr])* $pub $t $i { $($field)* });
210
    )*);
211
212
    (it: $(#[$attr:meta])* $pub:vis union $i:ident { $($field:tt)* }) => (
213
        #[repr(C)]
214
        #[::core::prelude::v1::derive(
215
            ::core::clone::Clone,
216
            ::core::marker::Copy,
217
        )]
218
        $(#[$attr])*
219
        $pub union $i { $($field)* }
220
221
        impl ::core::fmt::Debug for $i {
222
0
            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
223
0
                f.debug_struct(::core::stringify!($i)).finish_non_exhaustive()
224
0
            }
Unexecuted instantiation: <libc::unix::linux_like::linux::gnu::__c_anonymous_ptrace_syscall_info_data as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux_l4re_shared::__c_anonymous_ifr_ifru as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::gnu::sifields as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux_l4re_shared::__c_anonymous_ifc_ifcu as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::__c_anonymous_iwreq as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::__c_anonymous_ptp_perout_request_1 as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::__c_anonymous_ptp_perout_request_2 as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::__c_anonymous_xsk_tx_metadata_union as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::tpacket_req_u as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::tpacket_bd_header_u as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::unix::linux_like::linux::iwreq_data as core::fmt::Debug>::fmt
Unexecuted instantiation: <libc::new::linux_uapi::linux::can::__c_anonymous_sockaddr_can_can_addr as core::fmt::Debug>::fmt
225
        }
226
    );
227
228
    (it: $(#[$attr:meta])* $pub:vis struct $i:ident { $($field:tt)* }) => (
229
        #[repr(C)]
230
        #[::core::prelude::v1::derive(
231
            ::core::clone::Clone,
232
            ::core::marker::Copy,
233
            ::core::fmt::Debug,
234
        )]
235
        $(#[$attr])*
236
        $pub struct $i { $($field)* }
237
    );
238
}
239
240
/// Create an uninhabited type that can't be constructed. It implements `Debug`, `Clone`,
241
/// and `Copy`, but these aren't meaningful for extern types so they should eventually
242
/// be removed.
243
///
244
/// Really what we want here is something that also can't be named without indirection (in
245
/// ADTs or function signatures), but this doesn't exist.
246
macro_rules! extern_ty {
247
    ($(
248
        $(#[$attr:meta])*
249
        pub enum $i:ident {}
250
    )*) => ($(
251
        $(#[$attr])*
252
        // FIXME(1.0): the type is uninhabited so these traits are unreachable and could be
253
        // removed.
254
        #[::core::prelude::v1::derive(
255
            ::core::clone::Clone,
256
            ::core::marker::Copy,
257
            ::core::fmt::Debug,
258
        )]
259
        pub enum $i { }
260
    )*);
261
}
262
263
/// Implement `Clone` and `Copy` for an enum, as well as `Debug`, `Eq`, `Hash`, and
264
/// `PartialEq` if the `extra_traits` feature is enabled.
265
// FIXME(#4419): Replace all uses of `e!` with `c_enum!`
266
macro_rules! e {
267
    ($(
268
        $(#[$attr:meta])*
269
        pub enum $i:ident { $($field:tt)* }
270
    )*) => ($(
271
        #[cfg_attr(
272
            feature = "extra_traits",
273
            ::core::prelude::v1::derive(Eq, Hash, PartialEq)
274
        )]
275
        #[::core::prelude::v1::derive(
276
            ::core::clone::Clone,
277
            ::core::marker::Copy,
278
            ::core::fmt::Debug,
279
        )]
280
        $(#[$attr])*
281
        pub enum $i { $($field)* }
282
    )*);
283
}
284
285
/// Represent a C enum as Rust constants and a type.
286
///
287
/// C enums can't soundly be mapped to Rust enums since C enums are allowed to have duplicates or
288
/// unlisted values, but this is UB in Rust. This enum doesn't implement any traits, its main
289
/// purpose is to calculate the correct enum values.
290
///
291
/// Use the magic name `#anon` if the C enum doesn't create a type.
292
///
293
/// See <https://github.com/rust-lang/libc/issues/4419> for more.
294
macro_rules! c_enum {
295
    // Matcher for multiple enums
296
    ($(
297
        $(#[repr($repr:ty)])?
298
        pub enum $($ty_name:ident)? $(#$anon:ident)? {
299
            $($vis:vis $variant:ident $(= $value:expr)?,)+
300
        }
301
    )+) => {
302
        $(c_enum!(@single;
303
            $(#[repr($repr)])?
304
            pub enum $($ty_name)? $(#$anon)? {
305
                $($vis $variant $(= $value)?,)+
306
            }
307
        );)+
308
    };
309
310
    // Matcher for a single enum
311
    (@single;
312
        $(#[repr($repr:ty)])?
313
        pub enum $ty_name:ident {
314
            $($vis:vis $variant:ident $(= $value:expr)?,)+
315
        }
316
    ) => {
317
        pub type $ty_name = c_enum!(@ty $($repr)?);
318
        c_enum! {
319
            @variant;
320
            ty: $ty_name;
321
            default: 0;
322
            variants: [$($vis $variant $(= $value)?,)+]
323
        }
324
    };
325
326
    // Matcher for a single anonymous enum
327
    (@single;
328
        $(#[repr($repr:ty)])?
329
        pub enum #anon {
330
            $($vis:vis $variant:ident $(= $value:expr)?,)+
331
        }
332
    ) => {
333
        c_enum! {
334
            @variant;
335
            ty: c_enum!(@ty $($repr)?);
336
            default: 0;
337
            variants: [$($vis $variant $(= $value)?,)+]
338
        }
339
    };
340
341
    // Matcher for variants: eats a single variant then recurses with the rest
342
    (@variant; ty: $_ty_name:ty; default: $_idx:expr; variants: []) => { /* end of the chain */ };
343
    (
344
        @variant;
345
        ty: $ty_name:ty;
346
        default: $default_val:expr;
347
        variants: [
348
            $vis:vis $variant:ident $(= $value:expr)?,
349
            $($tail:tt)*
350
        ]
351
    ) => {
352
        $vis const $variant: $ty_name = {
353
            #[allow(unused_variables)]
354
            let r = $default_val;
355
            $(let r = $value;)?
356
            r
357
        };
358
359
        // The next value is always one more than the previous value, unless
360
        // set explicitly.
361
        c_enum! {
362
            @variant;
363
            ty: $ty_name;
364
            default: $variant + 1;
365
            variants: [$($tail)*]
366
        }
367
    };
368
369
    // Use a specific type if provided, otherwise default to `CEnumRepr`
370
    (@ty $repr:ty) => { $repr };
371
    (@ty) => { $crate::prelude::CEnumRepr };
372
}
373
374
/// Define a `unsafe` function.
375
macro_rules! f {
376
    ($(
377
        $(#[$attr:meta])*
378
        // Less than ideal hack to match either `fn` or `const fn`.
379
        pub $(fn $i:ident)? $(const fn $const_i:ident)?
380
        ($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
381
            $body:block
382
    )+) => {$(
383
        #[inline]
384
        $(#[$attr])*
385
        pub $(unsafe extern "C" fn $i)? $(const unsafe extern "C" fn $const_i)?
386
        ($($arg: $argty),*) -> $ret
387
            $body
388
    )+};
389
}
390
391
/// Define a safe function.
392
macro_rules! safe_f {
393
    ($(
394
        $(#[$attr:meta])*
395
        // Less than ideal hack to match either `fn` or `const fn`.
396
        pub $(fn $i:ident)? $(const fn $const_i:ident)?
397
        ($($arg:ident: $argty:ty),* $(,)*) -> $ret:ty
398
            $body:block
399
    )+) => {$(
400
        #[inline]
401
        $(#[$attr])*
402
        pub $(extern "C" fn $i)? $(const extern "C" fn $const_i)?
403
        ($($arg: $argty),*) -> $ret
404
            $body
405
    )+};
406
}
407
408
// This macro is used to deprecate items that should be accessed via the mach2 crate
409
macro_rules! deprecated_mach {
410
    (pub const $id:ident: $ty:ty = $expr:expr;) => {
411
        #[deprecated(
412
            since = "0.2.55",
413
            note = "Use the `mach2` crate instead",
414
        )]
415
        #[allow(deprecated)]
416
        pub const $id: $ty = $expr;
417
    };
418
    ($(pub const $id:ident: $ty:ty = $expr:expr;)*) => {
419
        $(
420
            deprecated_mach!(
421
                pub const $id: $ty = $expr;
422
            );
423
        )*
424
    };
425
    (pub type $id:ident = $ty:ty;) => {
426
        #[deprecated(
427
            since = "0.2.55",
428
            note = "Use the `mach2` crate instead",
429
        )]
430
        #[allow(deprecated)]
431
        pub type $id = $ty;
432
    };
433
    ($(pub type $id:ident = $ty:ty;)*) => {
434
        $(
435
            deprecated_mach!(
436
                pub type $id = $ty;
437
            );
438
        )*
439
    }
440
}
441
442
/// Polyfill for std's `offset_of`.
443
// FIXME(msrv): stabilized in std in 1.77
444
macro_rules! offset_of {
445
    ($Ty:path, $field:ident) => {{
446
        // Taken from bytemuck, avoids accidentally calling on deref
447
        #[allow(clippy::unneeded_field_pattern)]
448
        let $Ty { $field: _, .. };
449
        let data = core::mem::MaybeUninit::<$Ty>::uninit();
450
        let ptr = data.as_ptr();
451
        // nested unsafe, see f!
452
        #[allow(unused_unsafe)]
453
        // SAFETY: computed address is inbounds since we have a stack alloc for T
454
        let fptr = unsafe { core::ptr::addr_of!((*ptr).$field) };
455
        let off = (fptr as usize).checked_sub(ptr as usize).unwrap();
456
        core::assert!(off <= core::mem::size_of::<$Ty>());
457
        off
458
    }};
459
}
460
461
#[cfg(test)]
462
mod tests {
463
    use core::any::TypeId;
464
465
    use crate::types::CEnumRepr;
466
467
    #[test]
468
    fn c_enum_basic() {
469
        // By default, variants get sequential values.
470
        c_enum! {
471
            pub enum e {
472
                VAR0,
473
                VAR1,
474
                VAR2,
475
            }
476
477
            // Also check enums that don't create a type.
478
            pub enum #anon {
479
                ANON0,
480
                ANON1,
481
                ANON2,
482
            }
483
        }
484
485
        assert_eq!(TypeId::of::<e>(), TypeId::of::<CEnumRepr>());
486
        assert_eq!(VAR0, 0 as CEnumRepr);
487
        assert_eq!(VAR1, 1 as CEnumRepr);
488
        assert_eq!(VAR2, 2 as CEnumRepr);
489
490
        assert_eq!(type_id_of_val(&ANON0), TypeId::of::<CEnumRepr>());
491
        assert_eq!(ANON0, 0 as CEnumRepr);
492
        assert_eq!(ANON1, 1 as CEnumRepr);
493
        assert_eq!(ANON2, 2 as CEnumRepr);
494
    }
495
496
    #[test]
497
    fn c_enum_repr() {
498
        // Check specifying the integer representation
499
        c_enum! {
500
            #[repr(u16)]
501
            pub enum e {
502
                VAR0,
503
            }
504
505
            #[repr(u16)]
506
            pub enum #anon {
507
                ANON0,
508
            }
509
        }
510
511
        assert_eq!(TypeId::of::<e>(), TypeId::of::<u16>());
512
        assert_eq!(VAR0, 0_u16);
513
514
        assert_eq!(type_id_of_val(&ANON0), TypeId::of::<u16>());
515
        assert_eq!(ANON0, 0_u16);
516
    }
517
518
    #[test]
519
    fn c_enum_set_value() {
520
        // Setting an explicit value resets the count.
521
        c_enum! {
522
            pub enum e {
523
                VAR2 = 2,
524
                VAR3,
525
                VAR4,
526
            }
527
        }
528
529
        assert_eq!(VAR2, 2 as CEnumRepr);
530
        assert_eq!(VAR3, 3 as CEnumRepr);
531
        assert_eq!(VAR4, 4 as CEnumRepr);
532
    }
533
534
    #[test]
535
    fn c_enum_multiple_set_value() {
536
        // C enums always take one more than the previous value, unless set to a specific
537
        // value. Duplicates are allowed.
538
        c_enum! {
539
            pub enum e {
540
                VAR0,
541
                VAR2_0 = 2,
542
                VAR3_0,
543
                VAR4_0,
544
                VAR2_1 = 2,
545
                VAR3_1,
546
                VAR4_1,
547
            }
548
        }
549
550
        assert_eq!(VAR0, 0 as CEnumRepr);
551
        assert_eq!(VAR2_0, 2 as CEnumRepr);
552
        assert_eq!(VAR3_0, 3 as CEnumRepr);
553
        assert_eq!(VAR4_0, 4 as CEnumRepr);
554
        assert_eq!(VAR2_1, 2 as CEnumRepr);
555
        assert_eq!(VAR3_1, 3 as CEnumRepr);
556
        assert_eq!(VAR4_1, 4 as CEnumRepr);
557
    }
558
559
    #[test]
560
    fn c_enum_vis() {
561
        mod priv1 {
562
            c_enum! {
563
                #[repr(u8)]
564
                pub enum e1 {
565
                    PRIV_ON_1 = 10,
566
                    // Variant should still be usable within its visibility
567
                    pub PUB1 = PRIV_ON_1 * 2,
568
                }
569
            }
570
        }
571
        mod priv2 {
572
            c_enum! {
573
                #[repr(u16)]
574
                pub enum e2 {
575
                    pub PRIV_ON_1 = 42,
576
                    pub PUB2 = PRIV_ON_1 * 2,
577
                }
578
            }
579
        }
580
581
        use priv1::*;
582
        use priv2::*;
583
584
        assert_eq!(TypeId::of::<e1>(), TypeId::of::<u8>());
585
        assert_eq!(TypeId::of::<e2>(), TypeId::of::<u16>());
586
        assert_eq!(PUB1, 10u8 * 2);
587
        assert_eq!(PUB2, 42u16 * 2);
588
        // Verify that the default is private. If `PRIV_ON_1` was actually public in `priv1`, this
589
        // would be an ambiguous import and/or type mismatch error.
590
        assert_eq!(PRIV_ON_1, 42u16);
591
    }
592
593
    fn type_id_of_val<T: 'static>(_: &T) -> TypeId {
594
        TypeId::of::<T>()
595
    }
596
597
    #[test]
598
    fn test_offset_of() {
599
        #[repr(C)]
600
        struct Off1 {
601
            a: u8,
602
            b: u32,
603
            c: Off2,
604
            d: u64,
605
        }
606
607
        #[repr(C)]
608
        #[repr(align(128))]
609
        struct Off2 {}
610
611
        assert_eq!(core::mem::offset_of!(Off1, a), offset_of!(Off1, a));
612
        assert_eq!(core::mem::offset_of!(Off1, b), offset_of!(Off1, b));
613
        assert_eq!(core::mem::offset_of!(Off1, c), offset_of!(Off1, c));
614
        assert_eq!(core::mem::offset_of!(Off1, d), offset_of!(Off1, d));
615
    }
616
}
617
618
#[cfg(test)]
619
#[allow(unused)]
620
mod macro_checks {
621
    s! {
622
        pub struct S1 {
623
            pub a: u32,
624
            b: u32,
625
        }
626
627
        struct S1Priv {
628
            pub a: u32,
629
            b: u32,
630
        }
631
    }
632
633
    s_no_extra_traits! {
634
        pub struct S2 {
635
            pub a: u32,
636
            b: u32,
637
        }
638
639
        struct S2Priv {
640
            pub a: u32,
641
            b: u32,
642
        }
643
644
        pub union U2 {
645
            pub a: u32,
646
            b: f32,
647
        }
648
649
        union U2Priv {
650
            pub a: u32,
651
            b: f32,
652
        }
653
    }
654
}