mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
uucore: parser: num_parser: Parse "0x"/"0b" as PartialMatch
printf treats "0x" as a partial match of 0 and "x".
This commit is contained in:
parent
8363274f75
commit
a4c56fbcee
1 changed files with 66 additions and 25 deletions
|
@ -450,9 +450,6 @@ pub(crate) fn parse<'a>(
|
||||||
} else {
|
} else {
|
||||||
(Base::Decimal, unsigned)
|
(Base::Decimal, unsigned)
|
||||||
};
|
};
|
||||||
if rest.is_empty() {
|
|
||||||
return Err(ExtendedParserError::NotNumeric);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the integral part of the number
|
// Parse the integral part of the number
|
||||||
let mut chars = rest.chars().enumerate().fuse().peekable();
|
let mut chars = rest.chars().enumerate().fuse().peekable();
|
||||||
|
@ -518,6 +515,16 @@ pub(crate) fn parse<'a>(
|
||||||
|
|
||||||
// If no digit has been parsed, check if this is a special value, or declare the parsing unsuccessful
|
// If no digit has been parsed, check if this is a special value, or declare the parsing unsuccessful
|
||||||
if digits.is_none() {
|
if digits.is_none() {
|
||||||
|
// If we trimmed an initial `0x`/`0b`, return a partial match.
|
||||||
|
if rest != unsigned {
|
||||||
|
let ebd = if negative {
|
||||||
|
ExtendedBigDecimal::MinusZero
|
||||||
|
} else {
|
||||||
|
ExtendedBigDecimal::zero()
|
||||||
|
};
|
||||||
|
return Err(ExtendedParserError::PartialMatch(ebd, &unsigned[1..]));
|
||||||
|
}
|
||||||
|
|
||||||
return if target == ParseTarget::Integral {
|
return if target == ParseTarget::Integral {
|
||||||
Err(ExtendedParserError::NotNumeric)
|
Err(ExtendedParserError::NotNumeric)
|
||||||
} else {
|
} else {
|
||||||
|
@ -968,23 +975,41 @@ mod tests {
|
||||||
))
|
))
|
||||||
));
|
));
|
||||||
|
|
||||||
// TODO: GNU coreutils treats these as partial matches.
|
// Not actually hex numbers, but the prefixes look like it.
|
||||||
assert_eq!(
|
assert!(matches!(f64::extended_parse("0x"),
|
||||||
Err(ExtendedParserError::NotNumeric),
|
Err(ExtendedParserError::PartialMatch(f, "x")) if f == 0.0));
|
||||||
ExtendedBigDecimal::extended_parse("0x")
|
assert!(matches!(f64::extended_parse("0x."),
|
||||||
);
|
Err(ExtendedParserError::PartialMatch(f, "x.")) if f == 0.0));
|
||||||
assert_eq!(
|
assert!(matches!(f64::extended_parse("0xp"),
|
||||||
Err(ExtendedParserError::NotNumeric),
|
Err(ExtendedParserError::PartialMatch(f, "xp")) if f == 0.0));
|
||||||
ExtendedBigDecimal::extended_parse("0x.")
|
assert!(matches!(f64::extended_parse("0xp-2"),
|
||||||
);
|
Err(ExtendedParserError::PartialMatch(f, "xp-2")) if f == 0.0));
|
||||||
assert_eq!(
|
assert!(matches!(f64::extended_parse("0x.p-2"),
|
||||||
Err(ExtendedParserError::NotNumeric),
|
Err(ExtendedParserError::PartialMatch(f, "x.p-2")) if f == 0.0));
|
||||||
ExtendedBigDecimal::extended_parse("0xp")
|
assert!(matches!(f64::extended_parse("0X"),
|
||||||
);
|
Err(ExtendedParserError::PartialMatch(f, "X")) if f == 0.0));
|
||||||
assert_eq!(
|
assert!(matches!(f64::extended_parse("-0x"),
|
||||||
Err(ExtendedParserError::NotNumeric),
|
Err(ExtendedParserError::PartialMatch(f, "x")) if f == -0.0));
|
||||||
ExtendedBigDecimal::extended_parse("0xp-2")
|
assert!(matches!(f64::extended_parse("+0x"),
|
||||||
);
|
Err(ExtendedParserError::PartialMatch(f, "x")) if f == 0.0));
|
||||||
|
assert!(matches!(f64::extended_parse("-0x."),
|
||||||
|
Err(ExtendedParserError::PartialMatch(f, "x.")) if f == -0.0));
|
||||||
|
assert!(matches!(
|
||||||
|
u64::extended_parse("0x"),
|
||||||
|
Err(ExtendedParserError::PartialMatch(0, "x"))
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
u64::extended_parse("-0x"),
|
||||||
|
Err(ExtendedParserError::PartialMatch(0, "x"))
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
i64::extended_parse("0x"),
|
||||||
|
Err(ExtendedParserError::PartialMatch(0, "x"))
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
i64::extended_parse("-0x"),
|
||||||
|
Err(ExtendedParserError::PartialMatch(0, "x"))
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1018,6 +1043,27 @@ mod tests {
|
||||||
assert_eq!(Ok(0b1011), u64::extended_parse("+0b1011"));
|
assert_eq!(Ok(0b1011), u64::extended_parse("+0b1011"));
|
||||||
assert_eq!(Ok(-0b1011), i64::extended_parse("-0b1011"));
|
assert_eq!(Ok(-0b1011), i64::extended_parse("-0b1011"));
|
||||||
|
|
||||||
|
assert!(matches!(
|
||||||
|
u64::extended_parse("0b"),
|
||||||
|
Err(ExtendedParserError::PartialMatch(0, "b"))
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
u64::extended_parse("0b."),
|
||||||
|
Err(ExtendedParserError::PartialMatch(0, "b."))
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
u64::extended_parse("-0b"),
|
||||||
|
Err(ExtendedParserError::PartialMatch(0, "b"))
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
i64::extended_parse("0b"),
|
||||||
|
Err(ExtendedParserError::PartialMatch(0, "b"))
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
i64::extended_parse("-0b"),
|
||||||
|
Err(ExtendedParserError::PartialMatch(0, "b"))
|
||||||
|
));
|
||||||
|
|
||||||
// Binary not allowed for floats
|
// Binary not allowed for floats
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
f64::extended_parse("0b100"),
|
f64::extended_parse("0b100"),
|
||||||
|
@ -1042,11 +1088,6 @@ mod tests {
|
||||||
Err(ExtendedParserError::PartialMatch(ebd, "b.")) => ebd == ExtendedBigDecimal::zero(),
|
Err(ExtendedParserError::PartialMatch(ebd, "b.")) => ebd == ExtendedBigDecimal::zero(),
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
// TODO: GNU coreutils treats this as partial match.
|
|
||||||
assert_eq!(
|
|
||||||
Err(ExtendedParserError::NotNumeric),
|
|
||||||
u64::extended_parse("0b")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue