#![crate_type = "staticlib"] #![feature(c_variadic)] use std::ffi::VaList; use std::ffi::{c_char, c_double, c_int, c_long, c_longlong}; use std::ffi::{CStr, CString}; macro_rules! continue_if { ($cond:expr) => { if !($cond) { return 0xff; } }; } unsafe fn compare_c_str(ptr: *const c_char, val: &str) -> bool { let cstr0 = CStr::from_ptr(ptr); match CString::new(val) { Ok(cstr1) => &*cstr1 == cstr0, Err(_) => false, } } #[no_mangle] pub unsafe extern "C" fn check_list_0(mut ap: VaList) -> usize { continue_if!(ap.arg::() == 1); continue_if!(ap.arg::() == 2); continue_if!(ap.arg::() == 3); 0 } #[no_mangle] pub unsafe extern "C" fn check_list_1(mut ap: VaList) -> usize { continue_if!(ap.arg::() == -1); continue_if!(ap.arg::() == 'A' as c_char); continue_if!(ap.arg::() == '4' as c_char); continue_if!(ap.arg::() == ';' as c_char); continue_if!(ap.arg::() == 0x32); continue_if!(ap.arg::() == 0x10000001); continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Valid!")); 0 } #[no_mangle] pub unsafe extern "C" fn check_list_2(mut ap: VaList) -> usize { continue_if!(ap.arg::().floor() == 3.14f64.floor()); continue_if!(ap.arg::() == 12); continue_if!(ap.arg::() == 'a' as c_char); continue_if!(ap.arg::().floor() == 6.18f64.floor()); continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello")); continue_if!(ap.arg::() == 42); continue_if!(compare_c_str(ap.arg::<*const c_char>(), "World")); 0 } #[no_mangle] pub unsafe extern "C" fn check_list_copy_0(mut ap: VaList) -> usize { continue_if!(ap.arg::().floor() == 6.28f64.floor()); continue_if!(ap.arg::() == 16); continue_if!(ap.arg::() == 'A' as c_char); continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Skip Me!")); ap.with_copy( |mut ap| { if compare_c_str(ap.arg::<*const c_char>(), "Correct") { 0 } else { 0xff } }, ) } #[no_mangle] pub unsafe extern "C" fn check_varargs_0(_: c_int, mut ap: ...) -> usize { continue_if!(ap.arg::() == 42); continue_if!(compare_c_str(ap.arg::<*const c_char>(), "Hello, World!")); 0 } #[no_mangle] pub unsafe extern "C" fn check_varargs_1(_: c_int, mut ap: ...) -> usize { continue_if!(ap.arg::().floor() == 3.14f64.floor()); continue_if!(ap.arg::() == 12); continue_if!(ap.arg::() == 'A' as c_char); continue_if!(ap.arg::() == 1); 0 } #[no_mangle] pub unsafe extern "C" fn check_varargs_2(_: c_int, _ap: ...) -> usize { 0 } #[no_mangle] pub unsafe extern "C" fn check_varargs_3(_: c_int, mut ap: ...) -> usize { continue_if!(ap.arg::() == 1); continue_if!(ap.arg::() == 2); continue_if!(ap.arg::() == 3); continue_if!(ap.arg::() == 4); continue_if!(ap.arg::() == 5); continue_if!(ap.arg::() == 6); continue_if!(ap.arg::() == 7); continue_if!(ap.arg::() == 8); continue_if!(ap.arg::() == 9); continue_if!(ap.arg::() == 10); 0 } #[no_mangle] pub unsafe extern "C" fn check_varargs_4(_: c_double, mut ap: ...) -> usize { continue_if!(ap.arg::() == 1.0); continue_if!(ap.arg::() == 2.0); continue_if!(ap.arg::() == 3.0); continue_if!(ap.arg::() == 4.0); continue_if!(ap.arg::() == 5.0); continue_if!(ap.arg::() == 6.0); continue_if!(ap.arg::() == 7.0); continue_if!(ap.arg::() == 8.0); continue_if!(ap.arg::() == 9.0); continue_if!(ap.arg::() == 10.0); 0 } #[no_mangle] pub unsafe extern "C" fn check_varargs_5(_: c_int, mut ap: ...) -> usize { continue_if!(ap.arg::() == 1.0); continue_if!(ap.arg::() == 1); continue_if!(ap.arg::() == 2.0); continue_if!(ap.arg::() == 2); continue_if!(ap.arg::() == 3.0); continue_if!(ap.arg::() == 3); continue_if!(ap.arg::() == 4.0); continue_if!(ap.arg::() == 4); continue_if!(ap.arg::() == 5); continue_if!(ap.arg::() == 5.0); continue_if!(ap.arg::() == 6); continue_if!(ap.arg::() == 6.0); continue_if!(ap.arg::() == 7); continue_if!(ap.arg::() == 7.0); continue_if!(ap.arg::() == 8); continue_if!(ap.arg::() == 8.0); continue_if!(ap.arg::() == 9); continue_if!(ap.arg::() == 9.0); continue_if!(ap.arg::() == 10); continue_if!(ap.arg::() == 10.0); 0 }