extern crate clap;
extern crate failure;
extern crate wasm_nm;
use std::fs;
use std::io;
use std::process;
fn main() {
if let Err(()) = try_main() {
process::exit(1)
}
}
fn try_main() -> Result<(), ()> {
let matches = parse_args();
let mut opts = wasm_nm::Options::default();
if matches.is_present("only_imports") {
opts = wasm_nm::Options::nothing();
opts.imports = true;
} else if matches.is_present("only_exports") {
opts = wasm_nm::Options::nothing();
opts.exports = true;
} else if matches.is_present("only_privates") {
opts = wasm_nm::Options::nothing();
opts.privates = true;
}
if matches.is_present("sizes") {
opts.sizes = true;
}
let mut any_errors = false;
for path in matches.values_of("file").unwrap() {
if let Err(e) = print_symbols_in_one(path, opts.clone(), &matches) {
eprintln!("error: {}: {}", path, e);
any_errors = true;
}
}
if any_errors {
Err(())
} else {
Ok(())
}
}
fn print_symbols_in_one(
path: &str,
opts: wasm_nm::Options,
matches: &clap::ArgMatches<'static>,
) -> Result<(), failure::Error> {
let file = fs::File::open(path)?;
let mut file = io::BufReader::new(file);
let print_sizes = opts.sizes;
let symbols = wasm_nm::symbols(opts, &mut file)?;
let just_symbols = matches.is_present("just_symbols");
for sym in symbols.iter() {
if print_sizes {
match sym {
wasm_nm::Symbol::Import { .. } => print!("0 "),
wasm_nm::Symbol::Export { size, .. } | wasm_nm::Symbol::Private { size, .. } => {
print!("{} ", size.unwrap_or(0))
}
}
}
if !just_symbols {
match sym {
wasm_nm::Symbol::Import { .. } => print!("i "),
wasm_nm::Symbol::Export { .. } => print!("e "),
wasm_nm::Symbol::Private { .. } => print!("p "),
}
}
println!("{}", sym);
}
Ok(())
}
fn parse_args() -> clap::ArgMatches<'static> {
clap::App::new(env!("CARGO_PKG_NAME"))
.version(env!("CARGO_PKG_VERSION"))
.author(env!("CARGO_PKG_AUTHORS"))
.about(env!("CARGO_PKG_DESCRIPTION"))
.long_about(
"\
wasm-nm displays imported and exported symbols in a wasm file.
Each symbol is preceded by its symbol type: \"i\" for imported symbols, \"e\"
for exported symbols, and \"p\" for private symbols. Alternatively, the -j flag
can be used to avoid any prefixes.
",
)
.arg(
clap::Arg::with_name("file")
.required(true)
.multiple(true)
.help("The wasm file(s) whose symbols should be dumped."),
)
.arg(
clap::Arg::with_name("just_symbols")
.short("j")
.help("Just display the symbol names (no type)."),
)
.arg(
clap::Arg::with_name("sizes")
.short("z")
.help("Display symbol size (in bytes)."),
)
.arg(
clap::Arg::with_name("only_imports")
.short("i")
.conflicts_with("only_exports")
.conflicts_with("only_privates")
.help("Display only import symbols."),
)
.arg(
clap::Arg::with_name("no_imports")
.short("I")
.conflicts_with("only_imports")
.help("Do not display import symbols."),
)
.arg(
clap::Arg::with_name("only_exports")
.short("e")
.conflicts_with("only_imports")
.conflicts_with("only_privates")
.help("Display only export symbols."),
)
.arg(
clap::Arg::with_name("no_exports")
.short("E")
.conflicts_with("only_exports")
.help("Do not display export symbols."),
)
.arg(
clap::Arg::with_name("only_privates")
.short("p")
.conflicts_with("only_exports")
.conflicts_with("only_imports")
.help("Display only private symbols."),
)
.arg(
clap::Arg::with_name("no_privates")
.short("P")
.conflicts_with("only_privates")
.help("Do not display private symbols."),
)
.get_matches()
}