Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add #![deny(missing_docs)] #118

Merged
merged 2 commits into from
Oct 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/bin/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ Options:

// FIXME(emilio): Replace this with docopt if/when they fix their exponential
// algorithm for argument parsing.
//
// FIXME(fitzgen): Switch from `BindgenOptions` to the non-deprecated `Builder`.
#[allow(deprecated)]
fn parse_args_or_exit(args: Vec<String>) -> (BindgenOptions, Box<io::Write>) {
let mut options = BindgenOptions::default();
let mut dest_file = None;
Expand Down
Empty file modified src/codegen/mod.rs
100644 → 100755
Empty file.
119 changes: 115 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
//! Generate Rust bindings for C and C++ libraries.
//!
//! Provide a C/C++ header file, receive Rust FFI code to call into C/C++
//! functions and use types defined in the header.
//!
//! See the [Builder](./struct.Builder.html) struct for usage.

#![crate_name = "bindgen"]
#![crate_type = "dylib"]

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]

#![deny(missing_docs)]

// We internally use the deprecated BindgenOptions all over the place. Once we
// remove its `pub` declaration, we can un-deprecate it and remove this pragma.
#![allow(deprecated)]

// To avoid rather annoying warnings when matching with CXCursor_xxx as a
// constant.
#![allow(non_upper_case_globals)]
Expand Down Expand Up @@ -45,107 +58,189 @@ use ir::item::{Item, ItemId};
use parse::{ClangItemParser, ParseError};
use regex_set::RegexSet;

/// Configure and generate Rust bindings for a C/C++ header.
///
/// This is the main entry point to the library.
///
/// ```ignore
/// use bindgen::builder;
///
/// // Configure and generate bindings.
/// let bindings = try!(builder().header("path/to/input/header")
/// .whitelisted_type("SomeCoolClass")
/// .whitelisted_function("do_some_cool_thing")
/// .generate());
///
/// // Write the generated bindings to an output file.
/// try!(bindings.write_to_file("path/to/output.rs"));
/// ```
#[derive(Debug,Default)]
pub struct Builder {
options: BindgenOptions,
}

/// Construct a new [`Builder`](./struct.Builder.html).
pub fn builder() -> Builder {
Default::default()
}

impl Builder {
/// Set the input C/C++ header.
pub fn header<T: Into<String>>(self, header: T) -> Builder {
self.clang_arg(header)
}

/// Hide the given type from the generated bindings.
pub fn hide_type<T: Into<String>>(mut self, arg: T) -> Builder {
self.options.hidden_types.insert(arg.into());
self
}

/// Treat the given type as opaque in the generated bindings.
pub fn opaque_type<T: Into<String>>(mut self, arg: T) -> Builder {
self.options.opaque_types.insert(arg.into());
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);
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);
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);
self
}

/// Add a string to prepend to the generated bindings. The string is passed
/// through without any modification.
pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Builder {
self.options.raw_lines.push(arg.into());
self
}

/// Add an argument to be passed straight through to clang.
pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
self.options.clang_args.push(arg.into());
self
}

/// Make the generated bindings link the given shared library.
pub fn link<T: Into<String>>(mut self, library: T) -> Builder {
self.options.links.push((library.into(), LinkType::Default));
self
}

/// Make the generated bindings link the given static library.
pub fn link_static<T: Into<String>>(mut self, library: T) -> Builder {
self.options.links.push((library.into(), LinkType::Static));
self
}

/// Make the generated bindings link the given framework.
pub fn link_framework<T: Into<String>>(mut self, library: T) -> Builder {
self.options.links.push((library.into(), LinkType::Framework));
self
}

/// Emit bindings for builtin definitions (for example `__builtin_va_list`)
/// in the generated Rust.
pub fn emit_builtins(mut self) -> Builder {
self.options.builtins = true;
self
}

/// Avoid generating any unstable Rust in the generated bindings.
pub fn no_unstable_rust(mut self) -> Builder {
self.options.unstable_rust = false;
self
}

/// Generate the Rust bindings using the options built up thus far.
pub fn generate(self) -> Result<Bindings, ()> {
Bindings::generate(self.options, None)
}
}

