1#![allow(dead_code)]
2
3extern crate libc;
4
5#[macro_export]
28macro_rules! to_va_list {
29 ($func:expr, $($args:expr),*) => {{
30 #[inline(always)]
31 unsafe fn should_be_in_unsafe_block() {}
32 should_be_in_unsafe_block();
33
34 unsafe extern "C" fn call_func(f: *mut libc::c_void, ap: $crate::va_list) {
35 let f: &Box<Fn($crate::va_list) + 'static> = std::mem::transmute(f);
36 f(ap);
37 }
38
39 let fu = $func;
40 let wrap = $crate::Wrap {
41 f: std::mem::transmute(call_func as usize),
42 c: $crate::convert_closure(fu),
43 };
44 $crate::create_va_list(Box::into_raw(Box::new(wrap)), $($args),*);
45 }};
46 ($func:expr) => {{
47 #[inline(always)]
48 unsafe fn should_be_in_unsafe_block() {}
49 should_be_in_unsafe_block();
50
51 unsafe extern "C" fn call_func(f: *mut libc::c_void, ap: $crate::va_list) {
52 let f: &Box<Fn($crate::va_list) + 'static> = std::mem::transmute(f);
53 f(ap);
54 }
55
56 let fu = $func;
57 let wrap = $crate::Wrap {
58 f: std::mem::transmute(call_func as usize),
59 c: $crate::convert_closure(fu),
60 };
61 $crate::create_va_list(Box::into_raw(Box::new(wrap)));
62 }}
63}
64
65
66#[repr(C)]
67#[doc(hidden)]
68pub struct Wrap {
69 pub f: extern "C" fn(*mut libc::c_void, va_list),
70 pub c: *mut libc::c_void,
71}
72
73extern "C" {
74 #[allow(improper_ctypes)]
75 #[doc(hidden)]
76 pub fn create_va_list(w: *mut Wrap, ...);
77}
78
79#[doc(hidden)]
80pub fn convert_closure<F: Fn(va_list) + 'static>(f: F) -> *mut libc::c_void {
81 let f: Box<Box<Fn(va_list) + 'static>> = Box::new(Box::new(f));
82 Box::into_raw(f) as *mut _
83}
84
85#[doc(hidden)]
86#[allow(non_camel_case_types)]
87pub enum _va_list {}
88
89#[allow(non_camel_case_types)]
90pub type va_list = *mut _va_list;