diff --git a/Cargo.lock b/Cargo.lock index a8734cd0d7efa8533ed47cdb2f3b49e66bc104fd..6efac308f34f59aec2c34c6bf58a98219e7d4e7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,6 +3,7 @@ name = "cbindgen" version = "0.1.0" dependencies = [ "clap 2.23.2 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -55,6 +56,11 @@ name = "libc" version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "log" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "quote" version = "0.3.14" @@ -130,6 +136,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum clap 2.23.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf1114886d7cde2d6448517161d7db8d681a9a1c09f7d210f0b0864e48195f6" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)" = "88ee81885f9f04bff991e306fea7c1c60a5f0f9e409e99f6b40e3311a3363135" +"checksum log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "5141eca02775a762cc6cd564d8d2c50f67c0ea3a372cbf1c51592b3e029e10ad" "checksum quote 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7375cf7ad34a92e8fd18dd9c42f58b9a11def59ab48bec955bf359a788335592" "checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694" "checksum syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)" = "37c279fb816210c9bb28b2c292664581e7b87b4561e86b94df462664d8620bb8" diff --git a/Cargo.toml b/Cargo.toml index bb247b5f961bc2dceda2e3a763285eaca899a46b..8f5894287ec34bbe3764eac0ee2528474c45138b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ exclude = ["examples/**"] [dependencies] clap = "2.23.2" +log = "0.3" [dependencies.syn] version = "0.11.8" diff --git a/src/bindgen/library.rs b/src/bindgen/library.rs index dd12d845f8888ffc75f79812627e309a4dee8439..50ca68775758a77dfd7fea57bcb3b37cda1f30d3 100644 --- a/src/bindgen/library.rs +++ b/src/bindgen/library.rs @@ -1,4 +1,3 @@ -use std::io; use std::io::Write; use std::collections::BTreeMap; use std::cmp::Ordering; @@ -86,12 +85,12 @@ impl Library { if item.is_no_mangle() && abi.is_c() { match Function::convert(item.ident.to_string(), item.is_wr_destructor_safe(), decl) { Ok(func) => { - writeln!(io::stderr(), "take {}::{}", mod_name, &item.ident).unwrap(); + info!("take {}::{}", mod_name, &item.ident); library.functions.insert(func.name.clone(), func); } Err(msg) => { - writeln!(io::stderr(), "skip {}::{} - ({})", mod_name, &item.ident, msg).unwrap(); + info!("skip {}::{} - ({})", mod_name, &item.ident, msg); }, } } @@ -103,18 +102,18 @@ impl Library { if item.is_repr_c() { match Struct::convert(struct_name.clone(), variant, generics) { Ok(st) => { - writeln!(io::stderr(), "take {}::{}", mod_name, &item.ident).unwrap(); + info!("take {}::{}", mod_name, &item.ident); library.structs.insert(struct_name, st); } Err(msg) => { - writeln!(io::stderr(), "take {}::{} - opaque ({})", mod_name, &item.ident, msg).unwrap(); + info!("take {}::{} - opaque ({})", mod_name, &item.ident, msg); library.opaque_structs.insert(struct_name.clone(), OpaqueStruct::new(struct_name)); } } } else { - writeln!(io::stderr(), "take {}::{} - opaque (not marked as repr(C))", mod_name, &item.ident).unwrap(); + info!("take {}::{} - opaque (not marked as repr(C))", mod_name, &item.ident); library.opaque_structs.insert(struct_name.clone(), OpaqueStruct::new(struct_name)); } @@ -123,7 +122,7 @@ impl Library { if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() || !generics.where_clause.predicates.is_empty() { - writeln!(io::stderr(), "skip {}::{} - (has generics or lifetimes or where bounds)", mod_name, &item.ident).unwrap(); + info!("skip {}::{} - (has generics or lifetimes or where bounds)", mod_name, &item.ident); continue; } @@ -132,22 +131,22 @@ impl Library { match Enum::convert(enum_name.clone(), variants) { Ok(en) => { - writeln!(io::stderr(), "take {}::{}", mod_name, &item.ident).unwrap(); + info!("take {}::{}", mod_name, &item.ident); library.enums.insert(enum_name, en); } Err(msg) => { - writeln!(io::stderr(), "skip {}::{} - ({})", mod_name, &item.ident, msg).unwrap(); + info!("skip {}::{} - ({})", mod_name, &item.ident, msg); } } } else { - writeln!(io::stderr(), "skip {}::{} - (not marked as repr(u32)", mod_name, &item.ident).unwrap(); + info!("skip {}::{} - (not marked as repr(u32)", mod_name, &item.ident); } } ItemKind::Ty(ref ty, ref generics) => { if !generics.lifetimes.is_empty() || !generics.ty_params.is_empty() || !generics.where_clause.predicates.is_empty() { - writeln!(io::stderr(), "skip {}::{} - (has generics or lifetimes or where bounds)", mod_name, &item.ident).unwrap(); + info!("skip {}::{} - (has generics or lifetimes or where bounds)", mod_name, &item.ident); continue; } @@ -155,7 +154,7 @@ impl Library { let fail1 = match Specialization::convert(alias_name.clone(), ty) { Ok(spec) => { - writeln!(io::stderr(), "take {}::{}", mod_name, &item.ident).unwrap(); + info!("take {}::{}", mod_name, &item.ident); library.specializations.insert(alias_name, spec); continue; } @@ -163,13 +162,13 @@ impl Library { }; let fail2 = match Typedef::convert(alias_name.clone(), ty) { Ok(typedef) => { - writeln!(io::stderr(), "take {}::{}", mod_name, &item.ident).unwrap(); + info!("take {}::{}", mod_name, &item.ident); library.typedefs.insert(alias_name, typedef); continue; } Err(msg) => msg, }; - writeln!(io::stderr(), "skip {}::{} - ({} and {})", mod_name, &item.ident, fail1, fail2).unwrap(); + info!("skip {}::{} - ({} and {})", mod_name, &item.ident, fail1, fail2); } _ => {} } @@ -207,7 +206,7 @@ impl Library { out.push(value); } } else { - writeln!(io::stderr(), "warning: can't find {}", p).unwrap(); + warn!("can't find {}", p); } } @@ -215,7 +214,7 @@ impl Library { if let Some(value) = self.resolve_path(p) { value.add_deps(self, out); } else { - writeln!(io::stderr(), "warning: can't find {}", p).unwrap(); + warn!("can't find {}", p); } } @@ -245,7 +244,7 @@ impl Library { result.items.push(value); } Err(msg) => { - writeln!(io::stderr(), "error: specializing {} failed - ({})", dep.name(), msg).unwrap(); + warn!("specializing {} failed - ({})", dep.name(), msg); } } continue; diff --git a/src/logging.rs b/src/logging.rs new file mode 100644 index 0000000000000000000000000000000000000000..c880949b1abc67a3dfc290c107e286184959dff9 --- /dev/null +++ b/src/logging.rs @@ -0,0 +1,54 @@ +use std::io; +use std::io::Write; + +use log; +use log::*; + +pub struct WarnLogger; +pub struct InfoLogger; + +impl WarnLogger { + pub fn init() -> Result<(), SetLoggerError> { + log::set_logger(|max_log_level| { + max_log_level.set(LogLevelFilter::Warn); + Box::new(WarnLogger) + }) + } +} +impl log::Log for WarnLogger { + fn enabled(&self, metadata: &LogMetadata) -> bool { + metadata.level() <= LogLevel::Warn + } + + fn log(&self, record: &LogRecord) { + if self.enabled(record.metadata()) { + writeln!(io::stderr(), + "{}: {}", + record.level(), + record.args()).unwrap(); + } + } +} + +impl InfoLogger { + pub fn init() -> Result<(), SetLoggerError> { + log::set_logger(|max_log_level| { + max_log_level.set(LogLevelFilter::Info); + Box::new(InfoLogger) + }) + } +} +impl log::Log for InfoLogger { + fn enabled(&self, metadata: &LogMetadata) -> bool { + metadata.level() <= LogLevel::Info + } + + fn log(&self, record: &LogRecord) { + if self.enabled(record.metadata()) { + writeln!(io::stderr(), + "{}: {}", + record.level(), + record.args()).unwrap(); + } + } +} diff --git a/src/main.rs b/src/main.rs index cc3860568b627d06ddcdc5fc1260b8f0cf966307..c4530ba7be9bab3586c6084ac4630f69c2bf12a5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,14 @@ use std::io; use std::fs::File; +#[macro_use] +extern crate log; extern crate syn; extern crate clap; use clap::{Arg, App}; +mod logging; mod config; mod rust_lib; mod bindgen; @@ -21,6 +24,9 @@ fn main() { .long("config") .value_name("CONFIG") .help("the config to use. currently either `wr`, or `default`")) + .arg(Arg::with_name("v") + .short("v") + .help("whether to print verbose logs")) .arg(Arg::with_name("INPUT") .help("the crate or source file to generate bindings for") .required(true) @@ -31,6 +37,12 @@ fn main() { .index(2)) .get_matches(); + if matches.is_present("v") { + logging::InfoLogger::init().unwrap(); + } else { + logging::WarnLogger::init().unwrap(); + } + let input = matches.value_of("INPUT").unwrap(); let config = match matches.value_of("config") { Some(c) => Config::load(c).expect("unknown config"), diff --git a/src/rust_lib.rs b/src/rust_lib.rs index f15d4d8064d84bd1bbe3539a963fb528beab07fa..69c07d9c7bb3a3f30c067ed03beb5dcd121e3ec3 100644 --- a/src/rust_lib.rs +++ b/src/rust_lib.rs @@ -1,7 +1,5 @@ use std::fs::File; -use std::io; use std::io::Read; -use std::io::Write; use std::path::PathBuf; use syn; @@ -86,7 +84,7 @@ fn parse_mod<F>(crate_dir: PathBuf, next_mod_path2, items_callback); } else { - writeln!(io::stderr(), "warning, can't find a mod's file").unwrap(); + warn!("can't find mod {} in crate {}", next_mod_name, crate_name); } } syn::ItemKind::ExternCrate(_) => { @@ -96,7 +94,7 @@ fn parse_mod<F>(crate_dir: PathBuf, let next_crate_path = crate_parent.join(next_crate_name.clone()); if !next_crate_path.exists() { - writeln!(io::stderr(), "warning, can't find an extern crate {}", next_crate_name.clone()).unwrap(); + warn!("can't find extern crate {}", next_crate_name.clone()); continue; }