/// Deprecated - use a `Builder` instead
/// Configuration options for generated bindings.
///
/// Deprecated: use a `Builder` instead.
#[derive(Debug)]
#[deprecated]
pub struct BindgenOptions {
/// The set of types that have been blacklisted and should not appear
/// anywhere in the generated code.
pub hidden_types: HashSet<String>,

/// The set of types that should be treated as opaque structures in the
/// generated code.
pub opaque_types: HashSet<String>,

/// The set of types that we should have bindings for in the generated
/// code.
///
/// This includes all types transitively reachable from any type in this
/// set. One might think of whitelisted types/vars/functions as GC roots,
/// and the generated Rust code as including everything that gets marked.
pub whitelisted_types: RegexSet,

/// Whitelisted functions. See docs for `whitelisted_types` for more.
pub whitelisted_functions: RegexSet,

/// Whitelisted variables. See docs for `whitelisted_types` for more.
pub whitelisted_vars: RegexSet,

/// Whether we should generate builtins or not.
pub builtins: bool,

/// The set of libraries we should link in the generated Rust code.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a FIXME here pointing to #104?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

pub links: Vec<(String, LinkType)>,

/// True if we should dump the Clang AST for debugging purposes.
pub emit_ast: 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,

/// True if we shold derive Debug trait implementations for C/C++ structures
/// and types.
pub derive_debug: bool,
/// Generate or not only stable rust.

/// True if we can use unstable Rust code in the bindings, false if we
/// cannot.
pub unstable_rust: bool,
/// Wether to generate names that are **directly** under namespaces.

/// True if we should generate constant names that are **directly** under
/// namespaces.
pub namespaced_constants: bool,
/// Whether to use msvc mangling rules

/// True if we should use MSVC name mangling rules.
pub msvc_mangling: bool,

/// The set of raw lines to prepend to the generated Rust code.
pub raw_lines: Vec<String>,

/// The set of arguments to pass straight through to Clang.
pub clang_args: Vec<String>,
}

Expand Down Expand Up @@ -173,21 +268,31 @@ impl Default for BindgenOptions {
}
}

/// The linking type to use with a given library.
///
/// TODO: #104: This is ignored at the moment, but shouldn't be.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum LinkType {
/// Use shared library linking. This is the default.
Default,
/// Use static linking.
Static,
/// The library is an OSX framework.
Framework
}

/// Generated Rust bindings.
#[derive(Debug, Clone)]
pub struct Bindings {
module: ast::Mod,
raw_lines: Vec<String>,
}

impl Bindings {
/// Generate bindings for the given options.
///
/// Deprecated - use a `Builder` instead
#[deprecated]
pub fn generate(options: BindgenOptions, span: Option<Span>) -> Result<Bindings, ()> {
let span = span.unwrap_or(DUMMY_SP);

Expand All @@ -205,10 +310,12 @@ impl Bindings {
})
}

/// Convert these bindings into a Rust AST.
pub fn into_ast(self) -> Vec<P<ast::Item>> {
self.module.items
}

/// Convert these bindings into source text (with raw lines prepended).
pub fn to_string(&self) -> String {
let mut mod_str = vec![];
{
Expand All @@ -218,11 +325,13 @@ impl Bindings {
String::from_utf8(mod_str).unwrap()
}

/// Write these bindings as source text to a file.
pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
let file = try!(OpenOptions::new().write(true).truncate(true).create(true).open(path));
self.write(Box::new(file))
}

/// Write these bindings as source text to the given `Write`able.
// https://github.com/Manishearth/rust-clippy/issues/740
#[cfg_attr(feature = "clippy", allow(needless_lifetimes))]
pub fn write<'a>(&self, mut writer: Box<Write + 'a>) -> io::Result<()> {
Expand Down Expand Up @@ -255,6 +364,7 @@ fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
}
}

/// Parse one `Item` from the Clang cursor.
pub fn parse_one(ctx: &mut BindgenContext,
cursor: clang::Cursor,
parent: Option<ItemId>,
Expand All @@ -274,6 +384,7 @@ pub fn parse_one(ctx: &mut BindgenContext,
CXChildVisit_Continue
}

/// Parse the Clang AST into our `Item` internal representation.
fn parse(context: &mut BindgenContext) {
use clang::Diagnostic;
use clangll::*;
Expand Down