summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--Makefile4
-rw-r--r--src/codegen/mod.rs2
-rw-r--r--src/ir/annotations.rs2
-rw-r--r--src/ir/context.rs2
-rw-r--r--src/ir/item.rs2
-rwxr-xr-xsrc/lib.rs14
-rw-r--r--tests/support.rs108
-rw-r--r--tests/test_builtins.rs10
-rw-r--r--tests/test_cmath.rs13
-rw-r--r--tests/test_cxx.rs34
-rw-r--r--tests/test_decl.rs10
-rw-r--r--tests/test_enum.rs132
-rw-r--r--tests/test_extern.rs8
-rw-r--r--tests/test_func.rs50
-rw-r--r--tests/test_struct.rs264
-rw-r--r--tests/test_union.rs271
-rw-r--r--tests/tests.rs139
-rwxr-xr-xtests/tools/run-bindgen.py23
19 files changed, 150 insertions, 940 deletions
diff --git a/.travis.yml b/.travis.yml
index 274aefc1..70db4df3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -40,7 +40,7 @@ before_script:
script:
- cargo build --verbose --features llvm_stable
- - make test
+ - cargo test --features llvm_stable
- git add -A
- git diff @
- git diff-index --quiet HEAD
diff --git a/Makefile b/Makefile
index cad0f513..384ce323 100644
--- a/Makefile
+++ b/Makefile
@@ -12,8 +12,8 @@ $(BINDGEN):
[ -f $@ ] || cargo build --features llvm_stable
.PHONY: test
-test: regen-tests
- @echo > /dev/null
+test:
+ cargo test --features llvm_stable
.PHONY: regen-tests
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index a5159c98..5688065f 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -41,7 +41,7 @@ struct CodegenResult {
/// The set of generated function/var names, needed because in C/C++ is legal to
/// do something like:
///
- /// ```
+ /// ```c++
/// extern "C" {
/// void foo();
/// extern int bar;
diff --git a/src/ir/annotations.rs b/src/ir/annotations.rs
index cc61dbfd..64ab255d 100644
--- a/src/ir/annotations.rs
+++ b/src/ir/annotations.rs
@@ -87,7 +87,7 @@ impl Annotations {
///
/// the generated code would look something like:
///
- /// ```rust
+ /// ```c++
/// /** <div rustbindgen replaces="Bar"></div> */
/// struct Bar {
/// int x;
diff --git a/src/ir/context.rs b/src/ir/context.rs
index e6659697..da5f334f 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -421,7 +421,7 @@ impl<'ctx> BindgenContext<'ctx> {
///
/// To see an example of what this handles:
///
- /// ```
+ /// ```c++
/// template<typename T>
/// class Incomplete {
/// T p;
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 5b6297bd..4808806b 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -28,7 +28,7 @@ pub trait ItemCanonicalName {
///
/// To contrast with canonical_name, here's an example:
///
-/// ```
+/// ```c++
/// namespace foo {
/// const BAR = 3;
/// }
diff --git a/src/lib.rs b/src/lib.rs
index 64dba22c..44cadb4d 100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -294,20 +294,6 @@ impl Bindings {
}
}
-#[test]
-fn builder_state() {
- let logger = DummyLogger;
- let mut build = builder();
- {
- build.header("example.h");
- build.link_static("m");
- build.log(&logger);
- }
- assert!(build.logger.is_some());
- assert!(build.options.clang_args.binary_search(&"example.h".to_owned()).is_ok());
- assert!(build.options.links.binary_search(&("m".to_owned(), LinkType::Static)).is_ok());
-}
-
/// Determines whether the given cursor is in any of the files matched by the
/// options.
fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
diff --git a/tests/support.rs b/tests/support.rs
deleted file mode 100644
index 0ac92f5f..00000000
--- a/tests/support.rs
+++ /dev/null
@@ -1,108 +0,0 @@
-use bindgen;
-use bindgen::{Logger, BindgenOptions};
-
-use syntax::ast;
-use syntax::codemap;
-use syntax::codemap::DUMMY_SP;
-use syntax::parse;
-use syntax::parse::token;
-use syntax::print::pprust;
-use syntax::ptr::P;
-
-struct TestLogger;
-
-impl Logger for TestLogger {
- fn error(&self, msg: &str) {
- println!("err: {}", msg);
- }
-
- fn warn(&self, msg: &str) {
- println!("warn: {}", msg);
- }
-}
-
-pub fn generate_bindings(mut options: BindgenOptions,
- filename: &str)
- -> Result<Vec<P<ast::Item>>, ()> {
- if filename.ends_with("hpp") {
- options.clang_args.push("-std=c++11".to_string());
- options.clang_args.push("-Wno-narrowing".to_string());
- }
- options.clang_args.push(filename.to_string());
-
- let logger = TestLogger;
- Ok(try!(bindgen::Bindings::generate(&options, Some(&logger as &Logger), None)).into_ast())
-}
-
-pub fn assert_bind_eq(options: BindgenOptions,
- filename: &str,
- reference_items_str: &str) {
- let ext_cx = mk_dummy_ext_ctxt();
- let generated_items =
- generate_bindings(options, &format!("tests/{}", filename)[..]).unwrap();
-
- let mut parser = parse::new_parser_from_source_str(ext_cx.parse_sess(), ext_cx.cfg(), "".to_string(), reference_items_str.to_string());
- let mut reference_items = Vec::new();
- while let Ok(Some(item)) = parser.parse_item() {
- reference_items.push(item);
- }
-
- // The ast::Items themselves have insignificant (for our purposes)
- // differences that make them difficult to compare directly. So, compare
- // rendered versions, which is not beautiful, but should work.
- let reference_rendered = render_items(&reference_items);
- let generated_rendered = render_items(&generated_items);
-
- if reference_rendered != generated_rendered {
- println!("Generated bindings for {} do not match the reference bindings.", filename);
- println!("");
- println!("Generated:");
- println!("");
- println!("{}", generated_rendered);
- println!("");
- println!("Reference:");
- println!("");
- println!("{}", reference_rendered);
- panic!();
- }
-}
-
-fn render_items(items: &Vec<P<ast::Item>>) -> String {
- pprust::to_string(|s| {
- let module = ast::Mod {
- inner: DUMMY_SP,
- items: items.clone(),
- };
- s.print_mod(&module, &[])
- })
-}
-
-pub struct DummyExtCtxt {
- sess: parse::ParseSess,
-}
-
-impl DummyExtCtxt {
- pub fn cfg(&self) -> ast::CrateConfig {
- vec!()
- }
- pub fn parse_sess(&self) -> &parse::ParseSess {
- &self.sess
- }
- pub fn call_site(&self) -> codemap::Span {
- codemap::Span {
- lo: codemap::BytePos(0),
- hi: codemap::BytePos(0),
- expn_id: codemap::NO_EXPANSION
- }
- }
- pub fn ident_of(&self, s: &str) -> ast::Ident {
- token::str_to_ident(s)
- }
- pub fn name_of(&self, s: &str) -> ast::Name {
- token::intern(s)
- }
-}
-
-fn mk_dummy_ext_ctxt<'a>() -> DummyExtCtxt {
- DummyExtCtxt { sess: parse::ParseSess::new() }
-}
diff --git a/tests/test_builtins.rs b/tests/test_builtins.rs
deleted file mode 100644
index c1ddce72..00000000
--- a/tests/test_builtins.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-use bindgen;
-
-#[test]
-fn test_builtin_va_list() {
- let bindings = bindgen::builder().header("tests/headers/builtin_va_list.h")
- .emit_builtins().generate().unwrap().to_string();
- println!("{}", bindings);
- assert!(bindings.contains("__builtin_va_list"));
-}
-
diff --git a/tests/test_cmath.rs b/tests/test_cmath.rs
deleted file mode 100644
index 564e40e3..00000000
--- a/tests/test_cmath.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-// Unused until we can generate code for tests
-
-#[allow(dead_code, non_camel_case_types)]
-pub mod ffi { bindgen!("/usr/include/math.h", link = "m"); }
-
-#[test]
-fn floor_is_bound_and_callable() {
- unsafe {
- assert_eq!(ffi::floor( 2.7), 2.0);
- assert_eq!(ffi::floor(-2.7), -3.0);
- assert_eq!(ffi::floor(-0.0), 0.0);
- }
-}
diff --git a/tests/test_cxx.rs b/tests/test_cxx.rs
deleted file mode 100644
index ea4e516f..00000000
--- a/tests/test_cxx.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-use bindgen;
-use bindgen::BindgenOptions;
-use support::assert_bind_eq;
-
-fn cxx_options() -> BindgenOptions {
- let mut options = BindgenOptions::default();
- options.rename_types = false;
-
- options
-}
-
-#[test]
-fn test_cxx_class() {
- assert_bind_eq(cxx_options(), "headers/class.hpp", "
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct C {
- pub a: ::std::os::raw::c_int,
- }");
-}
-
-#[test]
-fn test_cxx_template() {
- assert_bind_eq(cxx_options(), "headers/template.hpp", "
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Foo<T> {
- pub m_member: T,
- }
- extern \"C\" {
- #[link_name = \"_Z3bar3FooIiE\"]
- pub fn bar(foo: Foo<::std::os::raw::c_int>);
- }");
-}
diff --git a/tests/test_decl.rs b/tests/test_decl.rs
deleted file mode 100644
index 6858d416..00000000
--- a/tests/test_decl.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-use support::assert_bind_eq;
-
-#[test]
-fn ptr_to_array() {
- assert_bind_eq(Default::default(), "headers/decl_ptr_to_array.h", "
- extern \"C\" {
- pub static mut foo: [::std::os::raw::c_int; 1usize];
- }
- ");
-}
diff --git a/tests/test_enum.rs b/tests/test_enum.rs
deleted file mode 100644
index 0a8a2bb8..00000000
--- a/tests/test_enum.rs
+++ /dev/null
@@ -1,132 +0,0 @@
-use bindgen::BindgenOptions;
-use support::assert_bind_eq;
-
-fn default_without_rust_enums() -> BindgenOptions {
- BindgenOptions { rust_enums: false, .. Default::default() }
-}
-
-#[test]
-fn with_simple_enum() {
- assert_bind_eq(Default::default(), "headers/enum.h", "
- #[repr(u32)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_Foo { Bar = 0, Qux = 1, }
- #[repr(i32)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_Neg { MinusOne = -1, One = 1, }
- ");
- assert_bind_eq(default_without_rust_enums(), "headers/enum.h", "
- type Enum_Foo = u32;
- const Bar: Enum_Foo = 0;
- const Qux: Enum_Foo = 1;
- type Enum_Neg = i32;
- const MinusOne: Enum_Neg = -1;
- const One: Enum_Neg = 1;
- ");
-}
-
-#[test]
-fn with_packed_enums() {
- assert_bind_eq(Default::default(), "headers/enum_packed.h", "
- #[repr(u8)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_Foo { Bar = 0, Qux = 1, }
- #[repr(i8)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_Neg { MinusOne = -1, One = 1, }
- #[repr(u16)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_Bigger { Much = 255, Larger = 256, }
- ");
- assert_bind_eq(default_without_rust_enums(), "headers/enum_packed.h", "
- type Enum_Foo = u8;
- const Bar: Enum_Foo = 0;
- const Qux: Enum_Foo = 1;
- type Enum_Neg = i8;
- const MinusOne: Enum_Neg = -1;
- const One: Enum_Neg = 1;
- type Enum_Bigger = u16;
- const Much: Enum_Bigger = 255;
- const Larger: Enum_Bigger = 256;
- ");
-}
-
-#[test]
-fn with_duplicate_enum_value() {
- assert_bind_eq(Default::default(), "headers/enum_dupe.h", "
- pub const Dupe: Enum_Foo = Enum_Foo::Bar;
- #[repr(u32)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_Foo { Bar = 1, }
- ");
- assert_bind_eq(default_without_rust_enums(), "headers/enum_dupe.h", "
- type Enum_Foo = u32;
- const Bar: Enum_Foo = 1;
- const Dupe: Enum_Foo = 1;
- ");
-}
-
-#[test]
-fn with_explicitly_typed_cxx_enum() {
- assert_bind_eq(Default::default(), "headers/enum_explicit_type.hpp", "
- #[repr(u8)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_Foo { Bar = 0, Qux = 1, }
-
- #[repr(i8)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_Neg { MinusOne = -1, One = 1, }
-
- #[repr(u16)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_Bigger { Much = 255, Larger = 256, }
-
- #[repr(i64)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_MuchLong { MuchLow = -4294967296, }
-
- #[repr(u64)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_MuchLongLong { MuchHigh = 4294967296, }
- ");
- assert_bind_eq(default_without_rust_enums(), "headers/enum_explicit_type.hpp", "
- type Enum_Foo = u8;
- const Bar: Enum_Foo = 0;
- const Qux: Enum_Foo = 1;
- type Enum_Neg = i8;
- const MinusOne: Enum_Neg = -1;
- const One: Enum_Neg = 1;
- type Enum_Bigger = u16;
- const Much: Enum_Bigger = 255;
- const Larger: Enum_Bigger = 256;
- type Enum_MuchLong = i64;
- const MuchLow: Enum_MuchLong = -4294967296;
- type Enum_MuchLongLong = u64;
- const MuchHigh: Enum_MuchLongLong = 4294967296;
- ");
-}
-
-#[test]
-fn with_overflowed_enum_value() {
- assert_bind_eq(Default::default(), "headers/overflowed_enum.hpp", "
- #[repr(u32)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_Foo {
- BAP_ARM = 9698489,
- BAP_X86 = 11960045,
- BAP_X86_64 = 3128633167,
- }
- #[repr(u16)]
- #[derive(Copy, Clone, Debug)]
- pub enum Enum_Bar { One = 1, Big = 2, }
- ");
- assert_bind_eq(default_without_rust_enums(), "headers/overflowed_enum.hpp", "
- type Enum_Foo = u32;
- const BAP_ARM: Enum_Foo = 9698489;
- const BAP_X86: Enum_Foo = 11960045;
- const BAP_X86_64: Enum_Foo = 3128633167;
- type Enum_Bar = u16;
- const One: Enum_Bar = 1;
- const Big: Enum_Bar = 2;
- ");
-}
diff --git a/tests/test_extern.rs b/tests/test_extern.rs
deleted file mode 100644
index bbe823ff..00000000
--- a/tests/test_extern.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-use support::assert_bind_eq;
-
-#[test]
-fn extern_c_in_hpp() {
- assert_bind_eq(Default::default(), "headers/extern.hpp", "
- pub type foo = unsafe extern \"C\" fn(bar: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
- ");
-}
diff --git a/tests/test_func.rs b/tests/test_func.rs
deleted file mode 100644
index b210186f..00000000
--- a/tests/test_func.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-use support::assert_bind_eq;
-
-#[test]
-fn func_ptr() {
- assert_bind_eq(Default::default(), "headers/func_ptr.h", "
- extern \"C\" {
- pub static mut foo: ::std::option::Option<
- unsafe extern \"C\" fn(x: ::std::os::raw::c_int,
- y: ::std::os::raw::c_int) -> ::std::os::raw::c_int>;
- }
- ");
-}
-
-#[test]
-fn func_ptr_in_struct() {
- assert_bind_eq(Default::default(), "headers/func_ptr_in_struct.h", "
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_Foo {
- pub bar: ::std::option::Option<
- unsafe extern \"C\" fn(x: ::std::os::raw::c_int,
- y: ::std::os::raw::c_int) -> Enum_baz>,
- }
- ");
-}
-
-#[test]
-fn func_proto() {
- assert_bind_eq(Default::default(), "headers/func_proto.h", "
- pub type foo = unsafe extern \"C\" fn(bar: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
- ");
-}
-
-#[test]
-fn with_func_ptr_arg() {
- assert_bind_eq(Default::default(), "headers/func_with_func_ptr_arg.h", "
- extern \"C\" {
- pub fn foo(bar: ::std::option::Option<unsafe extern \"C\" fn()>);
- }
- ");
-}
-
-#[test]
-fn with_array_arg() {
- assert_bind_eq(Default::default(), "headers/func_with_array_arg.h", "
- extern \"C\" {
- pub fn f(x: *mut ::std::os::raw::c_int);
- }
- ");
-}
diff --git a/tests/test_struct.rs b/tests/test_struct.rs
deleted file mode 100644
index 47e165f1..00000000
--- a/tests/test_struct.rs
+++ /dev/null
@@ -1,264 +0,0 @@
-use support::assert_bind_eq;
-
-#[test]
-fn with_anon_struct() {
- assert_bind_eq(Default::default(), "headers/struct_with_anon_struct.h", "
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_foo {
- pub bar: Struct_struct_with_anon_struct_h_unnamed_1,
- }
-
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_struct_with_anon_struct_h_unnamed_1 {
- pub a: ::std::os::raw::c_int,
- pub b: ::std::os::raw::c_int,
- }");
-}
-
-#[test]
-fn with_anon_struct_array() {
- assert_bind_eq(Default::default(), "headers/struct_with_anon_struct_array.h", "
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_foo {
- pub bar: [Struct_struct_with_anon_struct_array_h_unnamed_1; 2usize],
- pub baz: [[[Struct_struct_with_anon_struct_array_h_unnamed_2; 4usize]; 3usize]; 2usize],
- }
-
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_struct_with_anon_struct_array_h_unnamed_1 {
- pub a: ::std::os::raw::c_int,
- pub b: ::std::os::raw::c_int,
- }
-
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_struct_with_anon_struct_array_h_unnamed_2 {
- pub a: ::std::os::raw::c_int,
- pub b: ::std::os::raw::c_int,
- }");
-}
-
-#[test]
-fn with_anon_struct_pointer() {
- assert_bind_eq(Default::default(), "headers/struct_with_anon_struct_pointer.h", "
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_foo {
- pub bar: *mut Struct_struct_with_anon_struct_pointer_h_unnamed_1,
- }
-
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_struct_with_anon_struct_pointer_h_unnamed_1 {
- pub a: ::std::os::raw::c_int,
- pub b: ::std::os::raw::c_int,
- }");
-}
-
-#[test]
-fn with_anon_union() {
- assert_bind_eq(Default::default(), "headers/struct_with_anon_union.h", "
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_foo {
- pub bar: Union_unnamed1,
- }
- impl ::std::clone::Clone for Struct_foo {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Struct_foo {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- #[repr(C)]
- #[derive(Copy, Clone, Debug)]
- pub struct Union_unnamed1 {
- pub _bindgen_data_: [u32; 1usize],
- }
- impl Union_unnamed1 {
- pub unsafe fn a(&mut self) -> *mut ::std::os::raw::c_uint {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn b(&mut self) -> *mut ::std::os::raw::c_ushort {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- }
- ");
-}
-
-#[test]
-fn with_anon_unnamed_struct() {
- assert_bind_eq(Default::default(), "headers/struct_with_anon_unnamed_struct.h", "
- #[repr(C)]
- #[derive(Copy)]
- #[derive(Debug)]
- pub struct Struct_foo {
- pub _bindgen_data_1_: [u32; 2usize],
- }
- impl Struct_foo {
- pub unsafe fn a(&mut self) -> *mut ::std::os::raw::c_uint {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn b(&mut self) -> *mut ::std::os::raw::c_uint {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
- ::std::mem::transmute(raw.offset(4))
- }
- }
- impl ::std::clone::Clone for Struct_foo {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Struct_foo {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- ");
-}
-
-#[test]
-fn with_anon_unnamed_union() {
- assert_bind_eq(Default::default(), "headers/struct_with_anon_unnamed_union.h", "
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_foo {
- pub _bindgen_data_1_: [u32; 1usize],
- }
- impl Struct_foo {
- pub unsafe fn a(&mut self) -> *mut ::std::os::raw::c_uint {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn b(&mut self) -> *mut ::std::os::raw::c_ushort {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
- ::std::mem::transmute(raw.offset(0))
- }
- }
- impl ::std::clone::Clone for Struct_foo {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Struct_foo {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- ");
-}
-
-#[test]
-fn with_nesting() {
- assert_bind_eq(Default::default(), "headers/struct_with_nesting.h", "
- #[repr(C)]
- #[derive(Copy)]
- #[derive(Debug)]
- pub struct Struct_foo {
- pub a: ::std::os::raw::c_uint,
- pub _bindgen_data_1_: [u32; 1usize],
- }
- impl Struct_foo {
- pub unsafe fn b(&mut self) -> *mut ::std::os::raw::c_uint {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn c1(&mut self) -> *mut ::std::os::raw::c_ushort {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn c2(&mut self) -> *mut ::std::os::raw::c_ushort {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
- ::std::mem::transmute(raw.offset(2))
- }
- pub unsafe fn d1(&mut self) -> *mut ::std::os::raw::c_uchar {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn d2(&mut self) -> *mut ::std::os::raw::c_uchar {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
- ::std::mem::transmute(raw.offset(1))
- }
- pub unsafe fn d3(&mut self) -> *mut ::std::os::raw::c_uchar {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
- ::std::mem::transmute(raw.offset(2))
- }
- pub unsafe fn d4(&mut self) -> *mut ::std::os::raw::c_uchar {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_1_);
- ::std::mem::transmute(raw.offset(3))
- }
- }
- impl ::std::clone::Clone for Struct_foo {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Struct_foo {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- ");
-}
-
-#[test]
-fn containing_fwd_decl_struct() {
- assert_bind_eq(Default::default(), "headers/struct_containing_forward_declared_struct.h", "
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_a {
- pub val_a: *mut Struct_b,
- }
-
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_b {
- pub val_b: ::std::os::raw::c_int,
- }
- ");
-}
-
-#[test]
-fn with_bitfields() {
- assert_bind_eq(Default::default(), "headers/struct_with_bitfields.h", "
- #[repr(C)]
- #[derive(Copy)]
- #[derive(Debug)]
- pub struct Struct_bitfield {
- pub _bindgen_bitfield_1_: ::std::os::raw::c_ushort,
- pub e: ::std::os::raw::c_int,
- pub _bindgen_bitfield_2_: ::std::os::raw::c_uint,
- pub _bindgen_bitfield_3_: ::std::os::raw::c_uint,
- }
-
- impl ::std::clone::Clone for Struct_bitfield {
- fn clone(&self) -> Self { *self }
- }
-
- impl ::std::default::Default for Struct_bitfield {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- ");
-}
-
-#[test]
-fn with_fwd_decl_struct() {
- assert_bind_eq(Default::default(), "headers/forward_declared_struct.h", "
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_a {
- pub b: ::std::os::raw::c_int,
- }
-
- #[repr(C)]
- #[derive(Copy, Clone)]
- pub struct Struct_c {
- pub d: ::std::os::raw::c_int,
- }");
-}
-
-
-#[test]
-fn packed_struct() {
- assert_bind_eq(Default::default(), "headers/struct_with_packing.h", "
- #[repr(C, packed)]
- #[derive(Copy, Clone)]
- pub struct Struct_a {
- pub b: ::std::os::raw::c_char,
- pub c: ::std::os::raw::c_short,
- }");
-}
diff --git a/tests/test_union.rs b/tests/test_union.rs
deleted file mode 100644
index f35e325a..00000000
--- a/tests/test_union.rs
+++ /dev/null
@@ -1,271 +0,0 @@
-use support::assert_bind_eq;
-
-#[test]
-fn with_anon_struct() {
- assert_bind_eq(Default::default(), "headers/union_with_anon_struct.h", "
- #[repr(C)]
- #[derive(Copy)]
- #[derive(Debug)]
- pub struct Union_foo {
- pub _bindgen_data_: [u32; 2usize],
- }
- impl Union_foo {
- pub unsafe fn bar(&mut self) -> *mut Struct_Unnamed1 {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- }
- impl ::std::clone::Clone for Union_foo {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Union_foo {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- #[repr(C)]
- #[derive(Copy)]
- #[derive(Debug)]
- pub struct Struct_Unnamed1 {
- pub a: ::std::os::raw::c_uint,
- pub b: ::std::os::raw::c_uint,
- }
- impl ::std::clone::Clone for Struct_Unnamed1 {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Struct_Unnamed1 {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- ");
-}
-
-#[test]
-fn with_anon_struct_bitfield() {
- assert_bind_eq(Default::default(), "headers/union_with_anon_struct_bitfield.h", "
- #[repr(C)]
- #[derive(Copy)]
- #[derive(Debug)]
- pub struct Union_foo {
- pub _bindgen_data_: [u32; 1usize],
- }
-
- impl Union_foo {
- pub unsafe fn a(&mut self) -> *mut ::std::os::raw::c_int {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- }
-
- impl ::std::clone::Clone for Union_foo {
- fn clone(&self) -> Self { *self }
- }
-
- impl ::std::default::Default for Union_foo {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- ");
-}
-
-#[test]
-fn with_anon_union() {
- assert_bind_eq(Default::default(), "headers/union_with_anon_union.h", "
- #[repr(C)]
- #[derive(Copy)]
- #[derive(Debug)]
- pub struct Union_foo {
- pub _bindgen_data_: [u32; 1usize],
- }
- impl Union_foo {
- pub unsafe fn bar(&mut self) -> *mut Union_Unnamed1 {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- }
- impl ::std::clone::Clone for Union_foo {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Union_foo {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- #[repr(C)]
- #[derive(Copy)]
- #[derive(Debug)]
- pub struct Union_Unnamed1 {
- pub _bindgen_data_: [u32; 1usize],
- }
- impl Union_Unnamed1 {
- pub unsafe fn a(&mut self) -> *mut ::std::os::raw::c_uint {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn b(&mut self) -> *mut ::std::os::raw::c_ushort {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- }
- impl ::std::clone::Clone for Union_Unnamed1 {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Union_Unnamed1 {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- ");
-}
-
-#[test]
-fn with_anon_unnamed_struct() {
- assert_bind_eq(Default::default(), "headers/union_with_anon_unnamed_struct.h", "
- #[repr(C)]
- #[derive(Copy)]
- #[derive(Debug)]
- pub struct Union_pixel {
- pub _bindgen_data_: [u32; 1usize],
- }
- impl Union_pixel {
- pub unsafe fn rgba(&mut self) -> *mut ::std::os::raw::c_uint {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn r(&mut self) -> *mut ::std::os::raw::c_uchar {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn g(&mut self) -> *mut ::std::os::raw::c_uchar {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(1))
- }
- pub unsafe fn b(&mut self) -> *mut ::std::os::raw::c_uchar {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(2))
- }
- pub unsafe fn a(&mut self) -> *mut ::std::os::raw::c_uchar {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(3))
- }
- }
- impl ::std::clone::Clone for Union_pixel {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Union_pixel {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- ");
-}
-
-#[test]
-fn with_anon_unnamed_union() {
- assert_bind_eq(Default::default(), "headers/union_with_anon_unnamed_union.h", "
- #[repr(C)]
- #[derive(Copy)]
- #[derive(Debug)]
- pub struct Union_foo {
- pub _bindgen_data_: [u32; 1usize],
- }
- impl Union_foo {
- pub unsafe fn a(&mut self) -> *mut ::std::os::raw::c_uint {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn b(&mut self) -> *mut ::std::os::raw::c_ushort {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn c(&mut self) -> *mut ::std::os::raw::c_uchar {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- }
- impl ::std::clone::Clone for Union_foo {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Union_foo {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- ");
-}
-
-#[test]
-fn with_nesting() {
- assert_bind_eq(Default::default(), "headers/union_with_nesting.h", "
- #[repr(C)]
- #[derive(Copy)]
- #[derive(Debug)]
- pub struct Union_foo {
- pub _bindgen_data_: [u32; 1usize],
- }
- impl Union_foo {
- pub unsafe fn a(&mut self) -> *mut ::std::os::raw::c_uint {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn b1(&mut self) -> *mut ::std::os::raw::c_ushort {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn b2(&mut self) -> *mut ::std::os::raw::c_ushort {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn c1(&mut self) -> *mut ::std::os::raw::c_ushort {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(2))
- }
- pub unsafe fn c2(&mut self) -> *mut ::std::os::raw::c_ushort {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(2))
- }
- }
- impl ::std::clone::Clone for Union_foo {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Union_foo {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- ");
-}
-
-#[test]
-fn with_derive_debug() {
- assert_bind_eq(Default::default(), "headers/union_with_big_member.h", "
- #[repr(C)]
- #[derive(Copy)]
- pub struct Union_WithBigArray {
- pub _bindgen_data_: [u32; 33usize],
- }
- impl Union_WithBigArray {
- pub unsafe fn a(&mut self) -> *mut ::std::os::raw::c_int {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn b(&mut self) -> *mut [::std::os::raw::c_int; 33usize] {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- }
- impl ::std::clone::Clone for Union_WithBigArray {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Union_WithBigArray {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- #[repr(C)]
- #[derive(Copy)]
- pub struct Union_WithBigMember {
- pub _bindgen_data_: [u32; 33usize],
- }
- impl Union_WithBigMember {
- pub unsafe fn a(&mut self) -> *mut ::std::os::raw::c_int {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- pub unsafe fn b(&mut self) -> *mut Union_WithBigArray {
- let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
- ::std::mem::transmute(raw.offset(0))
- }
- }
- impl ::std::clone::Clone for Union_WithBigMember {
- fn clone(&self) -> Self { *self }
- }
- impl ::std::default::Default for Union_WithBigMember {
- fn default() -> Self { unsafe { ::std::mem::zeroed() } }
- }
- ");
-}
diff --git a/tests/tests.rs b/tests/tests.rs
index 2e7072fe..aaa7628e 100644
--- a/tests/tests.rs
+++ b/tests/tests.rs
@@ -1,17 +1,122 @@
-#![allow(dead_code)]
-
-extern crate bindgen;
-extern crate syntex_syntax as syntax;
-
-mod support;
-
-// Unused until we can generate code for tests
-//mod test_cmath;
-mod test_cxx;
-mod test_enum;
-mod test_decl;
-mod test_extern;
-mod test_func;
-mod test_struct;
-mod test_union;
-mod test_builtins;
+use std::env;
+use std::fs;
+use std::io::Read;
+use std::path::{Path, PathBuf};
+use std::process;
+
+fn spawn_run_bindgen<P, Q, R>(run_bindgen: P, bindgen: Q, header: R) -> process::Child
+ where P: AsRef<Path>,
+ Q: AsRef<Path>,
+ R: AsRef<Path>
+{
+ let run_bindgen = run_bindgen.as_ref();
+ let bindgen = bindgen.as_ref();
+ let header = header.as_ref();
+
+ // Convert from "tests/headers/foo.hpp" to "tests/expectations/foo.rs" by
+ // saving the filename, popping off "headers/foo.hpp", pushing
+ // "expectations", pushing the saved filename, and finally modifying the
+ // extension.
+
+ let mut expected = PathBuf::from(header);
+ let file_name = expected.file_name()
+ .expect("Should have filename")
+ .to_os_string();
+ expected.pop();
+ expected.pop();
+ expected.push("expectations");
+ expected.push(file_name);
+ expected.set_extension("rs");
+
+ process::Command::new(run_bindgen)
+ .arg(bindgen)
+ .arg(header)
+ .stdout(process::Stdio::piped())
+ .stderr(process::Stdio::piped())
+ .arg(expected)
+ .spawn()
+ .expect("Should be able to spawn run-bindgen.py child process")
+}
+
+#[test]
+fn run_bindgen_tests() {
+ let crate_root = env::var("CARGO_MANIFEST_DIR")
+ .expect("should have CARGO_MANIFEST_DIR environment variable");
+
+ let mut run_bindgen = PathBuf::from(&crate_root);
+ run_bindgen.push("tests");
+ run_bindgen.push("tools");
+ run_bindgen.push("run-bindgen.py");
+
+ let mut bindgen = PathBuf::from(&crate_root);
+ bindgen.push("target");
+ bindgen.push("debug");
+ bindgen.push("bindgen");
+ if !bindgen.is_file() {
+ panic!("{} is not a file! Build bindgen before running tests.",
+ bindgen.display());
+ }
+
+ let mut headers_dir = PathBuf::from(&crate_root);
+ headers_dir.push("tests");
+ headers_dir.push("headers");
+
+ let entries = fs::read_dir(&headers_dir)
+ .expect("Should read directory")
+ .map(|result| result.expect("Should read directory entry"));
+
+ let tests = entries.filter(|entry| {
+ match entry.path().extension().map(|s| s.to_str()) {
+ Some(Some("h")) |
+ Some(Some("hpp")) => true,
+ _ => false,
+ }
+ });
+
+ // First spawn all child processes and collect them, then wait on each
+ // one. This runs the tests in parallel rather than serially.
+
+ let children: Vec<_> = tests.map(|entry| {
+ let child = spawn_run_bindgen(run_bindgen.clone(), bindgen.clone(), entry.path());
+ (entry.path(), child)
+ })
+ .collect();
+
+ let failures: Vec<_> = children.into_iter()
+ .filter_map(|(path, mut child)| {
+ let passed = child.wait()
+ .expect("Should wait on child process")
+ .success();
+
+ if passed { None } else { Some((path, child)) }
+ })
+ .collect();
+
+ let num_failures = failures.len();
+
+ for (path, child) in failures {
+ println!("FAIL: {}", path.display());
+
+ let mut buf = String::new();
+
+ child.stdout
+ .expect("should have stdout piped")
+ .read_to_string(&mut buf)
+ .expect("should read child's stdout");
+ for line in buf.lines() {
+ println!("child stdout> {}", line);
+ }
+
+ child.stderr
+ .expect("should have stderr piped")
+ .read_to_string(&mut buf)
+ .expect("should read child's stderr");
+ for line in buf.lines() {
+ println!("child stderr> {}", line);
+ }
+ }
+
+ if num_failures > 0 {
+ panic!("{} test failures!", num_failures);
+ }
+}
diff --git a/tests/tools/run-bindgen.py b/tests/tools/run-bindgen.py
index 0d8ed580..656c6ae5 100755
--- a/tests/tools/run-bindgen.py
+++ b/tests/tools/run-bindgen.py
@@ -19,7 +19,7 @@ if len(sys.argv) != 4:
flags = ["--no-unstable-rust"]
-with open(sys.argv[2]) as f:
+with open(c_path) as f:
for line in f:
if line.startswith(BINDGEN_FLAGS_PREFIX):
flags.extend(line.strip().split(BINDGEN_FLAGS_PREFIX)[1].split(" "))
@@ -40,11 +40,30 @@ env = os.environ.copy()
# https://forums.developer.apple.com/thread/9233
if "DYLD_LIBRARY_PATH" not in env and "LIBCLANG_PATH" in env:
env["DYLD_LIBRARY_PATH"] = env["LIBCLANG_PATH"]
-subprocess.check_call(base_command, cwd=os.getcwd(), env=env)
+# If the rust file already exists, read it now so we can compare its contents
+# before and after.
+original_rust_contents = None
+if os.path.isfile(rust_path):
+ with open(rust_path) as f:
+ original_rust_contents = f.read()
+
+subprocess.check_call(base_command, cwd=os.getcwd(), env=env)
name = None
with tempfile.NamedTemporaryFile(delete=False) as tests:
name = tests.name
subprocess.check_call(["rustc", "--test", sys.argv[3], "-o", tests.name])
subprocess.check_call([tests.name])
+
+if original_rust_contents is not None:
+ new_rust_contents = None
+ with open(rust_path) as f:
+ new_rust_contents = f.read()
+ if new_rust_contents != original_rust_contents:
+ print("Generated rust bindings do not match expectation!")
+ print("Expected rust bindings:")
+ print(original_rust_contents)
+ print("Actual rust bindings:")
+ print(new_rust_contents)
+ sys.exit(1)