From 9858fef20ec1e3d4acd16ed74b63452dfd7d9b18 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Mon, 8 Jan 2024 13:28:24 +0100 Subject: [PATCH] printf: use 0 instead of 0o as octal prefix --- .../src/lib/features/format/num_format.rs | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/uucore/src/lib/features/format/num_format.rs b/src/uucore/src/lib/features/format/num_format.rs index 60a3a404a..325da3ce6 100644 --- a/src/uucore/src/lib/features/format/num_format.rs +++ b/src/uucore/src/lib/features/format/num_format.rs @@ -141,7 +141,17 @@ impl Formatter for UnsignedInt { let mut s = match self.variant { UnsignedIntVariant::Decimal => format!("{x}"), UnsignedIntVariant::Octal(Prefix::No) => format!("{x:o}"), - UnsignedIntVariant::Octal(Prefix::Yes) => format!("{x:#o}"), + UnsignedIntVariant::Octal(Prefix::Yes) => { + // 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!("0{x:o}") + } else { + format!("{x:o}") + } + } UnsignedIntVariant::Hexadecimal(Case::Lowercase, Prefix::No) => { format!("{x:x}") } @@ -487,6 +497,27 @@ fn strip_fractional_zeroes_and_dot(s: &mut String) { mod test { use crate::format::num_format::{Case, ForceDecimal}; + #[test] + fn unsigned_octal() { + use super::{Formatter, NumberAlignment, Prefix, UnsignedInt, UnsignedIntVariant}; + let f = |x| { + let mut s = Vec::new(); + UnsignedInt { + variant: UnsignedIntVariant::Octal(Prefix::Yes), + width: 0, + precision: 0, + alignment: NumberAlignment::Left, + } + .fmt(&mut s, x) + .unwrap(); + String::from_utf8(s).unwrap() + }; + + assert_eq!(f(0), "0"); + assert_eq!(f(5), "05"); + assert_eq!(f(8), "010"); + } + #[test] fn decimal_float() { use super::format_float_decimal;