diff --git a/src/head/head.rs b/src/head/head.rs index 804f862e0..9b54ce76e 100644 --- a/src/head/head.rs +++ b/src/head/head.rs @@ -32,12 +32,14 @@ enum FilterMode { struct Settings { mode: FilterMode, + verbose: bool, } impl Default for Settings { fn default() -> Settings { Settings { mode: FilterMode::Lines(10), + verbose: false, } } } @@ -57,10 +59,12 @@ pub fn uumain(args: Vec) -> i32 { opts.optopt("c", "bytes", "Print the first K bytes. With the leading '-', print all but the last K bytes", "[-]K"); opts.optopt("n", "lines", "Print the first K lines. With the leading '-', print all but the last K lines", "[-]K"); + opts.optflag("q", "quiet", "never print headers giving file names"); + opts.optflag("v", "verbose", "always print headers giving file names"); opts.optflag("h", "help", "display this help and exit"); opts.optflag("V", "version", "output version information and exit"); - let given_options = match opts.parse(&args) { + let matches = match opts.parse(&args) { Ok (m) => { m } Err(_) => { println!("{}", opts.usage("")); @@ -68,16 +72,16 @@ pub fn uumain(args: Vec) -> i32 { } }; - if given_options.opt_present("h") { + if matches.opt_present("h") { println!("{}", opts.usage("")); return 0; } - if given_options.opt_present("V") { version(); return 0 } + if matches.opt_present("V") { version(); return 0 } - let use_bytes = given_options.opt_present("c"); + let use_bytes = matches.opt_present("c"); // TODO: suffixes (e.g. b, kB, etc.) - match given_options.opt_str("n") { + match matches.opt_str("n") { Some(n) => { if use_bytes { show_error!("cannot specify both --bytes and --lines."); @@ -91,7 +95,7 @@ pub fn uumain(args: Vec) -> i32 { } } } - None => match given_options.opt_str("c") { + None => match matches.opt_str("c") { Some(count) => match count.parse::() { Ok(m) => settings.mode = FilterMode::Bytes(m), Err(e)=> { @@ -103,21 +107,32 @@ pub fn uumain(args: Vec) -> i32 { } }; - let files = given_options.free; + let quiet = matches.opt_present("q"); + let verbose = matches.opt_present("v"); + let files = matches.free; + + // GNU implementation allows multiple declarations of "-q" and "-v" with the + // last flag winning. This can't be simulated with the getopts cargo unless + // we manually parse the arguments. Given the declaration of both flags, + // verbose mode always wins. This is a potential future improvement. + if files.len() > 1 && !quiet && !verbose { + settings.verbose = true; + } + if quiet { + settings.verbose = false; + } + if verbose { + settings.verbose = true; + } if files.is_empty() { let mut buffer = BufReader::new(stdin()); head(&mut buffer, &settings); } else { - let mut multiple = false; let mut firstime = true; - if files.len() > 1 { - multiple = true; - } - for file in files.iter() { - if multiple { + if settings.verbose { if !firstime { pipe_println!(""); } pipe_println!("==> {} <==", file); } diff --git a/test/fixtures/head/lorem_ipsum_verbose.expected b/test/fixtures/head/lorem_ipsum_verbose.expected new file mode 100644 index 000000000..5f2d0ea61 --- /dev/null +++ b/test/fixtures/head/lorem_ipsum_verbose.expected @@ -0,0 +1,11 @@ +==> lorem_ipsum.txt <== +Lorem ipsum dolor sit amet, +consectetur adipiscing elit. +Nunc interdum suscipit sem vel ornare. +Proin euismod, +justo sed mollis dictum, +eros urna ultricies augue, +eu pharetra mi ex id ante. +Duis convallis porttitor aliquam. +Nunc vitae tincidunt ex. +Suspendisse iaculis ligula ac diam consectetur lacinia. diff --git a/test/head.rs b/test/head.rs index f92c8cbac..4368225b3 100644 --- a/test/head.rs +++ b/test/head.rs @@ -63,3 +63,10 @@ fn test_single_5_chars() { let result = run(&mut cmd.args(&["-c", "5", INPUT])); assert_eq!(result.stdout, get_file_contents("lorem_ipsum_5_chars.expected")); } + +#[test] +fn test_verbose() { + let mut cmd = Command::new(PROGNAME); + let result = run(&mut cmd.args(&["-v", INPUT])); + assert_eq!(result.stdout, get_file_contents("lorem_ipsum_verbose.expected")); +}