Merge pull request #7623 from drinkcat/parse-bigdecimal-smallfixes

uucore: format: Collection of small parser fixes
This commit is contained in:
Dorian Péron
2025-04-01 12:36:28 +02:00
committed by GitHub
5 changed files with 337 additions and 104 deletions
@@ -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
+13
View File
@@ -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");
}