1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 use std::ffi::{self, CString};
14 use libc::{c_char, c_int};
16 // ignore-fast doesn't like extern crate
19 fn sprintf(s: *mut c_char, format: *const c_char, ...) -> c_int;
22 unsafe fn check<T, F>(expected: &str, f: F) where F: FnOnce(*mut c_char) -> T {
23 let mut x = [0 as c_char; 50];
24 f(&mut x[0] as *mut c_char);
25 assert_eq!(expected.as_bytes(), ffi::c_str_to_bytes(&x.as_ptr()));
31 // Call with just the named parameter
32 let c = CString::from_slice(b"Hello World\n");
33 check("Hello World\n", |s| sprintf(s, c.as_ptr()));
35 // Call with variable number of arguments
36 let c = CString::from_slice(b"%d %f %c %s\n");
37 check("42 42.500000 a %d %f %c %s\n\n", |s| {
38 sprintf(s, c.as_ptr(), 42i, 42.5f64, 'a' as c_int, c.as_ptr());
41 // Make a function pointer
42 let x: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int = sprintf;
44 // A function that takes a function pointer
45 unsafe fn call(p: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int) {
46 // Call with just the named parameter
47 let c = CString::from_slice(b"Hello World\n");
48 check("Hello World\n", |s| sprintf(s, c.as_ptr()));
50 // Call with variable number of arguments
51 let c = CString::from_slice(b"%d %f %c %s\n");
52 check("42 42.500000 a %d %f %c %s\n\n", |s| {
53 sprintf(s, c.as_ptr(), 42i, 42.5f64, 'a' as c_int, c.as_ptr());
57 // Pass sprintf directly
60 // Pass sprintf indirectly