summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/chooser.rs3
-rw-r--r--src/lib.rs5
-rw-r--r--src/main.rs29
-rw-r--r--src/options.rs9
-rw-r--r--tests/tests.rs2
5 files changed, 41 insertions, 7 deletions
diff --git a/src/chooser.rs b/src/chooser.rs
index bf610b28..29090a42 100644
--- a/src/chooser.rs
+++ b/src/chooser.rs
@@ -3,10 +3,11 @@
pub use ir::enum_ty::{EnumVariantCustomBehavior, EnumVariantValue};
pub use ir::int::IntKind;
use std::fmt;
+use std::panic::UnwindSafe;
/// A trait to allow configuring different kinds of types in different
/// situations.
-pub trait TypeChooser: fmt::Debug {
+pub trait TypeChooser: fmt::Debug + UnwindSafe {
/// 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/lib.rs b/src/lib.rs
index 84a2ee67..2a1322e4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -554,6 +554,11 @@ pub struct BindgenOptions {
pub objc_extern_crate: bool,
}
+/// TODO(emilio): This is sort of a lie (see the error message that results from
+/// removing this), but since we don't share references across panic boundaries
+/// it's ok.
+impl ::std::panic::UnwindSafe for BindgenOptions {}
+
impl BindgenOptions {
fn build(&mut self) {
self.whitelisted_vars.build();
diff --git a/src/main.rs b/src/main.rs
index 9b037ef8..68f3d0a8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -8,6 +8,7 @@ extern crate rustc_serialize;
use bindgen::clang_version;
use std::env;
+use std::panic;
mod options;
use options::builder_from_flags;
@@ -41,9 +42,21 @@ pub fn main() {
}
match builder_from_flags(bind_args.into_iter()) {
- Ok((builder, output)) => {
- let mut bindings = builder.generate()
- .expect("Unable to generate bindings");
+ Ok((builder, output, verbose)) => {
+
+ let builder_result =
+ panic::catch_unwind(||
+ builder.generate().expect("Unable to generate bindings")
+ );
+
+ if builder_result.is_err() {
+ if verbose {
+ print_verbose_err();
+ }
+ std::process::exit(1);
+ }
+
+ let mut bindings = builder_result.unwrap();
bindings.write(output)
.expect("Unable to write output");
bindings.write_dummy_uses()
@@ -55,3 +68,13 @@ pub fn main() {
}
};
}
+
+fn print_verbose_err() {
+ println!("Bindgen unexpectedly panicked");
+ println!("This may be caused by one of the known-unsupported \
+ things (https://github.com/servo/rust-bindgen#c), \
+ please modify the bindgen flags to work around it as \
+ described in https://github.com/servo/rust-bindgen#c");
+ println!("Otherwise, please file an issue at \
+ https://github.com/servo/rust-bindgen/issues/new");
+}
diff --git a/src/options.rs b/src/options.rs
index 8d11be2d..5231ad24 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -5,7 +5,7 @@ use std::io::{self, Error, ErrorKind};
/// Construct a new [`Builder`](./struct.Builder.html) from command line flags.
pub fn builder_from_flags<I>(args: I)
- -> Result<(Builder, Box<io::Write>), io::Error>
+ -> Result<(Builder, Box<io::Write>, bool), io::Error>
where I: Iterator<Item = String>,
{
let matches = App::new("bindgen")
@@ -175,6 +175,9 @@ pub fn builder_from_flags<I>(args: I)
.takes_value(true)
.multiple(true)
.number_of_values(1),
+ Arg::with_name("verbose")
+ .long("verbose")
+ .help("Print verbose error messages"),
]) // .args()
.get_matches_from(args);
@@ -346,5 +349,7 @@ pub fn builder_from_flags<I>(args: I)
Box::new(io::BufWriter::new(io::stdout())) as Box<io::Write>
};
- Ok((builder, output))
+ let verbose = matches.is_present("verbose");
+
+ Ok((builder, output, verbose))
}
diff --git a/tests/tests.rs b/tests/tests.rs
index 5b0ccd11..bc853a33 100644
--- a/tests/tests.rs
+++ b/tests/tests.rs
@@ -117,7 +117,7 @@ fn create_bindgen_builder(header: &PathBuf) -> Result<Option<Builder>, Error> {
.chain(flags.into_iter());
builder_from_flags(args)
- .map(|(builder, _)| Some(builder.no_unstable_rust()))
+ .map(|(builder, _, _)| Some(builder.no_unstable_rust()))
}
macro_rules! test_header {