diff options
-rw-r--r-- | bindgen-integration/build.rs | 18 | ||||
-rw-r--r-- | bindgen-integration/cpp/Test.h | 2 | ||||
-rw-r--r-- | src/callbacks.rs (renamed from src/chooser.rs) | 6 | ||||
-rw-r--r-- | src/ir/context.rs | 8 | ||||
-rw-r--r-- | src/ir/enum_ty.rs | 2 | ||||
-rw-r--r-- | src/ir/var.rs | 7 | ||||
-rw-r--r-- | src/lib.rs | 14 |
7 files changed, 43 insertions, 14 deletions
diff --git a/bindgen-integration/build.rs b/bindgen-integration/build.rs index 9b157c5a..fe7ffb1f 100644 --- a/bindgen-integration/build.rs +++ b/bindgen-integration/build.rs @@ -1,9 +1,23 @@ extern crate bindgen; extern crate gcc; +use std::collections::HashSet; use std::env; use std::path::PathBuf; +use std::sync::{Arc, RwLock}; use bindgen::Builder; +use bindgen::callbacks::ParseCallbacks; + +#[derive(Debug)] +struct MacroCallback { + macros: Arc<RwLock<HashSet<String>>>, +} + +impl ParseCallbacks for MacroCallback { + fn parsed_macro(&self, _name: &str) { + self.macros.write().unwrap().insert(String::from(_name)); + } +} fn main() { gcc::Config::new() @@ -11,6 +25,8 @@ fn main() { .file("cpp/Test.cc") .compile("libtest.a"); + let macros = Arc::new(RwLock::new(HashSet::new())); + let bindings = Builder::default() .no_unstable_rust() .enable_cxx_namespaces() @@ -19,9 +35,11 @@ fn main() { .clang_arg("-x") .clang_arg("c++") .clang_arg("-std=c++11") + .parse_callbacks(Box::new(MacroCallback {macros: macros.clone()})) .generate() .expect("Unable to generate bindings"); + assert!(macros.read().unwrap().contains("TESTMACRO")); let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); bindings diff --git a/bindgen-integration/cpp/Test.h b/bindgen-integration/cpp/Test.h index c060984d..310478bb 100644 --- a/bindgen-integration/cpp/Test.h +++ b/bindgen-integration/cpp/Test.h @@ -1,5 +1,7 @@ #pragma once +#define TESTMACRO + class Test { int m_int; double m_double; diff --git a/src/chooser.rs b/src/callbacks.rs index 29090a42..ef85fdd7 100644 --- a/src/chooser.rs +++ b/src/callbacks.rs @@ -7,7 +7,11 @@ use std::panic::UnwindSafe; /// A trait to allow configuring different kinds of types in different /// situations. -pub trait TypeChooser: fmt::Debug + UnwindSafe { +pub trait ParseCallbacks: fmt::Debug + UnwindSafe { + + /// This function will be run on every macro that is identified + fn parsed_macro(&self, _name: &str) {} + /// The integer kind an integer macro should have, given a name and the /// value of that macro, or `None` if you want the default to be chosen. fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> { diff --git a/src/ir/context.rs b/src/ir/context.rs index 1dc4f4a4..4a6785b1 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -11,7 +11,7 @@ use super::traversal::{self, Edge, ItemTraversal}; use super::ty::{FloatKind, TemplateDeclaration, Type, TypeKind}; use BindgenOptions; use cexpr; -use chooser::TypeChooser; +use callbacks::ParseCallbacks; use clang::{self, Cursor}; use clang_sys; use parse::ClangItemParser; @@ -233,9 +233,9 @@ impl<'ctx> BindgenContext<'ctx> { .expect("should have been parsing a type, if we finished parsing a type") } - /// Get the user-provided type chooser by reference, if any. - pub fn type_chooser(&self) -> Option<&TypeChooser> { - self.options().type_chooser.as_ref().map(|t| &**t) + /// Get the user-provided callbacks by reference, if any. + pub fn parse_callbacks(&self) -> Option<&ParseCallbacks> { + self.options().parse_callbacks.as_ref().map(|t| &**t) } /// Define a new item. diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index d2385a29..175af691 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -91,7 +91,7 @@ impl Enum { }; if let Some(val) = value { let name = cursor.spelling(); - let custom_behavior = ctx.type_chooser() + let custom_behavior = ctx.parse_callbacks() .and_then(|t| { t.enum_variant_behavior(type_name, &name, val) }) diff --git a/src/ir/var.rs b/src/ir/var.rs index 2e56e9f5..656a1a6d 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -116,6 +116,11 @@ impl ClangSubItemParser for Var { use cexpr::literal::CChar; match cursor.kind() { CXCursor_MacroDefinition => { + + if let Some(visitor) = ctx.parse_callbacks() { + visitor.parsed_macro(&cursor.spelling()); + } + let value = parse_macro(ctx, &cursor, ctx.translation_unit()); let (id, value) = match value { @@ -170,7 +175,7 @@ impl ClangSubItemParser for Var { (TypeKind::Pointer(char_ty), VarType::String(val)) } EvalResult::Int(Wrapping(value)) => { - let kind = ctx.type_chooser() + let kind = ctx.parse_callbacks() .and_then(|c| c.int_macro(&name, value)) .unwrap_or_else(|| if value < 0 { if value < i32::min_value() as i64 { @@ -63,7 +63,7 @@ mod parse; mod regex_set; mod uses; -pub mod chooser; +pub mod callbacks; #[cfg(rustfmt)] mod codegen; @@ -445,10 +445,10 @@ impl Builder { self } - /// Allows configuring types in different situations, see the `TypeChooser` + /// Allows configuring types in different situations, see the `ParseCallbacks` /// documentation. - pub fn type_chooser(mut self, cb: Box<chooser::TypeChooser>) -> Self { - self.options.type_chooser = Some(cb); + pub fn parse_callbacks(mut self, cb: Box<callbacks::ParseCallbacks>) -> Self { + self.options.parse_callbacks = Some(cb); self } @@ -567,9 +567,9 @@ pub struct BindgenOptions { /// of all types defined therein. See the `uses` module for more. pub dummy_uses: Option<String>, - /// A user-provided type chooser to allow customizing different kinds of + /// A user-provided visitor to allow customizing different kinds of /// situations. - pub type_chooser: Option<Box<chooser::TypeChooser>>, + pub parse_callbacks: Option<Box<callbacks::ParseCallbacks>>, /// Which kind of items should we generate? By default, we'll generate all /// of them. @@ -650,7 +650,7 @@ impl Default for BindgenOptions { clang_args: vec![], input_header: None, dummy_uses: None, - type_chooser: None, + parse_callbacks: None, codegen_config: CodegenConfig::all(), conservative_inline_namespaces: false, generate_comments: true, |