mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
printf: Change get_char and write_padded to handle bytes instead of chars
This commit is contained in:
parent
5d74a6e002
commit
42cde767d2
3 changed files with 23 additions and 28 deletions
|
@ -31,7 +31,7 @@ pub enum FormatArgument {
|
|||
}
|
||||
|
||||
pub trait ArgumentIter<'a>: Iterator<Item = &'a FormatArgument> {
|
||||
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<Item = &'a FormatArgument> {
|
|||
}
|
||||
|
||||
impl<'a, T: Iterator<Item = &'a FormatArgument>> 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',
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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: <width$}"),
|
||||
let padlen = width.saturating_sub(text.len());
|
||||
if left {
|
||||
writer.write_all(text)?;
|
||||
write!(writer, "{: <padlen$}", "")
|
||||
} else {
|
||||
write!(writer, "{: >padlen$}", "")?;
|
||||
writer.write_all(text)
|
||||
}
|
||||
.map_err(FormatError::IoError)
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue