diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-08-13 17:03:10 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-08-13 17:06:42 +0200 |
commit | 9c8ea7f362768c7644866cf4aaccdbd32c22fec0 (patch) | |
tree | 548e85f2a010080b54a477141a6a3ad90a2cdbb2 | |
parent | d991134c1d0034db749a3b3aa573b4032ee3e5de (diff) |
Add ability to blacklist functions.
Fixes #1336
-rw-r--r-- | src/ir/context.rs | 14 | ||||
-rw-r--r-- | src/ir/item.rs | 20 | ||||
-rw-r--r-- | src/lib.rs | 29 | ||||
-rw-r--r-- | src/options.rs | 13 | ||||
-rw-r--r-- | tests/expectations/tests/blacklist-function.rs | 26 | ||||
-rw-r--r-- | tests/headers/blacklist-function.hpp | 11 |
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? @@ -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(); +} |