summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2018-08-13 17:03:10 +0200
committerEmilio Cobos Álvarez <emilio@crisal.io>2018-08-13 17:06:42 +0200
commit9c8ea7f362768c7644866cf4aaccdbd32c22fec0 (patch)
tree548e85f2a010080b54a477141a6a3ad90a2cdbb2
parentd991134c1d0034db749a3b3aa573b4032ee3e5de (diff)
Add ability to blacklist functions.
Fixes #1336
-rw-r--r--src/ir/context.rs14
-rw-r--r--src/ir/item.rs20
-rw-r--r--src/lib.rs29
-rw-r--r--src/options.rs13
-rw-r--r--tests/expectations/tests/blacklist-function.rs26
-rw-r--r--tests/headers/blacklist-function.hpp11
6 files changed, 97 insertions, 16 deletions
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 30c45dcc..ee15bcf5 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -2113,21 +2113,9 @@ If you encounter an error missing from this list, please file an issue or a PR!"
}
}
- /// Is the item with the given `name` blacklisted? Or is the item with the given
- /// `name` and `id` replaced by another type, and effectively blacklisted?
- pub fn blacklisted_by_name<Id: Into<ItemId>>(&self, path: &[String], id: Id) -> bool {
- let id = id.into();
- debug_assert!(
- self.in_codegen_phase(),
- "You're not supposed to call this yet"
- );
- self.options.blacklisted_types.matches(&path[1..].join("::")) ||
- self.is_replaced_type(path, id)
- }
-
/// Has the item with the given `name` and `id` been replaced by another
/// type?
- fn is_replaced_type<Id: Into<ItemId>>(&self, path: &[String], id: Id) -> bool {
+ pub fn is_replaced_type<Id: Into<ItemId>>(&self, path: &[String], id: Id) -> bool {
let id = id.into();
match self.replacements.get(path) {
Some(replaced_by) if *replaced_by != id => true,
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 91ec22b3..927322eb 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -631,8 +631,24 @@ impl Item {
ctx.in_codegen_phase(),
"You're not supposed to call this yet"
);
- self.annotations.hide() ||
- ctx.blacklisted_by_name(&self.canonical_path(ctx), self.id)
+ if self.annotations.hide() {
+ return true;
+ }
+
+ let path = self.canonical_path(ctx);
+ let name = path[1..].join("::");
+ match self.kind {
+ ItemKind::Type(..) => {
+ ctx.options().blacklisted_types.matches(&name) ||
+ ctx.is_replaced_type(&path, self.id)
+ }
+ ItemKind::Function(..) => {
+ ctx.options().blacklisted_functions.matches(&name)
+ }
+ // TODO: Add constant / namespace blacklisting?
+ ItemKind::Var(..) |
+ ItemKind::Module(..) => false,
+ }
}
/// Is this a reference to another type?
diff --git a/src/lib.rs b/src/lib.rs
index 606671a2..f12b3db5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -290,6 +290,20 @@ impl Builder {
})
.count();
+ self.options
+ .blacklisted_functions
+ .get_items()
+ .iter()
+ .map(|item| {
+ output_vector.push("--blacklist-function".into());
+ output_vector.push(
+ item.trim_left_matches("^")
+ .trim_right_matches("$")
+ .into(),
+ );
+ })
+ .count();
+
if !self.options.layout_tests {
output_vector.push("--no-layout-tests".into());
}
@@ -705,6 +719,13 @@ impl Builder {
self
}
+ /// Hide the given function from the generated bindings. Regular expressions
+ /// are supported.
+ pub fn blacklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
+ self.options.blacklisted_functions.insert(arg);
+ self
+ }
+
/// Treat the given type as opaque in the generated bindings. Regular
/// expressions are supported.
pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
@@ -1260,6 +1281,10 @@ struct BindgenOptions {
/// anywhere in the generated code.
blacklisted_types: RegexSet,
+ /// The set of functions that have been blacklisted and should not appear
+ /// in the generated code.
+ blacklisted_functions: RegexSet,
+
/// The set of types that should be treated as opaque structures in the
/// generated code.
opaque_types: RegexSet,
@@ -1469,6 +1494,7 @@ impl BindgenOptions {
self.whitelisted_types.build();
self.whitelisted_functions.build();
self.blacklisted_types.build();
+ self.blacklisted_functions.build();
self.opaque_types.build();
self.bitfield_enums.build();
self.constified_enums.build();
@@ -1498,9 +1524,10 @@ impl Default for BindgenOptions {
let rust_target = RustTarget::default();
BindgenOptions {
- rust_target: rust_target,
+ rust_target,
rust_features: rust_target.into(),
blacklisted_types: Default::default(),
+ blacklisted_functions: Default::default(),
opaque_types: Default::default(),
rustfmt_path: Default::default(),
whitelisted_types: Default::default(),
diff --git a/src/options.rs b/src/options.rs
index 5169fb9a..c65a80fc 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -71,6 +71,13 @@ where
.takes_value(true)
.multiple(true)
.number_of_values(1),
+ Arg::with_name("blacklist-function")
+ .long("blacklist-function")
+ .help("Mark <function> as hidden.")
+ .value_name("function")
+ .takes_value(true)
+ .multiple(true)
+ .number_of_values(1),
Arg::with_name("no-layout-tests")
.long("no-layout-tests")
.help("Avoid generating layout tests for any type."),
@@ -350,6 +357,12 @@ where
}
}
+ if let Some(hidden_functions) = matches.values_of("blacklist-function") {
+ for fun in hidden_functions {
+ builder = builder.blacklist_function(fun);
+ }
+ }
+
if matches.is_present("builtins") {
builder = builder.emit_builtins();
}
diff --git a/tests/expectations/tests/blacklist-function.rs b/tests/expectations/tests/blacklist-function.rs
new file mode 100644
index 00000000..b1d55643
--- /dev/null
+++ b/tests/expectations/tests/blacklist-function.rs
@@ -0,0 +1,26 @@
+/* automatically generated by rust-bindgen */
+
+#![allow(
+ dead_code,
+ non_snake_case,
+ non_camel_case_types,
+ non_upper_case_globals
+)]
+
+#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
+pub mod root {
+ #[allow(unused_imports)]
+ use self::super::root;
+ pub mod foo {
+ #[allow(unused_imports)]
+ use self::super::super::root;
+ }
+ pub mod bar {
+ #[allow(unused_imports)]
+ use self::super::super::root;
+ extern "C" {
+ #[link_name = "\u{1}_ZN3bar18NamespacedFunctionEv"]
+ pub fn NamespacedFunction();
+ }
+ }
+}
diff --git a/tests/headers/blacklist-function.hpp b/tests/headers/blacklist-function.hpp
new file mode 100644
index 00000000..c4a923fc
--- /dev/null
+++ b/tests/headers/blacklist-function.hpp
@@ -0,0 +1,11 @@
+// bindgen-flags: --blacklist-function "ExternFunction" --blacklist-function "foo::NamespacedFunction" --enable-cxx-namespaces
+
+extern "C" void ExternFunction();
+
+namespace foo {
+ void NamespacedFunction();
+}
+
+namespace bar {
+ void NamespacedFunction();
+}