diff --git a/Cargo.lock b/Cargo.lock index db334658a..30c808495 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1928,7 +1928,7 @@ dependencies = [ name = "yes" version = "0.0.1" dependencies = [ - "getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.31.1 (registry+https://github.com/rust-lang/crates.io-index)", "uucore 0.0.1", ] diff --git a/src/yes/Cargo.toml b/src/yes/Cargo.toml index ae5bf20f6..76ae141f2 100644 --- a/src/yes/Cargo.toml +++ b/src/yes/Cargo.toml @@ -2,6 +2,7 @@ name = "yes" version = "0.0.1" authors = [] +description = "Repeatedly output a line with all specified STRING(s), or 'y'." build = "../../mkmain.rs" [lib] @@ -9,8 +10,11 @@ name = "uu_yes" path = "yes.rs" [dependencies] -getopts = "0.2.14" -uucore = { path="../uucore" } +clap = "2.31" + +[dependencies.uucore] +path = "../uucore" +default-features = false [[bin]] name = "yes" diff --git a/src/yes/yes.rs b/src/yes/yes.rs index 99b4efb81..2eadb4e58 100644 --- a/src/yes/yes.rs +++ b/src/yes/yes.rs @@ -11,54 +11,50 @@ /* last synced with: yes (GNU coreutils) 8.13 */ -extern crate getopts; - +#[macro_use] +extern crate clap; #[macro_use] extern crate uucore; -use getopts::Options; +use clap::Arg; +use std::borrow::Cow; +use std::io::{self, Write}; -static NAME: &'static str = "yes"; -static VERSION: &'static str = env!("CARGO_PKG_VERSION"); +// force a re-build whenever Cargo.toml changes +const _CARGO_TOML: &'static str = include_str!("Cargo.toml"); const BUF_SIZE: usize = 8192; pub fn uumain(args: Vec) -> i32 { - let mut opts = Options::new(); + let app = app_from_crate!().arg(Arg::with_name("STRING").index(1).multiple(true)); - opts.optflag("h", "help", "display this help and exit"); - opts.optflag("V", "version", "output version information and exit"); - - let matches = match opts.parse(&args[1..]) { + let matches = match app.get_matches_from_safe(args) { Ok(m) => m, - Err(f) => crash!(1, "invalid options\n{}", f), - }; - if matches.opt_present("help") { - println!("{} {}", NAME, VERSION); - println!(""); - println!("Usage:"); - println!(" {0} [STRING]... [OPTION]...", NAME); - println!(""); - print!( - "{}", - opts.usage("Repeatedly output a line with all specified STRING(s), or 'y'.") - ); - return 0; - } - if matches.opt_present("version") { - println!("{} {}", NAME, VERSION); - return 0; - } - let string = if matches.free.is_empty() { - "y".to_owned() - } else { - matches.free.join(" ") + Err(ref e) + if e.kind == clap::ErrorKind::HelpDisplayed + || e.kind == clap::ErrorKind::VersionDisplayed => + { + println!("{}", e); + return 0; + } + Err(f) => { + show_error!("{}", f); + return 1; + } }; - let mut multistring = string.clone(); + let string = if let Some(values) = matches.values_of("STRING") { + let mut result = values.fold(String::new(), |res, s| res + s + " "); + result.pop(); + Cow::from(result) + } else { + Cow::from("y") + }; + + let mut multistring = String::with_capacity(BUF_SIZE); while multistring.len() < BUF_SIZE - string.len() - 1 { - multistring.push_str("\n"); multistring.push_str(&string); + multistring.push_str("\n"); } exec(&multistring[..]); @@ -67,7 +63,9 @@ pub fn uumain(args: Vec) -> i32 { } pub fn exec(string: &str) { + let stdout_raw = io::stdout(); + let mut stdout = stdout_raw.lock(); loop { - println!("{}", string) + writeln!(stdout, "{}", string).unwrap(); } }