mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
seq: adapt output to GNU seq
This commit is contained in:
parent
9b29ac98a5
commit
5329d77cc2
2 changed files with 38 additions and 27 deletions
|
@ -13,6 +13,7 @@ use num_traits::Zero;
|
|||
use num_traits::{Num, ToPrimitive};
|
||||
use std::cmp;
|
||||
use std::io::{stdout, Write};
|
||||
use std::str::FromStr;
|
||||
|
||||
static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
static ABOUT: &str = "Display numbers from FIRST to LAST, in steps of INCREMENT.";
|
||||
|
@ -43,18 +44,6 @@ enum Number {
|
|||
}
|
||||
|
||||
impl Number {
|
||||
fn new(mut s: &str) -> Self {
|
||||
if s.starts_with('+') {
|
||||
s = &s[1..];
|
||||
}
|
||||
|
||||
match s.parse::<BigInt>() {
|
||||
Ok(n) => Number::BigInt(n),
|
||||
// The argument validator made sure this is a valid float.
|
||||
Err(_) => Number::F64(s.parse::<f64>().unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
fn is_zero(&self) -> bool {
|
||||
match self {
|
||||
Number::BigInt(n) => n.is_zero(),
|
||||
|
@ -71,6 +60,32 @@ impl Number {
|
|||
}
|
||||
}
|
||||
|
||||
impl FromStr for Number {
|
||||
type Err = String;
|
||||
fn from_str(mut s: &str) -> Result<Self, Self::Err> {
|
||||
if s.starts_with('+') {
|
||||
s = &s[1..];
|
||||
}
|
||||
|
||||
match s.parse::<BigInt>() {
|
||||
Ok(n) => Ok(Number::BigInt(n)),
|
||||
Err(_) => match s.parse::<f64>() {
|
||||
Ok(value) if value.is_nan() => Err(format!(
|
||||
"invalid 'not-a-number' argument: '{}'\nTry '{} --help' for more information.",
|
||||
s,
|
||||
executable!(),
|
||||
)),
|
||||
Ok(value) => Ok(Number::F64(value)),
|
||||
Err(_) => Err(format!(
|
||||
"invalid floating point argument: '{}'\nTry '{} --help' for more information.",
|
||||
s,
|
||||
executable!(),
|
||||
)),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||
let usage = get_usage();
|
||||
let matches = App::new(executable!())
|
||||
|
@ -106,15 +121,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
.takes_value(true)
|
||||
.allow_hyphen_values(true)
|
||||
.max_values(3)
|
||||
.required(true)
|
||||
.validator(|value| {
|
||||
match value.parse::<f64>() {
|
||||
Ok(value) if value.is_nan() => Err("can not be NaN".to_string()),
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(e.to_string()),
|
||||
}
|
||||
.map_err(|e| format!("invalid floating point argument `{}`: {}", value, e))
|
||||
}),
|
||||
.required(true),
|
||||
)
|
||||
.get_matches_from(args);
|
||||
|
||||
|
@ -134,7 +141,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let dec = slice.find('.').unwrap_or(len);
|
||||
largest_dec = len - dec;
|
||||
padding = dec;
|
||||
Number::new(slice)
|
||||
return_if_err!(1, slice.parse())
|
||||
} else {
|
||||
Number::BigInt(BigInt::one())
|
||||
};
|
||||
|
@ -144,18 +151,22 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let dec = slice.find('.').unwrap_or(len);
|
||||
largest_dec = cmp::max(largest_dec, len - dec);
|
||||
padding = cmp::max(padding, dec);
|
||||
Number::new(slice)
|
||||
return_if_err!(1, slice.parse())
|
||||
} else {
|
||||
Number::BigInt(BigInt::one())
|
||||
};
|
||||
if increment.is_zero() {
|
||||
show_error!("increment value: '{}'", numbers[1]);
|
||||
show_error!(
|
||||
"invalid Zero increment value: '{}'\nTry '{} --help' for more information.",
|
||||
numbers[1],
|
||||
executable!()
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
let last = {
|
||||
let slice = numbers[numbers.len() - 1];
|
||||
padding = cmp::max(padding, slice.find('.').unwrap_or_else(|| slice.len()));
|
||||
Number::new(slice)
|
||||
return_if_err!(1, slice.parse())
|
||||
};
|
||||
if largest_dec > 0 {
|
||||
largest_dec -= 1;
|
||||
|
|
|
@ -5,7 +5,7 @@ fn test_rejects_nan() {
|
|||
new_ucmd!()
|
||||
.args(&["NaN"])
|
||||
.fails()
|
||||
.stderr_only("error: Invalid value for '<numbers>...': invalid floating point argument `NaN`: can not be NaN");
|
||||
.stderr_only("seq: invalid 'not-a-number' argument: 'NaN'\nTry 'seq --help' for more information.");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -13,7 +13,7 @@ fn test_rejects_non_floats() {
|
|||
new_ucmd!()
|
||||
.args(&["foo"])
|
||||
.fails()
|
||||
.stderr_only("error: Invalid value for '<numbers>...': invalid floating point argument `foo`: invalid float literal");
|
||||
.stderr_only("seq: invalid floating point argument: 'foo'\nTry 'seq --help' for more information.");
|
||||
}
|
||||
|
||||
// ---- Tests for the big integer based path ----
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue