diff --git a/Cargo.lock b/Cargo.lock index 9895009..7439159 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,4 +1,14 @@ [root] name = "nrgrip" version = "0.1.0" +dependencies = [ + "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", +] +[[package]] +name = "getopts" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" diff --git a/Cargo.toml b/Cargo.toml index a339810..633130a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,4 @@ name = "nrgrip" doc = false [dependencies] +getopts = "0.2" diff --git a/src/main.rs b/src/main.rs index 1fe7a94..b3dc8f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,31 +24,52 @@ use std::env; use std::fs::File; use std::process; +extern crate getopts; +use getopts::Options; + extern crate nrgrip; -fn exit_usage(prog_name: &String) { - println!("Usage:\n\t{} ", prog_name); - process::exit(1); -} - - fn main() { - let mut argv = env::args(); + let args: Vec = env::args().collect(); + let prog_name = &args.first().expect("Can't retrieve program's name"); - let prog_name = argv.next().unwrap_or("nrgrip".to_string()); + let mut opts = Options::new(); + opts.optflag("i", "info", + "display the image's metadata (default action)"); + opts.optflag("x", "extract", + "same as --extract-cue --extract-raw"); + opts.optflag("c", "extract-cue", + "extract cue sheet from the NRG metadata"); + opts.optflag("r", "extract-raw", + "extract the raw audio tracks"); + opts.optflag("h", "help", + "print this help message"); - let img_path = argv.next().unwrap_or("".to_string()); - if img_path == "" { - exit_usage(&prog_name); + let options = match opts.parse(&args[1..]) { + Ok(m) => m, + Err(err) => panic!(err.to_string()), + }; + + if options.opt_present("help") { + exit_usage(&prog_name, &opts); } + // Get input NRG image name + if options.free.len() != 1 { + // We need exactly one input file! + fail_usage(&prog_name, &opts); + } + let img_path = &options.free[0]; println!("NRG image path: \"{}\"", img_path); - // We don't support more than one input file - if argv.next().is_some() { - exit_usage(&prog_name); - } + // See what actions are to be taken on that file + let action_cue = + options.opt_present("extract-cue") || options.opt_present("extract"); + let action_raw = + options.opt_present("extract-raw") || options.opt_present("extract"); + let action_info = + options.opt_present("info") || !(action_cue || action_raw); // Open the image file let fd = File::open(&img_path); @@ -59,7 +80,7 @@ fn main() { } let mut fd = fd.unwrap(); - // Read and display the image's metadata + // Read the image's metadata let metadata = nrgrip::metadata::read_nrg_metadata(&mut fd); if metadata.is_err() { println!("Error reading \"{}\": {}", @@ -67,20 +88,50 @@ fn main() { process::exit(1); } let metadata = metadata.unwrap(); - println!("\n{}", metadata); + + // Display metadata if requested + if action_info { + println!("\n{}", metadata); + } // Read and write the cue sheet - println!("\nNow extracting cue sheet..."); - if let Err(err) = nrgrip::cue_sheet::write_cue_sheet(&img_path, &metadata) { - println!("Error writing cue sheet: {}", err.to_string()); - process::exit(1); + if action_cue { + println!("\nExtracting cue sheet..."); + if let Err(err) = nrgrip::cue_sheet::write_cue_sheet(&img_path, + &metadata) { + println!("Error writing cue sheet: {}", err.to_string()); + process::exit(1); + } + println!("OK!"); } // Extract raw audio data - println!("Now extracting raw audio data..."); - if let Err(err) = nrgrip::raw_audio::extract_nrg_raw_audio( - &mut fd, &img_path, &metadata) { - println!("Error extracting raw audio data: {}", err.to_string()); + if action_raw { + println!("\nExtracting raw audio data..."); + if let Err(err) = nrgrip::raw_audio::extract_nrg_raw_audio( + &mut fd, &img_path, &metadata) { + println!("Error extracting raw audio data: {}", err.to_string()); + } + println!("OK!"); } - println!("OK!"); +} + + +fn exit_usage(prog_name: &str, opts: &Options) { + print_usage(prog_name, opts); + process::exit(0); +} + +fn fail_usage(prog_name: &str, opts: &Options) { + print_usage(prog_name, opts); + process::exit(1); +} + +fn print_usage(prog_name: &str, opts: &Options) { + let brief = format!("NRGrip - rip Nero Burning ROM audio images + +Usage: + {prog} [-icrx] [options] + {prog} -h", prog = prog_name); + print!("{}", opts.usage(&brief)); } diff --git a/src/metadata/metadata.rs b/src/metadata/metadata.rs index ea76912..6487d86 100644 --- a/src/metadata/metadata.rs +++ b/src/metadata/metadata.rs @@ -105,7 +105,7 @@ impl fmt::Display for NrgMetadata { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "Image size: {} Bytes\n\ NRG format version: {}\n\ - First chunk offset: {}", + First NRG chunk offset: {}", self.file_size, self.nrg_version, self.chunk_offset,