mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
Merge pull request #7656 from eduardorittner/main
printf: make negative values wrap around with unsigned/hex format
This commit is contained in:
commit
a89fc48388
2 changed files with 69 additions and 13 deletions
|
@ -165,23 +165,24 @@ impl ExtendedParser for u64 {
|
||||||
ExtendedBigDecimal::BigDecimal(bd) => {
|
ExtendedBigDecimal::BigDecimal(bd) => {
|
||||||
let (digits, scale) = bd.into_bigint_and_scale();
|
let (digits, scale) = bd.into_bigint_and_scale();
|
||||||
if scale == 0 {
|
if scale == 0 {
|
||||||
let negative = digits.sign() == Sign::Minus;
|
let (sign, digits) = digits.into_parts();
|
||||||
|
|
||||||
match u64::try_from(digits) {
|
match u64::try_from(digits) {
|
||||||
Ok(i) => Ok(i),
|
Ok(i) => {
|
||||||
_ => Err(ExtendedParserError::Overflow(if negative {
|
if sign == Sign::Minus {
|
||||||
// TODO: We should wrap around here #7488
|
Ok(!i + 1)
|
||||||
0
|
|
||||||
} else {
|
} else {
|
||||||
u64::MAX
|
Ok(i)
|
||||||
})),
|
}
|
||||||
|
}
|
||||||
|
_ => Err(ExtendedParserError::Overflow(u64::MAX)),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Should not happen.
|
// Should not happen.
|
||||||
Err(ExtendedParserError::NotNumeric)
|
Err(ExtendedParserError::NotNumeric)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Handle -0 too #7488
|
ExtendedBigDecimal::MinusZero => Ok(0),
|
||||||
// No other case should not happen.
|
|
||||||
_ => Err(ExtendedParserError::NotNumeric),
|
_ => Err(ExtendedParserError::NotNumeric),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,10 +528,28 @@ mod tests {
|
||||||
fn test_decimal_u64() {
|
fn test_decimal_u64() {
|
||||||
assert_eq!(Ok(123), u64::extended_parse("123"));
|
assert_eq!(Ok(123), u64::extended_parse("123"));
|
||||||
assert_eq!(Ok(u64::MAX), u64::extended_parse(&format!("{}", u64::MAX)));
|
assert_eq!(Ok(u64::MAX), u64::extended_parse(&format!("{}", u64::MAX)));
|
||||||
// TODO: We should wrap around here #7488
|
assert_eq!(Ok(0), u64::extended_parse("-0"));
|
||||||
|
assert_eq!(Ok(u64::MAX), u64::extended_parse("-1"));
|
||||||
|
assert_eq!(
|
||||||
|
Ok(u64::MAX / 2 + 1),
|
||||||
|
u64::extended_parse("-9223372036854775808") // i64::MIN
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Ok(1123372036854675616),
|
||||||
|
u64::extended_parse("-17323372036854876000") // 2*i64::MIN
|
||||||
|
);
|
||||||
|
assert_eq!(Ok(1), u64::extended_parse("-18446744073709551615")); // -u64::MAX
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
u64::extended_parse("-123"),
|
u64::extended_parse("-18446744073709551616"), // -u64::MAX - 1
|
||||||
Err(ExtendedParserError::Overflow(0))
|
Err(ExtendedParserError::Overflow(u64::MAX))
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
u64::extended_parse("-92233720368547758150"),
|
||||||
|
Err(ExtendedParserError::Overflow(u64::MAX))
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
u64::extended_parse("-170141183460469231731687303715884105729"),
|
||||||
|
Err(ExtendedParserError::Overflow(u64::MAX))
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
u64::extended_parse(""),
|
u64::extended_parse(""),
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
//
|
//
|
||||||
// For the full copyright and license information, please view the LICENSE
|
// For the full copyright and license information, please view the LICENSE
|
||||||
// file that was distributed with this source code.
|
// file that was distributed with this source code.
|
||||||
|
|
||||||
|
// spell-checker:ignore fffffffffffffffc
|
||||||
use uutests::new_ucmd;
|
use uutests::new_ucmd;
|
||||||
use uutests::util::TestScenario;
|
use uutests::util::TestScenario;
|
||||||
use uutests::util_name;
|
use uutests::util_name;
|
||||||
|
@ -791,6 +793,41 @@ fn partial_integer() {
|
||||||
.stderr_is("printf: '42x23': value not completely converted\n");
|
.stderr_is("printf: '42x23': value not completely converted\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn unsigned_hex_negative_wraparound() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["%x", "-0b100"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("fffffffffffffffc");
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["%x", "-0100"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("ffffffffffffffc0");
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["%x", "-100"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("ffffffffffffff9c");
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["%x", "-0x100"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("ffffffffffffff00");
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["%x", "-92233720368547758150"])
|
||||||
|
.fails_with_code(1)
|
||||||
|
.stdout_is("ffffffffffffffff")
|
||||||
|
.stderr_is("printf: '-92233720368547758150': Numerical result out of range\n");
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["%u", "-1002233720368547758150"])
|
||||||
|
.fails_with_code(1)
|
||||||
|
.stdout_is("18446744073709551615")
|
||||||
|
.stderr_is("printf: '-1002233720368547758150': Numerical result out of range\n");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_overflow() {
|
fn test_overflow() {
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue