Skip to content

Commit

Permalink
Auto merge of #228 - jdub:clap, r=emilio
Browse files Browse the repository at this point in the history
Clap your hands say yeah! 👏🏻

In progress port to `clap`, obsoletes the `docopt` port in #202.
  • Loading branch information
bors-servo authored Nov 10, 2016
2 parents 8d83bdf + dc96c1f commit b3322dd
Show file tree
Hide file tree
Showing 4 changed files with 300 additions and 248 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ quasi_codegen = "0.20"
[dependencies]
cfg-if = "0.1.0"
clang-sys = "0.8.0"
clap = "2"
lazy_static = "0.1.*"
libc = "0.2"
log = "0.3"
Expand Down
266 changes: 18 additions & 248 deletions src/bin/bindgen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,248 +6,14 @@ extern crate env_logger;
#[macro_use]
extern crate log;
extern crate clang_sys;
extern crate clap;
extern crate rustc_serialize;

use bindgen::{BindgenOptions, Bindings, LinkType, clang_version};
use std::default::Default;
use bindgen::clang_version;
use std::env;
use std::fs;
use std::io;
use std::path;
use std::process;

const USAGE: &'static str = "
Usage:
bindgen [options] \
[--link=<lib>...] \
[--static-link=<lib>...] \
[--framework-link=<framework>...] \
[--raw-line=<raw>...] \
[--opaque-type=<type>...] \
[--blacklist-type=<type>...] \
[--whitelist-type=<type>...] \
[--whitelist-function=<name>...] \
[--whitelist-var=<name>...] \
[--bitfield-enum=<name>...] \
<input-header> \
[-- <clang-args>...]
bindgen (-h | --help)
Options:
-h, --help Display this help message.
-l=<lib>, --link=<lib> Link to a dynamic library, can be provided
multiple times.
--static-link=<lib> Link to a static library, can be provided
multiple times.
--framework-link=<framework> Link to a framework.
-o=<output-rust-file> Write bindings to <output-rust-file>
(defaults to stdout)
--builtins Output bindings for builtin definitions (for
example __builtin_va_list)
--ignore-functions Don't generate bindings for functions and
methods. This is useful when you only care
about struct layouts.
--ignore-methods Avoid generating all kind of methods.
--enable-cxx-namespaces Enable support for C++ namespaces.
--emit-clang-ast Output the ast (for debugging purposes)
--use-msvc-mangling Handle MSVC C++ ABI mangling; requires that
target be set to (i686|x86_64)-pc-win32
--no-convert-floats Don't convert floats automatically to f32/f64.
--raw-line=<raw> Add a raw line at the beginning of the output.
--no-unstable-rust Avoid generating unstable rust.
--use-core Use built-in types from core instead of std.
--ctypes-prefix=<prefix> Use the given prefix before the raw types
instead of ::std::os::raw::.
--opaque-type=<type> Mark a type as opaque.
--blacklist-type=<type> Mark a type as hidden.
--whitelist-type=<type> Whitelist the type. If this set or any other
of the whitelisting sets is not empty, then
all the non-whitelisted types (or dependant)
won't be generated.
--whitelist-function=<regex> Whitelist all the free-standing functions
matching <regex>. Same behavior on emptyness
than the type whitelisting.
--whitelist-var=<regex> Whitelist all the free-standing variables
matching <regex>. Same behavior on emptyness
than the type whitelisting.
--bitfield-enum=<regex> Mark any enum whose name matches <regex> as a
set of bitfield flags instead of an
enumeration.
--dummy-uses=<path> For testing purposes, generate a C/C++ file
containing dummy uses of all types defined in
the input header.
<clang-args> Options other than stated above are passed
directly through to clang.
";

// 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;
let mut source_file = None;

let mut iter = args.into_iter().skip(1);
loop {
let next = match iter.next() {
Some(arg) => arg,
_ => break,
};

match &*next {
"-h" | "--help" => {
println!("{}", USAGE);
process::exit(0);
}
"-l" | "--link" => {
let lib = iter.next().expect("--link needs an argument");
options.links.push((lib, LinkType::Default));
}
"--static-link" => {
let lib = iter.next().expect("--static-link needs an argument");
options.links.push((lib, LinkType::Static));
}
"--framework-link" => {
let lib = iter.next()
.expect("--framework-link needs an argument");
options.links.push((lib, LinkType::Framework));
}
"--raw-line" => {
let line = iter.next().expect("--raw-line needs an argument");
options.raw_lines.push(line);
}
"--opaque-type" => {
let ty_canonical_name = iter.next()
.expect("--opaque-type expects a type");
options.opaque_types.insert(ty_canonical_name);
}
"--blacklist-type" => {
let ty_canonical_name = iter.next()
.expect("--blacklist-type expects a type");
options.hidden_types.insert(ty_canonical_name);
}
"--whitelist-type" => {
let ty_pat = iter.next()
.expect("--whitelist-type expects a type pattern");
options.whitelisted_types.insert(&ty_pat);
}
"--whitelist-function" => {
let function_pat = iter.next()
.expect("--whitelist-function expects a pattern");
options.whitelisted_functions.insert(&function_pat);
}
"--whitelist-var" => {
let var_pat = iter.next()
.expect("--whitelist-var expects a pattern");
options.whitelisted_vars.insert(&var_pat);
}
"--bitfield-enum" => {
let enum_pat = iter.next()
.expect("--bitfield-enum expects a pattern");
options.bitfield_enums.insert(&enum_pat);
}
"--" => {
while let Some(clang_arg) = iter.next() {
options.clang_args.push(clang_arg);
}
}
"--output" | "-o" => {
let out_name = iter.next().expect("-o expects a file name");
dest_file = Some(out_name);
}
"--builtins" => {
options.builtins = true;
}
"--ignore-functions" => {
options.ignore_functions = true;
}
"--ignore-methods" => {
options.ignore_methods = true;
}
"--enable-cxx-namespaces" => {
options.enable_cxx_namespaces = true;
}
"--no-unstable-rust" => {
options.unstable_rust = false;
}
"--use-core" => {
options.use_core = true;
}
"--ctypes-prefix" => {
let prefix = iter.next()
.expect("--ctypes-prefix expects a prefix after it");
options.ctypes_prefix = Some(prefix);
}
"--emit-clang-ast" => {
options.emit_ast = true;
}
"--no-convert-floats" => {
options.convert_floats = false;
}
"--use-msvc-mangling" => {
options.msvc_mangling = true;
}
"--dummy-uses" => {
let dummy_path = iter.next()
.expect("--dummy-uses expects a file path");
options.dummy_uses = Some(dummy_path);
}
other if source_file.is_none() => {
source_file = Some(other.into());
}
other => {
panic!("Unknown option: \"{}\"", other);
}
}
}

if let Some(source_file) = source_file.take() {
options.clang_args.push(source_file);
options.input_header = options.clang_args.last().cloned();
} else {
options.input_header = options.clang_args
.iter()
.find(|arg| arg.ends_with(".h") || arg.ends_with(".hpp"))
.cloned();
}

let out = if let Some(ref path_name) = dest_file {
let path = path::Path::new(path_name);
let file = fs::File::create(path).expect("Opening out file failed");
Box::new(io::BufWriter::new(file)) as Box<io::Write>
} else {
Box::new(io::BufWriter::new(io::stdout())) as Box<io::Write>
};

(options, out)
}
mod options;
use options::builder_from_flags;

pub fn main() {
log::set_logger(|max_log_level| {
Expand Down Expand Up @@ -304,14 +70,18 @@ pub fn main() {
}
}

let (options, out) = parse_args_or_exit(bind_args);

let mut bindings = Bindings::generate(options, None)
.expect("Unable to generate bindings");

bindings.write_dummy_uses()
.expect("Unable to write dummy uses to file.");

bindings.write(out)
.expect("Unable to write bindings to file.");
match builder_from_flags(env::args()) {
Ok((builder, output)) => {
let mut bindings = builder.generate()
.expect("Unable to generate bindings");
bindings.write(output)
.expect("Unable to write output");
bindings.write_dummy_uses()
.expect("Unable to write dummy uses to file.");
}
Err(error) => {
println!("{}", error);
std::process::exit(1);
}
};
}
Loading

0 comments on commit b3322dd

Please sign in to comment.