1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 19:47:45 +00:00

stdbuf: use "parse_size" from uucore

This commit is contained in:
Jan Scheer 2021-05-31 09:35:46 +02:00
parent 0bf14da490
commit 1c41efd732
2 changed files with 13 additions and 41 deletions

View file

@ -19,14 +19,14 @@ use std::path::PathBuf;
use std::process::Command; use std::process::Command;
use tempfile::tempdir; use tempfile::tempdir;
use tempfile::TempDir; use tempfile::TempDir;
use uucore::parse_size::parse_size;
use uucore::InvalidEncodingHandling; use uucore::InvalidEncodingHandling;
static VERSION: &str = env!("CARGO_PKG_VERSION"); static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = static ABOUT: &str =
"Run COMMAND, with modified buffering operations for its standard streams.\n\n\ "Run COMMAND, with modified buffering operations for its standard streams.\n\n\
Mandatory arguments to long options are mandatory for short options too."; Mandatory arguments to long options are mandatory for short options too.";
static LONG_HELP: &str = static LONG_HELP: &str = "If MODE is 'L' the corresponding stream will be line buffered.\n\
"If MODE is 'L' the corresponding stream will be line buffered.\n\
This option is invalid with standard input.\n\n\ This option is invalid with standard input.\n\n\
If MODE is '0' the corresponding stream will be unbuffered.\n\n\ If MODE is '0' the corresponding stream will be unbuffered.\n\n\
Otherwise MODE is a number which may be followed by one of the following:\n\n\ Otherwise MODE is a number which may be followed by one of the following:\n\n\
@ -57,7 +57,7 @@ const STDBUF_INJECT: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/libstdbuf
enum BufferType { enum BufferType {
Default, Default,
Line, Line,
Size(u64), Size(usize),
} }
struct ProgramOptions { struct ProgramOptions {
@ -106,41 +106,6 @@ fn preload_strings() -> (&'static str, &'static str) {
crash!(1, "Command not supported for this operating system!") crash!(1, "Command not supported for this operating system!")
} }
fn parse_size(size: &str) -> Option<u64> {
let ext = size.trim_start_matches(|c: char| c.is_digit(10));
let num = size.trim_end_matches(char::is_alphabetic);
let mut recovered = num.to_owned();
recovered.push_str(ext);
if recovered != size {
return None;
}
let buf_size: u64 = match num.parse().ok() {
Some(m) => m,
None => return None,
};
let (power, base): (u32, u64) = match ext {
"" => (0, 0),
"KB" => (1, 1024),
"K" => (1, 1000),
"MB" => (2, 1024),
"M" => (2, 1000),
"GB" => (3, 1024),
"G" => (3, 1000),
"TB" => (4, 1024),
"T" => (4, 1000),
"PB" => (5, 1024),
"P" => (5, 1000),
"EB" => (6, 1024),
"E" => (6, 1000),
"ZB" => (7, 1024),
"Z" => (7, 1000),
"YB" => (8, 1024),
"Y" => (8, 1000),
_ => return None,
};
Some(buf_size * base.pow(power))
}
fn check_option(matches: &ArgMatches, name: &str) -> Result<BufferType, ProgramOptionsError> { fn check_option(matches: &ArgMatches, name: &str) -> Result<BufferType, ProgramOptionsError> {
match matches.value_of(name) { match matches.value_of(name) {
Some(value) => match value { Some(value) => match value {
@ -155,8 +120,8 @@ fn check_option(matches: &ArgMatches, name: &str) -> Result<BufferType, ProgramO
} }
x => { x => {
let size = match parse_size(x) { let size = match parse_size(x) {
Some(m) => m, Ok(m) => m,
None => return Err(ProgramOptionsError(format!("invalid mode {}", x))), Err(e) => return Err(ProgramOptionsError(format!("invalid mode {}", e))),
}; };
Ok(BufferType::Size(size)) Ok(BufferType::Size(size))
} }

View file

@ -57,8 +57,15 @@ fn test_stdbuf_line_buffering_stdin_fails() {
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
#[test] #[test]
fn test_stdbuf_invalid_mode_fails() { fn test_stdbuf_invalid_mode_fails() {
// TODO: GNU's `stdbuf` (8.32) does not return "\nTry 'stdbuf --help' for more information."
// for invalid modes.
new_ucmd!() new_ucmd!()
.args(&["-i", "1024R", "head"]) .args(&["-i", "1024R", "head"])
.fails() .fails()
.stderr_is("stdbuf: invalid mode 1024R\nTry 'stdbuf --help' for more information."); .stderr_contains("stdbuf: invalid mode 1024R");
#[cfg(not(target_pointer_width = "128"))]
new_ucmd!()
.args(&["--error", "1Y", "head"])
.fails()
.stderr_contains("stdbuf: invalid mode 1Y: Value too large to be stored in data type");
} }