From 05b20c32a996e56c9ced87e520e7a23cd19358af Mon Sep 17 00:00:00 2001 From: Ricardo Iglesias Date: Wed, 28 Apr 2021 00:36:27 -0700 Subject: [PATCH 1/3] base64: Moved argument parsing to clap. Moved argument parsing to clap and added tests to cover using "-" as stdin, passing in too many file arguments, and updated the "wrap" error message in the tests. --- Cargo.lock | 1 + src/uu/base64/Cargo.toml | 1 + src/uu/base64/src/base64.rs | 139 +++++++++++++++++++++++-- src/uu/base64/src/base_common.rs | 61 +---------- tests/by-util/test_base64.rs | 40 ++++++- tests/fixtures/base64/input-simple.txt | 1 + 6 files changed, 171 insertions(+), 72 deletions(-) create mode 100644 tests/fixtures/base64/input-simple.txt diff --git a/Cargo.lock b/Cargo.lock index c988d6d12..254ae8fda 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1688,6 +1688,7 @@ dependencies = [ name = "uu_base64" version = "0.0.6" dependencies = [ + "clap", "uucore", "uucore_procs", ] diff --git a/src/uu/base64/Cargo.toml b/src/uu/base64/Cargo.toml index 841ab140c..97241a571 100644 --- a/src/uu/base64/Cargo.toml +++ b/src/uu/base64/Cargo.toml @@ -15,6 +15,7 @@ edition = "2018" path = "src/base64.rs" [dependencies] +clap = "2.33" uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features = ["encoding"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } diff --git a/src/uu/base64/src/base64.rs b/src/uu/base64/src/base64.rs index 61a8dc5cb..62d36cc5f 100644 --- a/src/uu/base64/src/base64.rs +++ b/src/uu/base64/src/base64.rs @@ -8,12 +8,19 @@ #[macro_use] extern crate uucore; + use uucore::encoding::Format; use uucore::InvalidEncodingHandling; +use std::fs::File; +use std::io::{stdin, BufReader}; +use std::path::Path; + +use clap::{App, Arg}; + mod base_common; -static SYNTAX: &str = "[OPTION]... [FILE]"; +static BASE64_ARG_ERROR: i32 = 1; static SUMMARY: &str = "Base64 encode or decode FILE, or standard input, to standard output."; static LONG_HELP: &str = " With no FILE, or when FILE is -, read standard input. @@ -24,14 +31,128 @@ static LONG_HELP: &str = " to attempt to recover from any other non-alphabet bytes in the encoded stream. "; +static VERSION: &str = env!("CARGO_PKG_VERSION"); + +fn get_usage() -> String { + format!("{0} [OPTION]... [FILE]", executable!()) +} + +pub mod options { + pub static DECODE: &str = "decode"; + pub static WRAP: &str = "wrap"; + pub static IGNORE_GARBAGE: &str = "ignore-garbage"; + pub static FILE: &str = "file"; +} + +struct Config { + decode: bool, + ignore_garbage: bool, + wrap_cols: Option, + to_read: Option, +} + +impl Config { + fn from(options: clap::ArgMatches) -> Config { + let file: Option = match options.values_of(options::FILE) { + Some(mut values) => { + let name = values.next().unwrap(); + if values.len() != 0 { + crash!(BASE64_ARG_ERROR, "extra operand ‘{}’", name); + } + + if name == "-" { + None + } else { + if !Path::exists(Path::new(name)) { + crash!(BASE64_ARG_ERROR, "{}: No such file or directory", name); + } + Some(name.to_owned()) + } + } + None => None, + }; + + let cols = match options.value_of(options::WRAP) { + Some(num) => match num.parse::() { + Ok(n) => Some(n), + Err(e) => { + crash!(BASE64_ARG_ERROR, "invalid wrap size: ‘{}’: {}", num, e); + } + }, + None => None, + }; + + Config { + decode: options.is_present(options::DECODE), + ignore_garbage: options.is_present(options::IGNORE_GARBAGE), + wrap_cols: cols, + to_read: file, + } + } +} pub fn uumain(args: impl uucore::Args) -> i32 { - base_common::execute( - args.collect_str(InvalidEncodingHandling::Ignore) - .accept_any(), - SYNTAX, - SUMMARY, - LONG_HELP, - Format::Base64, - ) + let format = Format::Base64; + let usage = get_usage(); + let app = App::new(executable!()) + .version(VERSION) + .about(SUMMARY) + .usage(&usage[..]) + .about(LONG_HELP) + // Format arguments. + .arg( + Arg::with_name(options::DECODE) + .short("d") + .long(options::DECODE) + .help("decode data"), + ) + .arg( + Arg::with_name(options::IGNORE_GARBAGE) + .short("i") + .long(options::IGNORE_GARBAGE) + .help("when decoding, ignore non-alphabetic characters"), + ) + .arg( + Arg::with_name(options::WRAP) + .short("w") + .long(options::WRAP) + .takes_value(true) + .help( + "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", + ), + ) + // "multiple" arguments are used to check whether there is more than one + // file passed in. + .arg(Arg::with_name(options::FILE).index(1).multiple(true)); + + let arg_list = args + .collect_str(InvalidEncodingHandling::ConvertLossy) + .accept_any(); + let config: Config = Config::from(app.get_matches_from(arg_list)); + match config.to_read { + // Read from file. + Some(name) => { + let file_buf = safe_unwrap!(File::open(Path::new(&name))); + let mut input = BufReader::new(file_buf); + base_common::handle_input( + &mut input, + format, + config.wrap_cols, + config.ignore_garbage, + config.decode, + ); + } + // stdin + None => { + base_common::handle_input( + &mut stdin().lock(), + format, + config.wrap_cols, + config.ignore_garbage, + config.decode, + ); + } + }; + + 0 } diff --git a/src/uu/base64/src/base_common.rs b/src/uu/base64/src/base_common.rs index 3f1436fb2..a4b49e499 100644 --- a/src/uu/base64/src/base_common.rs +++ b/src/uu/base64/src/base_common.rs @@ -7,68 +7,11 @@ // For the full copyright and license information, please view the LICENSE file // that was distributed with this source code. -use std::fs::File; -use std::io::{stdin, stdout, BufReader, Read, Write}; -use std::path::Path; +use std::io::{stdout, Read, Write}; use uucore::encoding::{wrap_print, Data, Format}; -pub fn execute( - args: Vec, - syntax: &str, - summary: &str, - long_help: &str, - format: Format, -) -> i32 { - let matches = app!(syntax, summary, long_help) - .optflag("d", "decode", "decode data") - .optflag( - "i", - "ignore-garbage", - "when decoding, ignore non-alphabetic characters", - ) - .optopt( - "w", - "wrap", - "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", - "COLS", - ) - .parse(args); - - let line_wrap = matches.opt_str("wrap").map(|s| match s.parse() { - Ok(n) => n, - Err(e) => { - crash!(1, "invalid wrap size: ‘{}’: {}", s, e); - } - }); - let ignore_garbage = matches.opt_present("ignore-garbage"); - let decode = matches.opt_present("decode"); - - if matches.free.len() > 1 { - show_usage_error!("extra operand ‘{}’", matches.free[0]); - return 1; - } - - if matches.free.is_empty() || &matches.free[0][..] == "-" { - let stdin_raw = stdin(); - handle_input( - &mut stdin_raw.lock(), - format, - line_wrap, - ignore_garbage, - decode, - ); - } else { - let path = Path::new(matches.free[0].as_str()); - let file_buf = safe_unwrap!(File::open(&path)); - let mut input = BufReader::new(file_buf); - handle_input(&mut input, format, line_wrap, ignore_garbage, decode); - }; - - 0 -} - -fn handle_input( +pub fn handle_input( input: &mut R, format: Format, line_wrap: Option, diff --git a/tests/by-util/test_base64.rs b/tests/by-util/test_base64.rs index 6bc0436c5..c9adc5c0f 100644 --- a/tests/by-util/test_base64.rs +++ b/tests/by-util/test_base64.rs @@ -7,6 +7,21 @@ fn test_encode() { .pipe_in(input) .succeeds() .stdout_only("aGVsbG8sIHdvcmxkIQ==\n"); + + // Using '-' as our file + new_ucmd!() + .arg("-") + .pipe_in(input) + .succeeds() + .stdout_only("aGVsbG8sIHdvcmxkIQ==\n"); +} + +#[test] +fn test_base64_encode_file() { + new_ucmd!() + .arg("input-simple.txt") + .succeeds() + .stdout_only("SGVsbG8sIFdvcmxkIQo=\n"); } #[test] @@ -60,10 +75,9 @@ fn test_wrap() { #[test] fn test_wrap_no_arg() { for wrap_param in vec!["-w", "--wrap"] { - new_ucmd!().arg(wrap_param).fails().stderr_only(format!( - "base64: error: Argument to option '{}' missing\n", - if wrap_param == "-w" { "w" } else { "wrap" } - )); + new_ucmd!().arg(wrap_param).fails().stderr_contains( + &"The argument '--wrap ' requires a value but none was supplied", + ); } } @@ -77,3 +91,21 @@ fn test_wrap_bad_arg() { .stderr_only("base64: error: invalid wrap size: ‘b’: invalid digit found in string\n"); } } + +#[test] +fn test_base64_extra_operand() { + // Expect a failure when multiple files are specified. + new_ucmd!() + .arg("a.txt") + .arg("a.txt") + .fails() + .stderr_only("base64: error: extra operand ‘a.txt’"); +} + +#[test] +fn test_base64_file_not_found() { + new_ucmd!() + .arg("a.txt") + .fails() + .stderr_only("base64: error: a.txt: No such file or directory"); +} diff --git a/tests/fixtures/base64/input-simple.txt b/tests/fixtures/base64/input-simple.txt new file mode 100644 index 000000000..8ab686eaf --- /dev/null +++ b/tests/fixtures/base64/input-simple.txt @@ -0,0 +1 @@ +Hello, World! From f307de22d0636247c7cfbb4b6db88ea29971a7d6 Mon Sep 17 00:00:00 2001 From: Ricardo Iglesias Date: Thu, 29 Apr 2021 01:59:43 -0700 Subject: [PATCH 2/3] base64: Refactor argument parsing Moved most of the argument parsing logic to `base32/base_common.rs` to allow for significant code reuse. --- Cargo.lock | 1 + src/uu/base32/src/base32.rs | 152 +++++++------------------------ src/uu/base32/src/base_common.rs | 125 ++++++++++++++++++++++++- src/uu/base64/Cargo.toml | 1 + src/uu/base64/src/base64.rs | 151 ++++++------------------------ src/uu/base64/src/base_common.rs | 40 -------- tests/by-util/test_base32.rs | 2 +- tests/by-util/test_base64.rs | 2 +- 8 files changed, 187 insertions(+), 287 deletions(-) delete mode 100644 src/uu/base64/src/base_common.rs diff --git a/Cargo.lock b/Cargo.lock index 254ae8fda..54ddbd88e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1689,6 +1689,7 @@ name = "uu_base64" version = "0.0.6" dependencies = [ "clap", + "uu_base32", "uucore", "uucore_procs", ] diff --git a/src/uu/base32/src/base32.rs b/src/uu/base32/src/base32.rs index 6d9f7f08f..f0e187c31 100644 --- a/src/uu/base32/src/base32.rs +++ b/src/uu/base32/src/base32.rs @@ -7,19 +7,14 @@ #[macro_use] extern crate uucore; + +use std::io::{stdin, Read}; + use uucore::encoding::Format; -use uucore::InvalidEncodingHandling; -use std::fs::File; -use std::io::{stdin, BufReader}; -use std::path::Path; +pub mod base_common; -use clap::{App, Arg}; - -mod base_common; - -static SUMMARY: &str = "Base32 encode or decode FILE, or standard input, to standard output."; -static LONG_HELP: &str = " +static ABOUT: &str = " With no FILE, or when FILE is -, read standard input. The data are encoded as described for the base32 alphabet in RFC @@ -30,126 +25,41 @@ static LONG_HELP: &str = " "; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static BASE_CMD_PARSE_ERROR: i32 = 1; + fn get_usage() -> String { format!("{0} [OPTION]... [FILE]", executable!()) } -pub mod options { - pub static DECODE: &str = "decode"; - pub static WRAP: &str = "wrap"; - pub static IGNORE_GARBAGE: &str = "ignore-garbage"; - pub static FILE: &str = "file"; -} - -struct Config { - decode: bool, - ignore_garbage: bool, - wrap_cols: Option, - to_read: Option, -} - -impl Config { - fn from(options: clap::ArgMatches) -> Config { - let file: Option = match options.values_of(options::FILE) { - Some(mut values) => { - let name = values.next().unwrap(); - if values.len() != 0 { - crash!(3, "extra operand ‘{}’", name); - } - - if name == "-" { - None - } else { - if !Path::exists(Path::new(name)) { - crash!(2, "{}: No such file or directory", name); - } - Some(name.to_owned()) - } - } - None => None, - }; - - let cols = match options.value_of(options::WRAP) { - Some(num) => match num.parse::() { - Ok(n) => Some(n), - Err(e) => { - crash!(1, "invalid wrap size: ‘{}’: {}", num, e); - } - }, - None => None, - }; - - Config { - decode: options.is_present(options::DECODE), - ignore_garbage: options.is_present(options::IGNORE_GARBAGE), - wrap_cols: cols, - to_read: file, - } - } -} - pub fn uumain(args: impl uucore::Args) -> i32 { let format = Format::Base32; let usage = get_usage(); - let app = App::new(executable!()) - .version(VERSION) - .about(SUMMARY) - .usage(&usage[..]) - .about(LONG_HELP) - // Format arguments. - .arg( - Arg::with_name(options::DECODE) - .short("d") - .long(options::DECODE) - .help("decode data"), - ) - .arg( - Arg::with_name(options::IGNORE_GARBAGE) - .short("i") - .long(options::IGNORE_GARBAGE) - .help("when decoding, ignore non-alphabetic characters"), - ) - .arg( - Arg::with_name(options::WRAP) - .short("w") - .long(options::WRAP) - .takes_value(true) - .help( - "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", - ), - ) - // "multiple" arguments are used to check whether there is more than one - // file passed in. - .arg(Arg::with_name(options::FILE).index(1).multiple(true)); + let name = executable!(); - let arg_list = args - .collect_str(InvalidEncodingHandling::ConvertLossy) - .accept_any(); - let config: Config = Config::from(app.get_matches_from(arg_list)); - match config.to_read { - // Read from file. - Some(name) => { - let file_buf = safe_unwrap!(File::open(Path::new(&name))); - let mut input = BufReader::new(file_buf); - base_common::handle_input( - &mut input, - format, - config.wrap_cols, - config.ignore_garbage, - config.decode, - ); + let config_result: Result = + base_common::parse_base_cmd_args(args, name, VERSION, ABOUT, &usage); + + if config_result.is_err() { + match config_result { + Ok(_) => panic!(), + Err(s) => crash!(BASE_CMD_PARSE_ERROR, "{}", s), } - // stdin - None => { - base_common::handle_input( - &mut stdin().lock(), - format, - config.wrap_cols, - config.ignore_garbage, - config.decode, - ); - } - }; + } + + // Create a reference to stdin so we can return a locked stdin from + // parse_base_cmd_args + let stdin_raw = stdin(); + let config = config_result.unwrap(); + let mut input: Box = base_common::get_input(&config, &stdin_raw); + + base_common::handle_input( + &mut input, + format, + config.wrap_cols, + config.ignore_garbage, + config.decode, + name, + ); 0 } diff --git a/src/uu/base32/src/base_common.rs b/src/uu/base32/src/base_common.rs index a4b49e499..d0f47f500 100644 --- a/src/uu/base32/src/base_common.rs +++ b/src/uu/base32/src/base_common.rs @@ -10,6 +10,122 @@ use std::io::{stdout, Read, Write}; use uucore::encoding::{wrap_print, Data, Format}; +use uucore::InvalidEncodingHandling; + +use std::fs::File; +use std::io::{BufReader, Stdin}; +use std::path::Path; + +use clap::{App, Arg}; + +// Config. +pub struct Config { + pub decode: bool, + pub ignore_garbage: bool, + pub wrap_cols: Option, + pub to_read: Option, +} + +pub mod options { + pub static DECODE: &str = "decode"; + pub static WRAP: &str = "wrap"; + pub static IGNORE_GARBAGE: &str = "ignore-garbage"; + pub static FILE: &str = "file"; +} + +impl Config { + fn from(options: clap::ArgMatches) -> Result { + let file: Option = match options.values_of(options::FILE) { + Some(mut values) => { + let name = values.next().unwrap(); + if values.len() != 0 { + return Err(format!("extra operand ‘{}’", name)); + } + + if name == "-" { + None + } else { + if !Path::exists(Path::new(name)) { + return Err(format!("{}: No such file or directory", name)); + } + Some(name.to_owned()) + } + } + None => None, + }; + + let cols = match options.value_of(options::WRAP) { + Some(num) => match num.parse::() { + Ok(n) => Some(n), + Err(e) => { + return Err(format!("Invalid wrap size: ‘{}’: {}", num, e)); + } + }, + None => None, + }; + + Ok(Config { + decode: options.is_present(options::DECODE), + ignore_garbage: options.is_present(options::IGNORE_GARBAGE), + wrap_cols: cols, + to_read: file, + }) + } +} + +pub fn parse_base_cmd_args( + args: impl uucore::Args, + name: &str, + version: &str, + about: &str, + usage: &str, +) -> Result { + let app = App::new(name) + .version(version) + .about(about) + .usage(&usage[..]) + // Format arguments. + .arg( + Arg::with_name(options::DECODE) + .short("d") + .long(options::DECODE) + .help("decode data"), + ) + .arg( + Arg::with_name(options::IGNORE_GARBAGE) + .short("i") + .long(options::IGNORE_GARBAGE) + .help("when decoding, ignore non-alphabetic characters"), + ) + .arg( + Arg::with_name(options::WRAP) + .short("w") + .long(options::WRAP) + .takes_value(true) + .help( + "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", + ), + ) + // "multiple" arguments are used to check whether there is more than one + // file passed in. + .arg(Arg::with_name(options::FILE).index(1).multiple(true)); + let arg_list = args + .collect_str(InvalidEncodingHandling::ConvertLossy) + .accept_any(); + Config::from(app.get_matches_from(arg_list)) +} + +pub fn get_input<'a>(config: &Config, stdin_ref: &'a Stdin) -> Box { + match &config.to_read { + Some(name) => { + let file_buf = safe_unwrap!(File::open(Path::new(name))); + Box::new(BufReader::new(file_buf)) // as Box + } + None => { + Box::new(stdin_ref.lock()) // as Box + } + } +} pub fn handle_input( input: &mut R, @@ -17,6 +133,7 @@ pub fn handle_input( line_wrap: Option, ignore_garbage: bool, decode: bool, + name: &str, ) { let mut data = Data::new(input, format).ignore_garbage(ignore_garbage); if let Some(wrap) = line_wrap { @@ -31,10 +148,14 @@ pub fn handle_input( Ok(s) => { if stdout().write_all(&s).is_err() { // on windows console, writing invalid utf8 returns an error - crash!(1, "Cannot write non-utf8 data"); + eprintln!("{}: error: Cannot write non-utf8 data", name); + exit!(1) } } - Err(_) => crash!(1, "invalid input"), + Err(_) => { + eprintln!("{}: error: invalid input", name); + exit!(1) + } } } } diff --git a/src/uu/base64/Cargo.toml b/src/uu/base64/Cargo.toml index 97241a571..d4ee69f03 100644 --- a/src/uu/base64/Cargo.toml +++ b/src/uu/base64/Cargo.toml @@ -18,6 +18,7 @@ path = "src/base64.rs" clap = "2.33" uucore = { version=">=0.0.8", package="uucore", path="../../uucore", features = ["encoding"] } uucore_procs = { version=">=0.0.5", package="uucore_procs", path="../../uucore_procs" } +uu_base32 = { version=">=0.0.6", package="uu_base32", path="../base32"} [[bin]] name = "base64" diff --git a/src/uu/base64/src/base64.rs b/src/uu/base64/src/base64.rs index 62d36cc5f..810df4fe8 100644 --- a/src/uu/base64/src/base64.rs +++ b/src/uu/base64/src/base64.rs @@ -9,20 +9,13 @@ #[macro_use] extern crate uucore; +use uu_base32::base_common; + use uucore::encoding::Format; -use uucore::InvalidEncodingHandling; -use std::fs::File; -use std::io::{stdin, BufReader}; -use std::path::Path; +use std::io::{stdin, Read}; -use clap::{App, Arg}; - -mod base_common; - -static BASE64_ARG_ERROR: i32 = 1; -static SUMMARY: &str = "Base64 encode or decode FILE, or standard input, to standard output."; -static LONG_HELP: &str = " +static ABOUT: &str = " With no FILE, or when FILE is -, read standard input. The data are encoded as described for the base64 alphabet in RFC @@ -33,126 +26,40 @@ static LONG_HELP: &str = " "; static VERSION: &str = env!("CARGO_PKG_VERSION"); +static BASE_CMD_PARSE_ERROR: i32 = 1; + fn get_usage() -> String { format!("{0} [OPTION]... [FILE]", executable!()) } -pub mod options { - pub static DECODE: &str = "decode"; - pub static WRAP: &str = "wrap"; - pub static IGNORE_GARBAGE: &str = "ignore-garbage"; - pub static FILE: &str = "file"; -} - -struct Config { - decode: bool, - ignore_garbage: bool, - wrap_cols: Option, - to_read: Option, -} - -impl Config { - fn from(options: clap::ArgMatches) -> Config { - let file: Option = match options.values_of(options::FILE) { - Some(mut values) => { - let name = values.next().unwrap(); - if values.len() != 0 { - crash!(BASE64_ARG_ERROR, "extra operand ‘{}’", name); - } - - if name == "-" { - None - } else { - if !Path::exists(Path::new(name)) { - crash!(BASE64_ARG_ERROR, "{}: No such file or directory", name); - } - Some(name.to_owned()) - } - } - None => None, - }; - - let cols = match options.value_of(options::WRAP) { - Some(num) => match num.parse::() { - Ok(n) => Some(n), - Err(e) => { - crash!(BASE64_ARG_ERROR, "invalid wrap size: ‘{}’: {}", num, e); - } - }, - None => None, - }; - - Config { - decode: options.is_present(options::DECODE), - ignore_garbage: options.is_present(options::IGNORE_GARBAGE), - wrap_cols: cols, - to_read: file, - } - } -} - pub fn uumain(args: impl uucore::Args) -> i32 { let format = Format::Base64; let usage = get_usage(); - let app = App::new(executable!()) - .version(VERSION) - .about(SUMMARY) - .usage(&usage[..]) - .about(LONG_HELP) - // Format arguments. - .arg( - Arg::with_name(options::DECODE) - .short("d") - .long(options::DECODE) - .help("decode data"), - ) - .arg( - Arg::with_name(options::IGNORE_GARBAGE) - .short("i") - .long(options::IGNORE_GARBAGE) - .help("when decoding, ignore non-alphabetic characters"), - ) - .arg( - Arg::with_name(options::WRAP) - .short("w") - .long(options::WRAP) - .takes_value(true) - .help( - "wrap encoded lines after COLS character (default 76, 0 to disable wrapping)", - ), - ) - // "multiple" arguments are used to check whether there is more than one - // file passed in. - .arg(Arg::with_name(options::FILE).index(1).multiple(true)); + let name = executable!(); + let config_result: Result = + base_common::parse_base_cmd_args(args, name, VERSION, ABOUT, &usage); - let arg_list = args - .collect_str(InvalidEncodingHandling::ConvertLossy) - .accept_any(); - let config: Config = Config::from(app.get_matches_from(arg_list)); - match config.to_read { - // Read from file. - Some(name) => { - let file_buf = safe_unwrap!(File::open(Path::new(&name))); - let mut input = BufReader::new(file_buf); - base_common::handle_input( - &mut input, - format, - config.wrap_cols, - config.ignore_garbage, - config.decode, - ); + if config_result.is_err() { + match config_result { + Ok(_) => panic!(), + Err(s) => crash!(BASE_CMD_PARSE_ERROR, "{}", s), } - // stdin - None => { - base_common::handle_input( - &mut stdin().lock(), - format, - config.wrap_cols, - config.ignore_garbage, - config.decode, - ); - } - }; + } + + // Create a reference to stdin so we can return a locked stdin from + // parse_base_cmd_args + let stdin_raw = stdin(); + let config = config_result.unwrap(); + let mut input: Box = base_common::get_input(&config, &stdin_raw); + + base_common::handle_input( + &mut input, + format, + config.wrap_cols, + config.ignore_garbage, + config.decode, + name, + ); 0 } diff --git a/src/uu/base64/src/base_common.rs b/src/uu/base64/src/base_common.rs deleted file mode 100644 index a4b49e499..000000000 --- a/src/uu/base64/src/base_common.rs +++ /dev/null @@ -1,40 +0,0 @@ -// This file is part of the uutils coreutils package. -// -// (c) Jordy Dickinson -// (c) Jian Zeng -// (c) Alex Lyon -// -// For the full copyright and license information, please view the LICENSE file -// that was distributed with this source code. - -use std::io::{stdout, Read, Write}; - -use uucore::encoding::{wrap_print, Data, Format}; - -pub fn handle_input( - input: &mut R, - format: Format, - line_wrap: Option, - ignore_garbage: bool, - decode: bool, -) { - let mut data = Data::new(input, format).ignore_garbage(ignore_garbage); - if let Some(wrap) = line_wrap { - data = data.line_wrap(wrap); - } - - if !decode { - let encoded = data.encode(); - wrap_print(&data, encoded); - } else { - match data.decode() { - Ok(s) => { - if stdout().write_all(&s).is_err() { - // on windows console, writing invalid utf8 returns an error - crash!(1, "Cannot write non-utf8 data"); - } - } - Err(_) => crash!(1, "invalid input"), - } - } -} diff --git a/tests/by-util/test_base32.rs b/tests/by-util/test_base32.rs index 157503d83..fd49aa951 100644 --- a/tests/by-util/test_base32.rs +++ b/tests/by-util/test_base32.rs @@ -98,7 +98,7 @@ fn test_wrap_bad_arg() { .arg(wrap_param) .arg("b") .fails() - .stderr_only("base32: error: invalid wrap size: ‘b’: invalid digit found in string\n"); + .stderr_only("base32: error: Invalid wrap size: ‘b’: invalid digit found in string\n"); } } diff --git a/tests/by-util/test_base64.rs b/tests/by-util/test_base64.rs index c9adc5c0f..8d9dc5639 100644 --- a/tests/by-util/test_base64.rs +++ b/tests/by-util/test_base64.rs @@ -88,7 +88,7 @@ fn test_wrap_bad_arg() { .arg(wrap_param) .arg("b") .fails() - .stderr_only("base64: error: invalid wrap size: ‘b’: invalid digit found in string\n"); + .stderr_only("base64: error: Invalid wrap size: ‘b’: invalid digit found in string\n"); } } From 193ad56c2a5e9a615618de8e74368c8cc2c1baad Mon Sep 17 00:00:00 2001 From: Ricardo Iglesias Date: Thu, 29 Apr 2021 02:07:59 -0700 Subject: [PATCH 3/3] Removed clippy warnings. --- src/uu/base32/src/base_common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/base32/src/base_common.rs b/src/uu/base32/src/base_common.rs index d0f47f500..ee5fe8675 100644 --- a/src/uu/base32/src/base_common.rs +++ b/src/uu/base32/src/base_common.rs @@ -83,7 +83,7 @@ pub fn parse_base_cmd_args( let app = App::new(name) .version(version) .about(about) - .usage(&usage[..]) + .usage(usage) // Format arguments. .arg( Arg::with_name(options::DECODE)