From 42cde767d2dad9633c1f8422b738b1467a6400ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dorian=20P=C3=A9ron?= Date: Thu, 29 Feb 2024 00:45:35 +0100 Subject: [PATCH] printf: Change get_char and write_padded to handle bytes instead of chars --- .../src/lib/features/format/argument.rs | 12 +++++------ src/uucore/src/lib/features/format/spec.rs | 21 ++++++++++--------- tests/by-util/test_printf.rs | 18 ++++++---------- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/src/uucore/src/lib/features/format/argument.rs b/src/uucore/src/lib/features/format/argument.rs index ef81fc353..758510498 100644 --- a/src/uucore/src/lib/features/format/argument.rs +++ b/src/uucore/src/lib/features/format/argument.rs @@ -31,7 +31,7 @@ pub enum FormatArgument { } pub trait ArgumentIter<'a>: Iterator { - fn get_char(&mut self) -> char; + fn get_char(&mut self) -> u8; fn get_i64(&mut self) -> i64; fn get_u64(&mut self) -> u64; fn get_f64(&mut self) -> f64; @@ -39,14 +39,14 @@ pub trait ArgumentIter<'a>: Iterator { } impl<'a, T: Iterator> ArgumentIter<'a> for T { - fn get_char(&mut self) -> char { + fn get_char(&mut self) -> u8 { let Some(next) = self.next() else { - return '\0'; + return b'\0'; }; match next { - FormatArgument::Char(c) => *c, - FormatArgument::Unparsed(s) => s.bytes().next().map_or('\0', char::from), - _ => '\0', + FormatArgument::Char(c) => *c as u8, + FormatArgument::Unparsed(s) => s.bytes().next().unwrap_or(b'\0'), + _ => b'\0', } } diff --git a/src/uucore/src/lib/features/format/spec.rs b/src/uucore/src/lib/features/format/spec.rs index 6d342f742..57ed5ad45 100644 --- a/src/uucore/src/lib/features/format/spec.rs +++ b/src/uucore/src/lib/features/format/spec.rs @@ -14,7 +14,7 @@ use super::{ }, parse_escape_only, ArgumentIter, FormatChar, FormatError, }; -use std::{fmt::Display, io::Write, ops::ControlFlow}; +use std::{io::Write, ops::ControlFlow}; /// A parsed specification for formatting a value /// @@ -312,7 +312,7 @@ impl Spec { match self { Self::Char { width, align_left } => { let width = resolve_asterisk(*width, &mut args)?.unwrap_or(0); - write_padded(writer, args.get_char(), width, false, *align_left) + write_padded(writer, &[args.get_char()], width, *align_left) } Self::String { width, @@ -333,7 +333,7 @@ impl Spec { Some(p) if p < s.len() => &s[..p], _ => s, }; - write_padded(writer, truncated, width, false, *align_left) + write_padded(writer, truncated.as_bytes(), width, *align_left) } Self::EscapedString => { let s = args.get_str(); @@ -445,16 +445,17 @@ fn resolve_asterisk<'a>( fn write_padded( mut writer: impl Write, - text: impl Display, + text: &[u8], width: usize, - pad_zero: bool, left: bool, ) -> Result<(), FormatError> { - match (left, pad_zero) { - (false, false) => write!(writer, "{text: >width$}"), - (false, true) => write!(writer, "{text:0>width$}"), - // 0 is ignored if we pad left. - (true, _) => write!(writer, "{text: padlen$}", "")?; + writer.write_all(text) } .map_err(FormatError::IoError) } diff --git a/tests/by-util/test_printf.rs b/tests/by-util/test_printf.rs index 531e527bc..38d7b10a6 100644 --- a/tests/by-util/test_printf.rs +++ b/tests/by-util/test_printf.rs @@ -743,12 +743,7 @@ fn pad_unsigned_three() { #[test] fn pad_char() { - for (format, expected) in [ - ("%3c", " X"), - ("%1c", "X"), - ("%-1c", "X"), - ("%-3c", "X "), - ] { + for (format, expected) in [("%3c", " X"), ("%1c", "X"), ("%-1c", "X"), ("%-3c", "X ")] { new_ucmd!() .args(&[format, "X"]) .succeeds() @@ -756,18 +751,17 @@ fn pad_char() { } } - #[test] fn pad_string() { for (format, expected) in [ - ("%8s", " bottle"), - ("%-8s", "bottle "), - ("%6s", "bottle"), - ("%-6s", "bottle"), + ("%8s", " bottle"), + ("%-8s", "bottle "), + ("%6s", "bottle"), + ("%-6s", "bottle"), ] { new_ucmd!() .args(&[format, "bottle"]) .succeeds() .stdout_only(expected); } -} \ No newline at end of file +}