lib.rs 2.11 KB
Newer Older
John Hodge's avatar
John Hodge committed
1 2 3 4
/*!
 * C FFI - va_list support
 *
 * This crate provides an interface for rust code to read values passed in C's va_list type.
5
 *
Jeremy Soller's avatar
Jeremy Soller committed
6
 * ## Example
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * In C Code
 * ```c
 * #include <stdint.h>
 * #include <stdarg.h>
 * extern void print_ints_va(uint32_t count, va_list args);
 * extern void print_ints(uint32_t count, ...)
 * {
 *   va_list args;
 *   va_start(args, count);
 *   print_ints_va(count, args);
 *   va_end(args);
 * }
 * ```
 *
 * In rust code:
22 23
 * ```rust
 * extern crate va_list;
Jeremy Soller's avatar
Jeremy Soller committed
24
 *
25
 * #[no_mangle]
John Hodge's avatar
John Hodge committed
26
 * extern "C" fn print_ints_va(count: u32, mut args: va_list::VaList)
27
 * {
John Hodge's avatar
John Hodge committed
28 29 30 31 32
 *   unsafe {
 *     for i in (0 .. count) {
 *       println!("{}: {}", i, args.get::<i32>());
 *     }
 *   }
33 34
 * }
 * ```
John Hodge's avatar
John Hodge committed
35
 */
Dan Robertson's avatar
Dan Robertson committed
36 37 38
#![cfg_attr(feature = "no_std", no_std)]
#![crate_type = "lib"]
#![crate_name = "va_list"]
John Hodge's avatar
John Hodge committed
39

Dan Robertson's avatar
Dan Robertson committed
40
#[cfg(feature = "no_std")]
41
#[doc(hidden)]
42
mod std {
Dan Robertson's avatar
Dan Robertson committed
43
    pub use core::{mem, ptr};
44 45
}

46
// x86_64 on unix platforms is _usually_ ELF.
Dan Robertson's avatar
Dan Robertson committed
47 48
#[cfg(all(target_arch = "x86_64",
          any(target_family = "unix", target_os = "redox", target_os = "tifflin")))]
Dan Robertson's avatar
Dan Robertson committed
49 50
#[path = "impl-x86_64-elf.rs"]
mod imp;
51

52
//// x86_64 on windows is special
Dan Robertson's avatar
Dan Robertson committed
53 54 55
#[cfg(all(target_arch = "x86_64", target_family = "windows"))]
#[path = "impl-x86_64-win64.rs"]
mod imp;
56

57
// x86+unix = cdecl
Dan Robertson's avatar
Dan Robertson committed
58 59 60
#[cfg(all(target_arch = "x86", target_family = "unix"))]
#[path = "impl-x86-sysv.rs"]
mod imp;
John Hodge's avatar
John Hodge committed
61

Dan Robertson's avatar
Dan Robertson committed
62 63 64 65 66
// aarch64
#[cfg(all(target_arch = "aarch64", any(target_family = "unix", target_os = "redox")))]
#[path = "impl-aarch64-elf.rs"]
mod imp;

67
// arm+unix = cdecl
Dan Robertson's avatar
Dan Robertson committed
68 69 70
#[cfg(all(target_arch = "arm", target_family = "unix"))]
#[path = "impl-arm-sysv.rs"]
mod imp;
John Hodge's avatar
John Hodge committed
71

72
/// Rust version of C's `va_list` type from the `stdarg.h` header
John Hodge's avatar
John Hodge committed
73 74
#[repr(C)]
pub struct VaList {
Dan Robertson's avatar
Dan Robertson committed
75
    internal: imp::VaList,
John Hodge's avatar
John Hodge committed
76
}
77 78

/// Core type as passed though the FFI
Dan Robertson's avatar
Dan Robertson committed
79 80 81 82 83 84 85
impl VaList {
    /// Read a value from the VaList.
    ///
    /// Users should take care that they are reading the correct type
    pub unsafe fn get<T: VaPrimitive>(&mut self) -> T {
        T::get(&mut self.internal)
    }
86
}
John Hodge's avatar
John Hodge committed
87 88

/// Trait implemented on types that can be read from a va_list
Dan Robertson's avatar
Dan Robertson committed
89 90 91
pub trait VaPrimitive: 'static {
    #[doc(hidden)]
    unsafe fn get(&mut imp::VaList) -> Self;
John Hodge's avatar
John Hodge committed
92
}