From 9771b45e0ead3fff4187b1674de9dc84d39dbda2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 5 Jul 2017 15:29:02 -0700 Subject: [PATCH] Add support for testing `str` consts --- src/lib.rs | 73 +++++++++++++++++++++++++++++++++--------- testcrate/src/t1.h | 1 + testcrate/src/t1.rs | 1 + testcrate/src/t2.h | 1 + testcrate/src/t2.rs | 1 + testcrate/tests/all.rs | 1 + 6 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1857d14..f476590 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -683,6 +683,9 @@ impl TestGenerator { fn pretty(&self) -> String; } + impl<'a> Pretty for &'a str { + fn pretty(&self) -> String { format!("{:?}", self) } + } impl Pretty for *const T { fn pretty(&self) -> String { format!("{:?}", self) } } @@ -994,6 +997,9 @@ impl<'a> Generator<'a> { } fn rust_ty_to_c_ty(&self, mut rust_ty: &str) -> String { + if rust_ty == "&str" { + return "char*".to_string(); + } let mut cty = self.rust2c(&rust_ty.replace("*mut ", "") .replace("*const ", "")); while rust_ty.starts_with("*") { @@ -1014,30 +1020,47 @@ impl<'a> Generator<'a> { } let cty = self.rust_ty_to_c_ty(rust_ty); - t!(writeln!(self.c, r#" static {cty} __test_const_{name}_val = {name}; {cty}* __test_const_{name}(void) {{ return &__test_const_{name}_val; }} "#, name = name, cty = cty)); - t!(writeln!(self.rust, r#" - fn const_{name}() {{ - extern {{ - fn __test_const_{name}() -> *const {ty}; + + if rust_ty == "&str" { + t!(writeln!(self.rust, r#" + fn const_{name}() {{ + extern {{ + fn __test_const_{name}() -> *const *const u8; + }} + let val = {name}; + unsafe {{ + let ptr = *__test_const_{name}(); + let c = ::std::ffi::CStr::from_ptr(ptr as *const _); + let c = c.to_str().expect("const {name} not utf8"); + same(val, c, "{name} string"); + }} }} - let val = {name}; - unsafe {{ - let ptr1 = &val as *const _ as *const u8; - let ptr2 = __test_const_{name}() as *const u8; - for i in 0..mem::size_of::<{ty}>() {{ - let i = i as isize; - same(*ptr1.offset(i), *ptr2.offset(i), - &format!("{name} value at byte {{}}", i)); + "#, name = name)); + } else { + t!(writeln!(self.rust, r#" + fn const_{name}() {{ + extern {{ + fn __test_const_{name}() -> *const {ty}; + }} + let val = {name}; + unsafe {{ + let ptr1 = &val as *const _ as *const u8; + let ptr2 = __test_const_{name}() as *const u8; + for i in 0..mem::size_of::<{ty}>() {{ + let i = i as isize; + same(*ptr1.offset(i), *ptr2.offset(i), + &format!("{name} value at byte {{}}", i)); + }} }} }} - }} - "#, ty = rust_ty, name = name)); + "#, ty = rust_ty, name = name)); + } self.tests.push(format!("const_{}", name)); } @@ -1149,6 +1172,26 @@ impl<'a> Generator<'a> { assert!(rust); format!("[{}; {}]", self.ty2name(t, rust), self.expr2str(e)) } + ast::TyKind::Rptr(_, ast::MutTy { + ref ty, + mutbl: ast::Mutability::Immutable, + }) => { + let path = match ty.node { + ast::TyKind::Path(_, ref p) => p, + _ => panic!("unknown ty {:?}", ty), + }; + if path.segments.len() != 1 { + panic!("unknown ty {:?}", ty) + } + if &*path.segments[0].identifier.name.as_str() != "str" { + panic!("unknown ty {:?}", ty) + } + if rust { + format!("&str") + } else { + format!("char*") + } + } _ => panic!("unknown ty {:?}", ty), } } diff --git a/testcrate/src/t1.h b/testcrate/src/t1.h index 0fc6c0d..d32cd94 100644 --- a/testcrate/src/t1.h +++ b/testcrate/src/t1.h @@ -3,6 +3,7 @@ typedef int32_t T1Foo; #define T1N 5 +#define T1S "foo" struct T1Bar { int32_t a; diff --git a/testcrate/src/t1.rs b/testcrate/src/t1.rs index a234840..0e48f0b 100644 --- a/testcrate/src/t1.rs +++ b/testcrate/src/t1.rs @@ -3,6 +3,7 @@ use libc::*; pub type T1Foo = i32; +pub const T1S: &'static str = "foo"; pub const T1N: i32 = 5; diff --git a/testcrate/src/t2.h b/testcrate/src/t2.h index 85ac048..0ef984f 100644 --- a/testcrate/src/t2.h +++ b/testcrate/src/t2.h @@ -12,3 +12,4 @@ struct T2Baz { static void T2a(void) {} #define T2C 4 +#define T2S "a" diff --git a/testcrate/src/t2.rs b/testcrate/src/t2.rs index d68dd03..768f645 100644 --- a/testcrate/src/t2.rs +++ b/testcrate/src/t2.rs @@ -8,6 +8,7 @@ pub struct T2Baz { } pub const T2C: i32 = 5; +pub const T2S: &'static str = "b"; extern { pub fn T2a(); diff --git a/testcrate/tests/all.rs b/testcrate/tests/all.rs index 32ddf18..a605366 100644 --- a/testcrate/tests/all.rs +++ b/testcrate/tests/all.rs @@ -35,6 +35,7 @@ fn t2() { "bad field type b of T2Baz", "bad T2a function pointer", "bad T2C value at byte 0", + "bad T2S string", ]; let mut errors = errors.iter().cloned().collect::>();