diff options
-rw-r--r-- | libbindgen/src/codegen/mod.rs | 32 | ||||
-rw-r--r-- | libbindgen/src/lib.rs | 68 | ||||
-rw-r--r-- | src/options.rs | 25 |
3 files changed, 97 insertions, 28 deletions
diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 7fa76d56..ff18ab83 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -267,15 +267,19 @@ impl CodeGenerator for Item { module.codegen(ctx, result, whitelisted_items, self); } ItemKind::Function(ref fun) => { - if !ctx.options().ignore_functions { + if ctx.options().codegen_config.functions { fun.codegen(ctx, result, whitelisted_items, self); } } ItemKind::Var(ref var) => { - var.codegen(ctx, result, whitelisted_items, self); + if ctx.options().codegen_config.vars { + var.codegen(ctx, result, whitelisted_items, self); + } } ItemKind::Type(ref ty) => { - ty.codegen(ctx, result, whitelisted_items, self); + if ctx.options().codegen_config.types { + ty.codegen(ctx, result, whitelisted_items, self); + } } } } @@ -1152,14 +1156,16 @@ impl CodeGenerator for CompInfo { result.push(item); } - let mut method_names = Default::default(); - for method in self.methods() { - method.codegen_method(ctx, - &mut methods, - &mut method_names, - result, - whitelisted_items, - item); + if ctx.options().codegen_config.methods { + let mut method_names = Default::default(); + for method in self.methods() { + method.codegen_method(ctx, + &mut methods, + &mut method_names, + result, + whitelisted_items, + item); + } } } @@ -1222,10 +1228,6 @@ impl MethodCodegen for Method { result: &mut CodegenResult, whitelisted_items: &ItemSet, _parent: &Item) { - if ctx.options().ignore_methods { - return; - } - if self.is_virtual() { return; // FIXME } diff --git a/libbindgen/src/lib.rs b/libbindgen/src/lib.rs index f25c6cdf..b2d3593c 100644 --- a/libbindgen/src/lib.rs +++ b/libbindgen/src/lib.rs @@ -98,6 +98,49 @@ use syntax::print::pp::eof; use syntax::print::pprust; use syntax::ptr::P; +/// A type used to indicate which kind of items do we have to generate. +/// +/// TODO(emilio): Use `bitflags!` +#[derive(Debug, Clone)] +pub struct CodegenConfig { + /// Whether to generate functions. + pub functions: bool, + /// Whether to generate types. + pub types: bool, + /// Whether to generate constants. + pub vars: bool, + /// Whether to generate methods. + pub methods: bool, +} + +impl CodegenConfig { + /// Generate all kinds of items. + pub fn all() -> Self { + CodegenConfig { + functions: true, + types: true, + vars: true, + methods: true, + } + } + + /// Generate nothing. + pub fn nothing() -> Self { + CodegenConfig { + functions: false, + types: false, + vars: false, + methods: false, + } + } +} + +impl Default for CodegenConfig { + fn default() -> Self { + CodegenConfig::all() + } +} + /// Configure and generate Rust bindings for a C/C++ header. /// /// This is the main entry point to the library. @@ -264,13 +307,13 @@ impl Builder { /// Ignore functions. pub fn ignore_functions(mut self) -> Builder { - self.options.ignore_functions = true; + self.options.codegen_config.functions = false; self } /// Ignore methods. pub fn ignore_methods(mut self) -> Builder { - self.options.ignore_methods = true; + self.options.codegen_config.methods = false; self } @@ -299,6 +342,12 @@ impl Builder { self } + /// Choose what to generate using a CodegenConfig. + pub fn with_codegen_config(mut self, config: CodegenConfig) -> Self { + self.options.codegen_config = config; + self + } + /// Generate the Rust bindings using the options built up thus far. pub fn generate<'ctx>(self) -> Result<Bindings<'ctx>, ()> { Bindings::generate(self.options, None) @@ -348,14 +397,6 @@ pub struct BindgenOptions { /// True if we should dump our internal IR for debugging purposes. pub emit_ir: bool, - /// True if we should ignore functions and only generate bindings for - /// structures, types, and methods. - pub ignore_functions: bool, - - /// True if we should avoid generating bindings for methods, and instead - /// just generate code for structures and types. - pub ignore_methods: bool, - /// True if we should emulate C++ namespaces with Rust modules in the /// generated bindings. pub enable_cxx_namespaces: bool, @@ -403,6 +444,10 @@ pub struct BindgenOptions { /// A user-provided type chooser to allow customizing different kinds of /// situations. pub type_chooser: Option<Box<chooser::TypeChooser>>, + + /// Which kind of items should we generate? By default, we'll generate all + /// of them. + pub codegen_config: CodegenConfig, } impl Default for BindgenOptions { @@ -418,8 +463,6 @@ impl Default for BindgenOptions { links: vec![], emit_ast: false, emit_ir: false, - ignore_functions: false, - ignore_methods: false, derive_debug: true, enable_cxx_namespaces: false, disable_name_namespacing: false, @@ -434,6 +477,7 @@ impl Default for BindgenOptions { input_header: None, dummy_uses: None, type_chooser: None, + codegen_config: CodegenConfig::all(), } } } diff --git a/src/options.rs b/src/options.rs index 9632619f..a783696e 100644 --- a/src/options.rs +++ b/src/options.rs @@ -1,5 +1,5 @@ use clap::{App, Arg}; -use libbindgen::{Builder, builder}; +use libbindgen::{Builder, builder, CodegenConfig}; use std::fs::File; use std::io::{self, Error, ErrorKind}; @@ -71,6 +71,12 @@ pub fn builder_from_flags<I>(args: I) .long("ignore-functions") .help("Do not generate bindings for functions or methods. This \ is useful when you only care about struct layouts."), + Arg::with_name("generate") + .long("generate") + .help("Generate a given kind of items, split by commas. \ + Valid values are \"functions\",\"types\", \"vars\" and \ + \"methods\".") + .takes_value(true), Arg::with_name("ignore-methods") .long("ignore-methods") .help("Do not generate bindings for methods."), @@ -185,6 +191,23 @@ pub fn builder_from_flags<I>(args: I) } } + if let Some(what_to_generate) = matches.value_of("generate") { + let mut config = CodegenConfig::nothing(); + for what in what_to_generate.split(",") { + match what { + "functions" => config.functions = true, + "types" => config.types = true, + "vars" => config.vars = true, + "methods" => config.methods = true, + _ => { + return Err( + Error::new(ErrorKind::Other, "Unknown generate item")); + } + } + } + builder = builder.with_codegen_config(config); + } + if matches.is_present("emit-clang-ast") { builder = builder.emit_clang_ast(); } |