diff options
-rw-r--r-- | libbindgen/Cargo.toml | 2 | ||||
-rw-r--r-- | libbindgen/src/lib.rs | 38 | ||||
-rw-r--r-- | libbindgen/src/regex_set.rs | 55 |
3 files changed, 55 insertions, 40 deletions
diff --git a/libbindgen/Cargo.toml b/libbindgen/Cargo.toml index dfaba98b..cbe3b13f 100644 --- a/libbindgen/Cargo.toml +++ b/libbindgen/Cargo.toml @@ -30,7 +30,7 @@ clang-sys = { version = "0.12", features = ["runtime", "clang_3_9"] } lazy_static = "0.2.1" rustc-serialize = "0.3.19" syntex_syntax = "0.50" -regex = "0.1" +regex = "0.2" [dependencies.aster] features = ["with-syntex"] diff --git a/libbindgen/src/lib.rs b/libbindgen/src/lib.rs index 375fd212..1834b3f2 100644 --- a/libbindgen/src/lib.rs +++ b/libbindgen/src/lib.rs @@ -83,7 +83,6 @@ use ir::item::Item; use parse::{ClangItemParser, ParseError}; use regex_set::RegexSet; -use std::borrow::Borrow; use std::fs::OpenOptions; use std::io::{self, Write}; use std::path::Path; @@ -184,35 +183,35 @@ impl Builder { } /// Hide the given type from the generated bindings. - pub fn hide_type<T: Borrow<str>>(mut self, arg: T) -> Builder { - self.options.hidden_types.insert(&arg); + pub fn hide_type<T: AsRef<str>>(mut self, arg: T) -> Builder { + self.options.hidden_types.insert(arg); self } /// Treat the given type as opaque in the generated bindings. - pub fn opaque_type<T: Borrow<str>>(mut self, arg: T) -> Builder { - self.options.opaque_types.insert(&arg); + pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder { + self.options.opaque_types.insert(arg); self } /// Whitelist the given type so that it (and all types that it transitively /// refers to) appears in the generated bindings. - pub fn whitelisted_type<T: Borrow<str>>(mut self, arg: T) -> Builder { - self.options.whitelisted_types.insert(&arg); + pub fn whitelisted_type<T: AsRef<str>>(mut self, arg: T) -> Builder { + self.options.whitelisted_types.insert(arg); self } /// Whitelist the given function so that it (and all types that it /// transitively refers to) appears in the generated bindings. - pub fn whitelisted_function<T: Borrow<str>>(mut self, arg: T) -> Builder { - self.options.whitelisted_functions.insert(&arg); + pub fn whitelisted_function<T: AsRef<str>>(mut self, arg: T) -> Builder { + self.options.whitelisted_functions.insert(arg); self } /// Whitelist the given variable so that it (and all types that it /// transitively refers to) appears in the generated bindings. - pub fn whitelisted_var<T: Borrow<str>>(mut self, arg: T) -> Builder { - self.options.whitelisted_vars.insert(&arg); + pub fn whitelisted_var<T: AsRef<str>>(mut self, arg: T) -> Builder { + self.options.whitelisted_vars.insert(arg); self } @@ -220,8 +219,8 @@ impl Builder { /// bitfield-like. /// /// This makes bindgen generate a type that isn't a rust `enum`. - pub fn bitfield_enum<T: Borrow<str>>(mut self, arg: T) -> Builder { - self.options.bitfield_enums.insert(&arg); + pub fn bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder { + self.options.bitfield_enums.insert(arg); self } @@ -451,6 +450,17 @@ pub struct BindgenOptions { pub codegen_config: CodegenConfig, } +impl BindgenOptions { + fn build(&mut self) { + self.whitelisted_vars.build(); + self.whitelisted_types.build(); + self.whitelisted_functions.build(); + self.hidden_types.build(); + self.opaque_types.build(); + self.bitfield_enums.build(); + } +} + impl Default for BindgenOptions { fn default() -> BindgenOptions { BindgenOptions { @@ -543,6 +553,8 @@ impl<'ctx> Bindings<'ctx> { let span = span.unwrap_or(DUMMY_SP); ensure_libclang_is_loaded(); + options.build(); + // TODO: Make this path fixup configurable? if let Some(clang) = clang_sys::support::Clang::find(None) { // If --target is specified, assume caller knows what they're doing diff --git a/libbindgen/src/regex_set.rs b/libbindgen/src/regex_set.rs index 8747d285..dbdb6565 100644 --- a/libbindgen/src/regex_set.rs +++ b/libbindgen/src/regex_set.rs @@ -1,7 +1,6 @@ //! A type that represents the union of a set of regular expressions. -use regex::Regex; -use std::borrow::Borrow; +use regex::RegexSet as RxSet; // Yeah, I'm aware this is sorta crappy, should be cheaper to compile a regex // ORing all the patterns, I guess... @@ -9,7 +8,8 @@ use std::borrow::Borrow; /// A dynamic set of regular expressions. #[derive(Debug)] pub struct RegexSet { - items: Vec<Regex>, + items: Vec<String>, + set: Option<RxSet>, } impl RegexSet { @@ -19,41 +19,43 @@ impl RegexSet { } /// Extend this set with every regex in the iterator. - pub fn extend<I>(&mut self, iter: I) - where I: IntoIterator<Item = String>, + pub fn extend<I, S>(&mut self, iter: I) + where I: IntoIterator<Item = S>, + S: AsRef<str> { for s in iter.into_iter() { - self.insert(&s) + self.insert(s) } } /// Insert a new regex into this set. - pub fn insert<S>(&mut self, string: &S) - where S: Borrow<str>, + pub fn insert<S>(&mut self, string: S) + where S: AsRef<str> { - let s = string.borrow(); - match Regex::new(&format!("^{}$", s)) { - Ok(r) => { - self.items.push(r); - } - Err(err) => { - warn!("Invalid pattern provided: {}, {:?}", s, err); - } + self.items.push(format!("^{}$", string.as_ref())); + self.set = None; + } + + /// Construct a RegexSet from the set of entries we've accumulated. + /// + /// Must be called before calling `matches()`, or it will always return + /// false. + pub fn build(&mut self) { + self.set = match RxSet::new(&self.items) { + Ok(x) => Some(x), + Err(e) => { + error!("Invalid regex in {:?}: {:?}", self.items, e); + None + }, } } /// Does the given `string` match any of the regexes in this set? - pub fn matches<S>(&self, string: &S) -> bool - where S: Borrow<str>, + pub fn matches<S>(&self, string: S) -> bool + where S: AsRef<str> { - let s = string.borrow(); - for r in &self.items { - if r.is_match(s) { - return true; - } - } - - false + let s = string.as_ref(); + self.set.as_ref().map(|set| set.is_match(s)).unwrap_or(false) } } @@ -61,6 +63,7 @@ impl Default for RegexSet { fn default() -> Self { RegexSet { items: vec![], + set: None, } } } |