|
@@ -423,174 +423,3 @@ pub unsafe fn scanf<R: Read>(r: R, format: *const c_char, ap: VaList) -> c_int {
|
|
|
Err(n) => n,
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-#[cfg(test)]
|
|
|
-pub trait VaPrimitive {
|
|
|
- fn as_mut_ptr(&mut self) -> *mut c_void;
|
|
|
-}
|
|
|
-#[cfg(test)]
|
|
|
-macro_rules! va_primitives {
|
|
|
- ($($type:ty),+) => {
|
|
|
- $(impl VaPrimitive for $type {
|
|
|
- fn as_mut_ptr(&mut self) -> *mut c_void {
|
|
|
- self as *mut _ as *mut c_void
|
|
|
- }
|
|
|
- })+
|
|
|
- }
|
|
|
-}
|
|
|
-#[cfg(test)]
|
|
|
-va_primitives!(
|
|
|
- c_uchar,
|
|
|
- c_ushort,
|
|
|
- c_uint,
|
|
|
- c_ulong,
|
|
|
- c_char,
|
|
|
- c_short,
|
|
|
- c_int,
|
|
|
- c_long,
|
|
|
- c_float,
|
|
|
- c_double,
|
|
|
- *mut c_void
|
|
|
-);
|
|
|
-
|
|
|
-#[cfg(test)]
|
|
|
-trait FromVoidPtr {
|
|
|
- fn from_void_ptr(ptr: *mut c_void) -> Self;
|
|
|
-}
|
|
|
-#[cfg(test)]
|
|
|
-macro_rules! from_void_ptr {
|
|
|
- ($($type:ty),+) => {
|
|
|
- $(impl FromVoidPtr for *mut $type {
|
|
|
- fn from_void_ptr(ptr: *mut c_void) -> Self {
|
|
|
- ptr as *mut _ as Self
|
|
|
- }
|
|
|
- })+
|
|
|
- }
|
|
|
-}
|
|
|
-#[cfg(test)]
|
|
|
-from_void_ptr!(
|
|
|
- c_uchar,
|
|
|
- c_ushort,
|
|
|
- c_uint,
|
|
|
- c_ulong,
|
|
|
- c_char,
|
|
|
- c_short,
|
|
|
- c_int,
|
|
|
- c_long,
|
|
|
- c_float,
|
|
|
- c_double,
|
|
|
- size_t,
|
|
|
- ssize_t,
|
|
|
- *mut c_void
|
|
|
-);
|
|
|
-
|
|
|
-#[cfg(test)]
|
|
|
-pub struct VaList<'a> {
|
|
|
- args: &'a mut [&'a mut VaPrimitive],
|
|
|
- i: usize,
|
|
|
-}
|
|
|
-#[cfg(test)]
|
|
|
-impl<'a> VaList<'a> {
|
|
|
- pub fn new(args: &'a mut [&'a mut VaPrimitive]) -> VaList<'a> {
|
|
|
- VaList { args: args, i: 0 }
|
|
|
- }
|
|
|
- pub fn get<T: FromVoidPtr>(&mut self) -> T {
|
|
|
- let ptr = T::from_void_ptr(self.args[self.i].as_mut_ptr());
|
|
|
- self.i += 1;
|
|
|
- ptr
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-#[cfg(test)]
|
|
|
-mod tests {
|
|
|
- use super::*;
|
|
|
- use core::ptr;
|
|
|
- use platform::StringReader;
|
|
|
-
|
|
|
- fn scanf<'a>(format: &str, args: &'a mut [&'a mut VaPrimitive], input: &str) -> c_int {
|
|
|
- unsafe {
|
|
|
- let mut format = format.to_string();
|
|
|
- let format = format.as_bytes_mut();
|
|
|
- let format = format.as_mut_ptr();
|
|
|
- let out = super::inner_scanf(
|
|
|
- StringReader(input.as_bytes()),
|
|
|
- format as *mut c_char,
|
|
|
- VaList::new(args),
|
|
|
- ).expect("running test scanf failed");
|
|
|
- out
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- #[test]
|
|
|
- fn ints() {
|
|
|
- let mut a: c_char = 0;
|
|
|
- let mut b: c_int = 0;
|
|
|
- assert_eq!(scanf("%hhd %d\0", &mut [&mut a, &mut b], "12 345"), 2);
|
|
|
- assert_eq!(a, 12);
|
|
|
- assert_eq!(b, 345);
|
|
|
- }
|
|
|
- #[test]
|
|
|
- fn formats() {
|
|
|
- let mut a: c_uint = 0;
|
|
|
- let mut b: c_int = 0;
|
|
|
- let mut c: c_int = 0;
|
|
|
- assert_eq!(
|
|
|
- scanf("%x %i %i\0", &mut [&mut a, &mut b, &mut c], "12 0x345 010"),
|
|
|
- 3
|
|
|
- );
|
|
|
- assert_eq!(a, 0x12);
|
|
|
- assert_eq!(b, 0x345);
|
|
|
- assert_eq!(c, 0o10);
|
|
|
- }
|
|
|
- #[test]
|
|
|
- fn floats() {
|
|
|
- let mut a: c_float = 0.0;
|
|
|
- let mut b: c_double = 0.0;
|
|
|
- assert_eq!(scanf("%f.%lf\0", &mut [&mut a, &mut b], "0.1.0.2"), 2);
|
|
|
- assert_eq!(a, 0.1);
|
|
|
- assert_eq!(b, 0.2);
|
|
|
- }
|
|
|
- #[test]
|
|
|
- fn pointer() {
|
|
|
- let mut a: *mut c_void = ptr::null_mut();
|
|
|
- assert_eq!(scanf("%p\0", &mut [&mut a], "0xABCDEF"), 1);
|
|
|
- assert_eq!(a as usize, 0xABCDEF);
|
|
|
- }
|
|
|
- #[test]
|
|
|
- fn string() {
|
|
|
- let mut a = [1u8; 10];
|
|
|
- assert_eq!(scanf("%s\0", &mut [&mut (a[0])], "Hello World"), 1);
|
|
|
- assert_eq!(&a[..6], b"Hello\0");
|
|
|
- assert_eq!(a[6..], [1; 4]); // nothing else was modified
|
|
|
- }
|
|
|
- #[test]
|
|
|
- fn width() {
|
|
|
- let mut a: c_int = 0;
|
|
|
- assert_eq!(scanf("%3i\0", &mut [&mut a], "0xFF"), 1);
|
|
|
- assert_eq!(a, 0xF);
|
|
|
- }
|
|
|
- #[test]
|
|
|
- fn chars() {
|
|
|
- let mut a: u8 = 0;
|
|
|
- let mut b = [1u8; 5];
|
|
|
- assert_eq!(scanf("%c%3c\0", &mut [&mut a, &mut (b[0])], "hello"), 2);
|
|
|
- assert_eq!(a, b'h');
|
|
|
- assert_eq!(&b[..3], b"ell");
|
|
|
- assert_eq!(&b[3..5], [1; 2]); // nothing else was modified, no trailing NUL-byte
|
|
|
- }
|
|
|
- #[test]
|
|
|
- fn count() {
|
|
|
- let mut a: c_int = 0;
|
|
|
- let mut b: c_int = 0;
|
|
|
- assert_eq!(
|
|
|
- scanf("test: %2i%n\0", &mut [&mut a, &mut b], "test: 0xFF"),
|
|
|
- 1
|
|
|
- );
|
|
|
- assert_eq!(a, 0);
|
|
|
- assert_eq!(b, 8);
|
|
|
- }
|
|
|
- #[test]
|
|
|
- fn literal() {
|
|
|
- assert_eq!(scanf("hello world%%\0", &mut [], "hello world%"), 0);
|
|
|
- }
|
|
|
-}
|