mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
printf: negative asterisk param changes alignement
This commit is contained in:
parent
3891ee1159
commit
707e346b84
2 changed files with 55 additions and 4 deletions
|
@ -314,15 +314,17 @@ impl Spec {
|
|||
) -> Result<(), FormatError> {
|
||||
match self {
|
||||
Self::Char { width, align_left } => {
|
||||
let width = resolve_asterisk(*width, &mut args)?.unwrap_or(0);
|
||||
write_padded(writer, &[args.get_char()], width, *align_left)
|
||||
let (width, neg_width) =
|
||||
resolve_asterisk_maybe_negative(*width, &mut args)?.unwrap_or_default();
|
||||
write_padded(writer, &[args.get_char()], width, *align_left || neg_width)
|
||||
}
|
||||
Self::String {
|
||||
width,
|
||||
align_left,
|
||||
precision,
|
||||
} => {
|
||||
let width = resolve_asterisk(*width, &mut args)?.unwrap_or(0);
|
||||
let (width, neg_width) =
|
||||
resolve_asterisk_maybe_negative(*width, &mut args)?.unwrap_or_default();
|
||||
|
||||
// GNU does do this truncation on a byte level, see for instance:
|
||||
// printf "%.1s" 🙃
|
||||
|
@ -336,7 +338,12 @@ impl Spec {
|
|||
Some(p) if p < s.len() => &s[..p],
|
||||
_ => s,
|
||||
};
|
||||
write_padded(writer, truncated.as_bytes(), width, *align_left)
|
||||
write_padded(
|
||||
writer,
|
||||
truncated.as_bytes(),
|
||||
width,
|
||||
*align_left || neg_width,
|
||||
)
|
||||
}
|
||||
Self::EscapedString => {
|
||||
let s = args.get_str();
|
||||
|
@ -458,6 +465,24 @@ fn resolve_asterisk<'a>(
|
|||
})
|
||||
}
|
||||
|
||||
fn resolve_asterisk_maybe_negative<'a>(
|
||||
option: Option<CanAsterisk<usize>>,
|
||||
mut args: impl ArgumentIter<'a>,
|
||||
) -> Result<Option<(usize, bool)>, FormatError> {
|
||||
Ok(match option {
|
||||
None => None,
|
||||
Some(CanAsterisk::Asterisk) => {
|
||||
let nb = args.get_i64();
|
||||
if nb < 0 {
|
||||
Some((usize::try_from(-(nb as isize)).ok().unwrap_or(0), true))
|
||||
} else {
|
||||
Some((usize::try_from(nb).ok().unwrap_or(0), false))
|
||||
}
|
||||
}
|
||||
Some(CanAsterisk::Fixed(w)) => Some((w, false)),
|
||||
})
|
||||
}
|
||||
|
||||
fn write_padded(
|
||||
mut writer: impl Write,
|
||||
text: &[u8],
|
||||
|
|
|
@ -495,6 +495,32 @@ fn sub_any_asterisk_hex_arg() {
|
|||
.stdout_only("0123456789");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_any_asterisk_negative_first_param() {
|
||||
new_ucmd!()
|
||||
.args(&["a(%*s)b", "-5", "xyz"])
|
||||
.succeeds()
|
||||
.stdout_only("a(xyz )b"); // Would be 'a( xyz)b' if -5 was 5
|
||||
|
||||
// Negative octal
|
||||
new_ucmd!()
|
||||
.args(&["a(%*s)b", "-010", "xyz"])
|
||||
.succeeds()
|
||||
.stdout_only("a(xyz )b");
|
||||
|
||||
// Negative hexadecimal
|
||||
new_ucmd!()
|
||||
.args(&["a(%*s)b", "-0x10", "xyz"])
|
||||
.succeeds()
|
||||
.stdout_only("a(xyz )b");
|
||||
|
||||
// Should also work on %c
|
||||
new_ucmd!()
|
||||
.args(&["a(%*c)b", "-5", "x"])
|
||||
.succeeds()
|
||||
.stdout_only("a(x )b"); // Would be 'a( x)b' if -5 was 5
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sub_any_specifiers_no_params() {
|
||||
new_ucmd!()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue