va_list/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
//!
//! C FFI - va_list support
//!
//! This crate provides an interface for rust code to read values passed in C's va_list type.
//!
//! ## Example
//! 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:
//!
//! ```rust
//! extern crate va_list;
//!
//! #[no_mangle]
//! extern "C" fn print_ints_va(count: u32, mut args: va_list::VaList)
//! {
//! unsafe {
//! for i in (0 .. count) {
//! println!("{}: {}", i, args.get::<i32>());
//! }
//! }
//! }
//! ```
//!
#![no_std]
// Helper macro that allows build-testing all platforms at once
macro_rules! def_platforms {
(
$(
if $conds:meta {
mod $name:ident = $path:expr;
}
)*
) => {
#[cfg(build_check_all)]
#[path="."]
mod build_all {
$(
#[path="."]
mod $name {
#[path=$path]
mod imp;
#[allow(dead_code)]
mod wrapper;
#[allow(dead_code)]
use self::wrapper::*;
}
)*
}
$(
#[cfg($conds)]
#[path=$path]
mod imp;
)*
}
}
def_platforms! {
// x86+unix = cdecl
if all(target_arch = "x86", target_family = "unix") {
mod x86_unix = "impl-cdecl32.rs";
}
// arm+unix = cdecl
if all(target_arch = "arm", target_family = "unix") {
mod arm_sysv = "impl-cdecl32.rs";
}
// x86_64 on unix platforms is _usually_ the ELF/itanium ABI
if all(
target_arch = "x86_64",
any(target_family = "unix", target_os = "redox", target_os = "tifflin")
) {
mod x8664_elf = "impl-x86_64-elf.rs";
}
// x86_64/arm64 windows = cdecl (64-bit)
if all(any(target_arch = "x86_64", target_arch = "aarch64"), target_family = "windows") {
mod x8664_win64 = "impl-cdecl64.rs";
}
// aarch64 elf ABI
if all(
target_arch = "aarch64",
any(target_family = "unix", target_os = "redox"),
not(any(target_os = "macos", target_os = "ios")), // Apple uses a 64-bit cdecl instead
) {
mod aarch64_elf = "impl-aarch64-elf.rs";
}
// aarch64+macos = cdecl (64-bit)
if all(target_arch = "aarch64", any(target_os = "macos", target_os = "ios")) {
mod aarch64_macos = "impl-cdecl64.rs";
}
}
/// Wrapper logic, shared for testing
mod wrapper;
pub use self::wrapper::*;