mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
Merge pull request #7623 from drinkcat/parse-bigdecimal-smallfixes
uucore: format: Collection of small parser fixes
This commit is contained in:
@@ -105,9 +105,13 @@ fn extract_value<T: Default>(p: Result<T, ExtendedParserError<'_, T>>, input: &s
|
||||
},
|
||||
);
|
||||
match e {
|
||||
ExtendedParserError::Overflow => {
|
||||
ExtendedParserError::Overflow(v) => {
|
||||
show_error!("{}: Numerical result out of range", input.quote());
|
||||
Default::default()
|
||||
v
|
||||
}
|
||||
ExtendedParserError::Underflow(v) => {
|
||||
show_error!("{}: Numerical result out of range", input.quote());
|
||||
v
|
||||
}
|
||||
ExtendedParserError::NotNumeric => {
|
||||
show_error!("{}: expected a numeric value", input.quote());
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt::Display;
|
||||
use std::ops::Add;
|
||||
use std::ops::Neg;
|
||||
|
||||
use bigdecimal::BigDecimal;
|
||||
use num_traits::FromPrimitive;
|
||||
@@ -227,6 +228,27 @@ impl PartialOrd for ExtendedBigDecimal {
|
||||
}
|
||||
}
|
||||
|
||||
impl Neg for ExtendedBigDecimal {
|
||||
type Output = Self;
|
||||
|
||||
fn neg(self) -> Self::Output {
|
||||
match self {
|
||||
Self::BigDecimal(bd) => {
|
||||
if bd.is_zero() {
|
||||
Self::MinusZero
|
||||
} else {
|
||||
Self::BigDecimal(bd.neg())
|
||||
}
|
||||
}
|
||||
Self::MinusZero => Self::BigDecimal(BigDecimal::zero()),
|
||||
Self::Infinity => Self::MinusInfinity,
|
||||
Self::MinusInfinity => Self::Infinity,
|
||||
Self::Nan => Self::MinusNan,
|
||||
Self::MinusNan => Self::Nan,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
|
||||
@@ -80,10 +80,12 @@ pub struct SignedInt {
|
||||
|
||||
impl Formatter<i64> for SignedInt {
|
||||
fn fmt(&self, writer: impl Write, x: i64) -> std::io::Result<()> {
|
||||
// -i64::MIN is actually 1 larger than i64::MAX, so we need to cast to i128 first.
|
||||
let abs = (x as i128).abs();
|
||||
let s = if self.precision > 0 {
|
||||
format!("{:0>width$}", x.abs(), width = self.precision)
|
||||
format!("{:0>width$}", abs, width = self.precision)
|
||||
} else {
|
||||
x.abs().to_string()
|
||||
abs.to_string()
|
||||
};
|
||||
|
||||
let sign_indicator = get_sign_indicator(self.positive_sign, x.is_negative());
|
||||
@@ -1046,6 +1048,8 @@ mod test {
|
||||
let format = Format::<SignedInt, i64>::parse("%d").unwrap();
|
||||
assert_eq!(fmt(&format, 123i64), "123");
|
||||
assert_eq!(fmt(&format, -123i64), "-123");
|
||||
assert_eq!(fmt(&format, i64::MAX), "9223372036854775807");
|
||||
assert_eq!(fmt(&format, i64::MIN), "-9223372036854775808");
|
||||
|
||||
let format = Format::<SignedInt, i64>::parse("%i").unwrap();
|
||||
assert_eq!(fmt(&format, 123i64), "123");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -675,6 +675,19 @@ fn test_overflow() {
|
||||
new_ucmd!()
|
||||
.args(&["%d", "36893488147419103232"])
|
||||
.fails_with_code(1)
|
||||
.stdout_is("9223372036854775807")
|
||||
.stderr_is("printf: '36893488147419103232': Numerical result out of range\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["%d", "-36893488147419103232"])
|
||||
.fails_with_code(1)
|
||||
.stdout_is("-9223372036854775808")
|
||||
.stderr_is("printf: '-36893488147419103232': Numerical result out of range\n");
|
||||
|
||||
new_ucmd!()
|
||||
.args(&["%u", "36893488147419103232"])
|
||||
.fails_with_code(1)
|
||||
.stdout_is("18446744073709551615")
|
||||
.stderr_is("printf: '36893488147419103232': Numerical result out of range\n");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user