summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.rs15
-rw-r--r--tests/expectations/tests/test_mixed_header_and_header_contents.rs111
-rw-r--r--tests/tests.rs54
3 files changed, 178 insertions, 2 deletions
diff --git a/src/lib.rs b/src/lib.rs
index b9e1bcc5..2329dee9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -596,8 +596,16 @@ impl Builder {
///
/// The file `name` will be added to the clang arguments.
pub fn header_contents(mut self, name: &str, contents: &str) -> Builder {
+ // Apparently clang relies on having virtual FS correspondent to
+ // the real one, so we need absolute paths here
+ let absolute_path = env::current_dir()
+ .expect("Cannot retrieve current directory")
+ .join(name)
+ .to_str()
+ .expect("Cannot convert current directory name to string")
+ .to_owned();
self.input_header_contents
- .push((name.into(), contents.into()));
+ .push((absolute_path, contents.into()));
self
}
@@ -2154,7 +2162,10 @@ impl Bindings {
}
}
- for f in options.input_unsaved_files.iter() {
+ for (idx, f) in options.input_unsaved_files.iter().enumerate() {
+ if idx != 0 || options.input_header.is_some() {
+ options.clang_args.push("-include".to_owned());
+ }
options.clang_args.push(f.name.to_str().unwrap().to_owned())
}
diff --git a/tests/expectations/tests/test_mixed_header_and_header_contents.rs b/tests/expectations/tests/test_mixed_header_and_header_contents.rs
new file mode 100644
index 00000000..c97be9b0
--- /dev/null
+++ b/tests/expectations/tests/test_mixed_header_and_header_contents.rs
@@ -0,0 +1,111 @@
+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,
+ >;
+}
+extern "C" {
+ pub fn bar(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn bar2(b: *const ::std::os::raw::c_char) -> f32;
+}
+pub type Char = ::std::os::raw::c_char;
+pub type SChar = ::std::os::raw::c_schar;
+pub type UChar = ::std::os::raw::c_uchar;
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct Test {
+ pub ch: ::std::os::raw::c_char,
+ pub u: ::std::os::raw::c_uchar,
+ pub d: ::std::os::raw::c_schar,
+ pub cch: ::std::os::raw::c_char,
+ pub cu: ::std::os::raw::c_uchar,
+ pub cd: ::std::os::raw::c_schar,
+ pub Cch: Char,
+ pub Cu: UChar,
+ pub Cd: SChar,
+ pub Ccch: Char,
+ pub Ccu: UChar,
+ pub Ccd: SChar,
+}
+#[test]
+fn bindgen_test_layout_Test() {
+ assert_eq!(
+ ::std::mem::size_of::<Test>(),
+ 12usize,
+ concat!("Size of: ", stringify!(Test))
+ );
+ assert_eq!(
+ ::std::mem::align_of::<Test>(),
+ 1usize,
+ concat!("Alignment of ", stringify!(Test))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).ch as *const _ as usize },
+ 0usize,
+ concat!("Offset of field: ", stringify!(Test), "::", stringify!(ch))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).u as *const _ as usize },
+ 1usize,
+ concat!("Offset of field: ", stringify!(Test), "::", stringify!(u))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).d as *const _ as usize },
+ 2usize,
+ concat!("Offset of field: ", stringify!(Test), "::", stringify!(d))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).cch as *const _ as usize },
+ 3usize,
+ concat!("Offset of field: ", stringify!(Test), "::", stringify!(cch))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).cu as *const _ as usize },
+ 4usize,
+ concat!("Offset of field: ", stringify!(Test), "::", stringify!(cu))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).cd as *const _ as usize },
+ 5usize,
+ concat!("Offset of field: ", stringify!(Test), "::", stringify!(cd))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).Cch as *const _ as usize },
+ 6usize,
+ concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cch))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).Cu as *const _ as usize },
+ 7usize,
+ concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cu))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).Cd as *const _ as usize },
+ 8usize,
+ concat!("Offset of field: ", stringify!(Test), "::", stringify!(Cd))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).Ccch as *const _ as usize },
+ 9usize,
+ concat!(
+ "Offset of field: ",
+ stringify!(Test),
+ "::",
+ stringify!(Ccch)
+ )
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).Ccu as *const _ as usize },
+ 10usize,
+ concat!("Offset of field: ", stringify!(Test), "::", stringify!(Ccu))
+ );
+ assert_eq!(
+ unsafe { &(*(::std::ptr::null::<Test>())).Ccd as *const _ as usize },
+ 11usize,
+ concat!("Offset of field: ", stringify!(Test), "::", stringify!(Ccd))
+ );
+}
diff --git a/tests/tests.rs b/tests/tests.rs
index 8b5a91f7..cd621177 100644
--- a/tests/tests.rs
+++ b/tests/tests.rs
@@ -474,6 +474,60 @@ fn test_multiple_header_calls_in_builder() {
}
#[test]
+fn test_multiple_header_contents() {
+ let actual = builder()
+ .header_contents("test.h", "int foo(const char* a);")
+ .header_contents("test2.h", "float foo2(const char* b);")
+ .clang_arg("--target=x86_64-unknown-linux")
+ .generate()
+ .unwrap()
+ .to_string();
+
+ let (actual, stderr) = rustfmt(actual);
+ println!("{}", stderr);
+
+ let (expected, _) = rustfmt(
+ "extern \"C\" {
+ pub fn foo2(b: *const ::std::os::raw::c_char) -> f32;
+}
+extern \"C\" {
+ pub fn foo(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int;
+}
+"
+ .to_string(),
+ );
+
+ assert_eq!(expected, actual);
+}
+
+#[test]
+fn test_mixed_header_and_header_contents() {
+ let actual = builder()
+ .header(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/tests/headers/func_ptr.h"
+ ))
+ .header(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/char.h"))
+ .header_contents("test.h", "int bar(const char* a);")
+ .header_contents("test2.h", "float bar2(const char* b);")
+ .clang_arg("--target=x86_64-unknown-linux")
+ .generate()
+ .unwrap()
+ .to_string();
+
+ let (actual, stderr) = rustfmt(actual);
+ println!("{}", stderr);
+
+ let expected = include_str!(concat!(
+ env!("CARGO_MANIFEST_DIR"),
+ "/tests/expectations/tests/test_mixed_header_and_header_contents.rs"
+ ));
+ let (expected, _) = rustfmt(expected.to_string());
+
+ assert_eq!(expected, actual);
+}
+
+#[test]
// Doesn't support executing sh file on Windows.
// We may want to implement it in Rust so that we support all systems.
#[cfg(not(target_os = "windows"))]