Move scanf unit tests to normal C tests
This commit is contained in:
@@ -235,11 +235,9 @@ pub unsafe extern "C" fn execve(
|
||||
}
|
||||
|
||||
let mut len = 0;
|
||||
for i in 0.. {
|
||||
if (*argv.offset(i)).is_null() {
|
||||
len = i;
|
||||
break;
|
||||
}
|
||||
while !(*argv.offset(len)).is_null() {
|
||||
len += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
let mut args: Vec<[usize; 2]> = Vec::with_capacity(len as usize);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,9 @@
|
||||
success!
|
||||
2, { sa: 12, ia: 345, ib: 0, ic: 0, fa: 0, da: 0, ptr: 0x0, char: a, string: }
|
||||
3, { sa: 12, ia: 18, ib: 837, ic: 8, fa: 0, da: 0, ptr: 0x0, char: a, string: }
|
||||
2, { sa: 12, ia: 18, ib: 837, ic: 8, fa: 0.10000000149011612, da: 0.2, ptr: 0x0, char: a, string: }
|
||||
1, { sa: 12, ia: 18, ib: 837, ic: 8, fa: 0.10000000149011612, da: 0.2, ptr: 0xabcdef, char: a, string: }
|
||||
1, { sa: 12, ia: 18, ib: 837, ic: 8, fa: 0.10000000149011612, da: 0.2, ptr: 0xabcdef, char: a, string: Hello }
|
||||
1, { sa: 12, ia: 15, ib: 837, ic: 8, fa: 0.10000000149011612, da: 0.2, ptr: 0xabcdef, char: a, string: Hello }
|
||||
2, { sa: 12, ia: 15, ib: 837, ic: 8, fa: 0.10000000149011612, da: 0.2, ptr: 0xabcdef, char: h, string: elllo }
|
||||
1, { sa: 12, ia: 0, ib: 8, ic: 8, fa: 0.10000000149011612, da: 0.2, ptr: 0xabcdef, char: h, string: elllo }
|
||||
0, { sa: 12, ia: 0, ib: 8, ic: 8, fa: 0.10000000149011612, da: 0.2, ptr: 0xabcdef, char: h, string: elllo }
|
||||
|
||||
+36
-13
@@ -1,16 +1,39 @@
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
int val = sscanf("123 0x321", "%d %i", &a, &b);
|
||||
if (val != 2) {
|
||||
printf("error: %d\n", val);
|
||||
} else {
|
||||
if (a == 123 && b == 0x321) {
|
||||
puts("success!");
|
||||
} else {
|
||||
printf("incorrect results: { a: %d, b: %x }\n", a, b);
|
||||
}
|
||||
}
|
||||
struct params {
|
||||
short sa;
|
||||
int ia;
|
||||
int ib;
|
||||
int ic;
|
||||
float fa;
|
||||
double da;
|
||||
int *ptr;
|
||||
char c;
|
||||
char string[20];
|
||||
};
|
||||
|
||||
void test(char* fmt_in, char* input, struct params *p, ...) {
|
||||
va_list args;
|
||||
va_start(args, p);
|
||||
int ret = vsscanf(input, fmt_in, args);
|
||||
va_end(args);
|
||||
|
||||
printf(
|
||||
"%d, { sa: %hhd, ia: %d, ib: %d, ic: %d, fa: %f, da: %lf, ptr: %p, char: %c, string: %s }\n",
|
||||
ret, p->sa, p->ia, p->ib, p->ic, p->fa, p->da, p->ptr, p->c, p->string
|
||||
);
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
struct params p = { .c = 'a' };
|
||||
|
||||
test("%hhd %d", "12 345", &p, &p.sa, &p.ia);
|
||||
test("%x %i %i", "12 0x345 010", &p, &p.ia, &p.ib, &p.ic);
|
||||
test("%f.%lf", "0.1.0.2", &p, &p.fa, &p.da);
|
||||
test("%p", "0xABCDEF", &p, &p.ptr);
|
||||
test("%s", "Hello World", &p, &p.string);
|
||||
test("%3i", "0xFF", &p, &p.ia);
|
||||
test("%c%3c", "hello", &p, &p.c, &p.string);
|
||||
test("test: %2i%n", "test: 0xFF", &p, &p.ia, &p.ib);
|
||||
test("hello world%%", "hello world%", &p);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user