va_list/
lib.rs

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