mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 19:17:43 +00:00
Merge pull request #5955 from tertsdiepraam/printf-pad-octal-prefix
`printf`: pad unsigned numbers properly
This commit is contained in:
commit
da139c9524
2 changed files with 70 additions and 32 deletions
|
@ -140,43 +140,25 @@ impl Formatter for UnsignedInt {
|
||||||
fn fmt(&self, mut writer: impl Write, x: Self::Input) -> std::io::Result<()> {
|
fn fmt(&self, mut writer: impl Write, x: Self::Input) -> std::io::Result<()> {
|
||||||
let mut s = match self.variant {
|
let mut s = match self.variant {
|
||||||
UnsignedIntVariant::Decimal => format!("{x}"),
|
UnsignedIntVariant::Decimal => format!("{x}"),
|
||||||
UnsignedIntVariant::Octal(Prefix::No) => format!("{x:o}"),
|
UnsignedIntVariant::Octal(_) => format!("{x:o}"),
|
||||||
UnsignedIntVariant::Octal(Prefix::Yes) => {
|
UnsignedIntVariant::Hexadecimal(Case::Lowercase, _) => {
|
||||||
// The prefix that rust uses is `0o`, but GNU uses `0`.
|
|
||||||
// We also need to take into account that 0 should not be 00
|
|
||||||
// Since this is an unsigned int, we do not need to take the minus
|
|
||||||
// sign into account.
|
|
||||||
if x == 0 {
|
|
||||||
format!("{x:o}")
|
|
||||||
} else {
|
|
||||||
format!("0{x:o}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UnsignedIntVariant::Hexadecimal(Case::Lowercase, Prefix::No) => {
|
|
||||||
format!("{x:x}")
|
format!("{x:x}")
|
||||||
}
|
}
|
||||||
UnsignedIntVariant::Hexadecimal(Case::Lowercase, Prefix::Yes) => {
|
UnsignedIntVariant::Hexadecimal(Case::Uppercase, _) => {
|
||||||
if x == 0 {
|
|
||||||
"0".to_string()
|
|
||||||
} else {
|
|
||||||
format!("{x:#x}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UnsignedIntVariant::Hexadecimal(Case::Uppercase, Prefix::No) => {
|
|
||||||
format!("{x:X}")
|
format!("{x:X}")
|
||||||
}
|
}
|
||||||
UnsignedIntVariant::Hexadecimal(Case::Uppercase, Prefix::Yes) => {
|
|
||||||
if x == 0 {
|
|
||||||
"0".to_string()
|
|
||||||
} else {
|
|
||||||
format!("{x:#X}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.precision > s.len() {
|
// Zeroes do not get a prefix. An octal value does also not get a
|
||||||
s = format!("{:0width$}", s, width = self.precision);
|
// prefix if the padded value will not start with a zero.
|
||||||
}
|
let prefix = match (x, self.variant) {
|
||||||
|
(1.., UnsignedIntVariant::Hexadecimal(Case::Lowercase, Prefix::Yes)) => "0x",
|
||||||
|
(1.., UnsignedIntVariant::Hexadecimal(Case::Uppercase, Prefix::Yes)) => "0X",
|
||||||
|
(1.., UnsignedIntVariant::Octal(Prefix::Yes)) if s.len() >= self.precision => "0",
|
||||||
|
_ => "",
|
||||||
|
};
|
||||||
|
|
||||||
|
s = format!("{prefix}{s:0>width$}", width = self.precision);
|
||||||
|
|
||||||
match self.alignment {
|
match self.alignment {
|
||||||
NumberAlignment::Left => write!(writer, "{s:<width$}", width = self.width),
|
NumberAlignment::Left => write!(writer, "{s:<width$}", width = self.width),
|
||||||
|
|
|
@ -668,7 +668,7 @@ fn sub_alternative_upper_hex() {
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
.args(&["%#X", "42"])
|
.args(&["%#X", "42"])
|
||||||
.succeeds()
|
.succeeds()
|
||||||
.stdout_only("0x2A");
|
.stdout_only("0X2A");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -680,3 +680,59 @@ fn char_as_byte() {
|
||||||
fn no_infinite_loop() {
|
fn no_infinite_loop() {
|
||||||
new_ucmd!().args(&["a", "b"]).succeeds().stdout_only("a");
|
new_ucmd!().args(&["a", "b"]).succeeds().stdout_only("a");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pad_octal_with_prefix() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[">%#15.6o<", "0"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("> 000000<");
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[">%#15.6o<", "01"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("> 000001<");
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[">%#15.6o<", "01234"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("> 001234<");
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[">%#15.6o<", "012345"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("> 012345<");
|
||||||
|
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[">%#15.6o<", "0123456"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("> 0123456<");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pad_unsigned_zeroes() {
|
||||||
|
for format in ["%.3u", "%.3x", "%.3X", "%.3o"] {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[format, "0"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only("000");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pad_unsigned_three() {
|
||||||
|
for (format, expected) in [
|
||||||
|
("%.3u", "003"),
|
||||||
|
("%.3x", "003"),
|
||||||
|
("%.3X", "003"),
|
||||||
|
("%.3o", "003"),
|
||||||
|
("%#.3x", "0x003"),
|
||||||
|
("%#.3X", "0X003"),
|
||||||
|
("%#.3o", "003"),
|
||||||
|
] {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&[format, "3"])
|
||||||
|
.succeeds()
|
||||||
|
.stdout_only(expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue