diff options
| author | Simonas Kazlauskas <git@kazlauskas.me> | 2016-05-27 03:05:52 +0300 |
|---|---|---|
| committer | Simonas Kazlauskas <git@kazlauskas.me> | 2016-05-27 03:05:52 +0300 |
| commit | f18118702f088ee2d4726e1e1e6e87d17b105f5d (patch) | |
| tree | eff009ce8b5b08284957574ac802e6764e167ffe | |
| parent | da66f2fd8cab261911163ece04d5c15a13cf5e58 (diff) | |
| download | rust-f18118702f088ee2d4726e1e1e6e87d17b105f5d.tar.gz rust-f18118702f088ee2d4726e1e1e6e87d17b105f5d.zip | |
Rewrite variadic-ffi pass to use test helper
The sprintf used in this test previously isn’t available on some versions of MSVC. Fixes #32305
| -rw-r--r-- | src/test/run-pass/variadic-ffi.rs | 67 |
1 files changed, 23 insertions, 44 deletions
diff --git a/src/test/run-pass/variadic-ffi.rs b/src/test/run-pass/variadic-ffi.rs index abd1709825c..fad360329ff 100644 --- a/src/test/run-pass/variadic-ffi.rs +++ b/src/test/run-pass/variadic-ffi.rs @@ -8,60 +8,39 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-msvc -- sprintf isn't a symbol in msvcrt? maybe a #define? - -#![feature(libc, std_misc)] - -extern crate libc; - -use std::ffi::{CStr, CString}; -use libc::{c_char, c_int}; - - +#[link(name = "rust_test_helpers")] extern { - fn sprintf(s: *mut c_char, format: *const c_char, ...) -> c_int; -} - -unsafe fn check<T, F>(expected: &str, f: F) where F: FnOnce(*mut c_char) -> T { - let mut x = [0 as c_char; 50]; - f(&mut x[0] as *mut c_char); - assert_eq!(expected.as_bytes(), CStr::from_ptr(x.as_ptr()).to_bytes()); + fn rust_interesting_average(_: i64, ...) -> f64; } pub fn main() { - + // Call without variadic arguments unsafe { - // Call with just the named parameter - let c = CString::new(&b"Hello World\n"[..]).unwrap(); - check("Hello World\n", |s| sprintf(s, c.as_ptr())); - - // Call with variable number of arguments - let c = CString::new(&b"%d %f %c %s\n"[..]).unwrap(); - check("42 42.500000 a %d %f %c %s\n\n", |s| { - sprintf(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr()); - }); + assert!(rust_interesting_average(0).is_nan()); + } - // Make a function pointer - let x: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int = sprintf; + // Call with direct arguments + unsafe { + assert_eq!(rust_interesting_average(1, 10, 10.0) as i64, 20); + } - // A function that takes a function pointer - unsafe fn call(fp: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int) { - // Call with just the named parameter - let c = CString::new(&b"Hello World\n"[..]).unwrap(); - check("Hello World\n", |s| fp(s, c.as_ptr())); + // Call with named arguments, variable number of them + let (x1, x2, x3, x4) = (10, 10.0, 20, 20.0); + unsafe { + assert_eq!(rust_interesting_average(2, x1, x2, x3, x4) as i64, 30); + } - // Call with variable number of arguments - let c = CString::new(&b"%d %f %c %s\n"[..]).unwrap(); - check("42 42.500000 a %d %f %c %s\n\n", |s| { - fp(s, c.as_ptr(), 42, 42.5f64, 'a' as c_int, c.as_ptr()); - }); - } + // A function that takes a function pointer + unsafe fn call(fp: unsafe extern fn(i64, ...) -> f64) { + let (x1, x2, x3, x4) = (10, 10.0, 20, 20.0); + assert_eq!(fp(2, x1, x2, x3, x4) as i64, 30); + } - // Pass sprintf directly - call(sprintf); + unsafe { + call(rust_interesting_average); - // Pass sprintf indirectly + // Make a function pointer, pass indirectly + let x: unsafe extern fn(i64, ...) -> f64 = rust_interesting_average; call(x); } - } |
