mirror of
https://github.com/uutils/coreutils
synced 2024-12-14 15:22:38 +00:00
printf: support precision for integers
This commit is contained in:
parent
f83e0d1b04
commit
f3da0817a5
2 changed files with 38 additions and 4 deletions
|
@ -63,6 +63,7 @@ pub enum NumberAlignment {
|
|||
|
||||
pub struct SignedInt {
|
||||
pub width: usize,
|
||||
pub precision: usize,
|
||||
pub positive_sign: PositiveSign,
|
||||
pub alignment: NumberAlignment,
|
||||
}
|
||||
|
@ -79,16 +80,19 @@ impl Formatter for SignedInt {
|
|||
}?;
|
||||
}
|
||||
|
||||
let s = format!("{:0width$}", x, width = self.precision);
|
||||
|
||||
match self.alignment {
|
||||
NumberAlignment::Left => write!(writer, "{x:<width$}", width = self.width),
|
||||
NumberAlignment::RightSpace => write!(writer, "{x:>width$}", width = self.width),
|
||||
NumberAlignment::RightZero => write!(writer, "{x:0>width$}", width = self.width),
|
||||
NumberAlignment::Left => write!(writer, "{s:<width$}", width = self.width),
|
||||
NumberAlignment::RightSpace => write!(writer, "{s:>width$}", width = self.width),
|
||||
NumberAlignment::RightZero => write!(writer, "{s:0>width$}", width = self.width),
|
||||
}
|
||||
}
|
||||
|
||||
fn try_from_spec(s: Spec) -> Result<Self, FormatError> {
|
||||
let Spec::SignedInt {
|
||||
width,
|
||||
precision,
|
||||
positive_sign,
|
||||
alignment,
|
||||
} = s
|
||||
|
@ -102,8 +106,15 @@ impl Formatter for SignedInt {
|
|||
Some(CanAsterisk::Asterisk) => return Err(FormatError::SpecError),
|
||||
};
|
||||
|
||||
let precision = match precision {
|
||||
Some(CanAsterisk::Fixed(x)) => x,
|
||||
None => 0,
|
||||
Some(CanAsterisk::Asterisk) => return Err(FormatError::SpecError),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
width,
|
||||
precision,
|
||||
positive_sign,
|
||||
alignment,
|
||||
})
|
||||
|
@ -113,6 +124,7 @@ impl Formatter for SignedInt {
|
|||
pub struct UnsignedInt {
|
||||
pub variant: UnsignedIntVariant,
|
||||
pub width: usize,
|
||||
pub precision: usize,
|
||||
pub alignment: NumberAlignment,
|
||||
}
|
||||
|
||||
|
@ -120,7 +132,7 @@ impl Formatter for UnsignedInt {
|
|||
type Input = u64;
|
||||
|
||||
fn fmt(&self, mut writer: impl Write, x: Self::Input) -> std::io::Result<()> {
|
||||
let s = match self.variant {
|
||||
let mut s = match self.variant {
|
||||
UnsignedIntVariant::Decimal => format!("{x}"),
|
||||
UnsignedIntVariant::Octal(Prefix::No) => format!("{x:o}"),
|
||||
UnsignedIntVariant::Octal(Prefix::Yes) => format!("{x:#o}"),
|
||||
|
@ -138,6 +150,10 @@ impl Formatter for UnsignedInt {
|
|||
}
|
||||
};
|
||||
|
||||
if self.precision > s.len() {
|
||||
s = format!("{:0width$}", s, width = self.precision)
|
||||
}
|
||||
|
||||
match self.alignment {
|
||||
NumberAlignment::Left => write!(writer, "{s:<width$}", width = self.width),
|
||||
NumberAlignment::RightSpace => write!(writer, "{s:>width$}", width = self.width),
|
||||
|
@ -149,6 +165,7 @@ impl Formatter for UnsignedInt {
|
|||
let Spec::UnsignedInt {
|
||||
variant,
|
||||
width,
|
||||
precision,
|
||||
alignment,
|
||||
} = s
|
||||
else {
|
||||
|
@ -161,8 +178,15 @@ impl Formatter for UnsignedInt {
|
|||
Some(CanAsterisk::Asterisk) => return Err(FormatError::SpecError),
|
||||
};
|
||||
|
||||
let precision = match precision {
|
||||
Some(CanAsterisk::Fixed(x)) => x,
|
||||
None => 0,
|
||||
Some(CanAsterisk::Asterisk) => return Err(FormatError::SpecError),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
width,
|
||||
precision,
|
||||
variant,
|
||||
alignment,
|
||||
})
|
||||
|
|
|
@ -22,12 +22,14 @@ pub enum Spec {
|
|||
},
|
||||
SignedInt {
|
||||
width: Option<CanAsterisk<usize>>,
|
||||
precision: Option<CanAsterisk<usize>>,
|
||||
positive_sign: PositiveSign,
|
||||
alignment: NumberAlignment,
|
||||
},
|
||||
UnsignedInt {
|
||||
variant: UnsignedIntVariant,
|
||||
width: Option<CanAsterisk<usize>>,
|
||||
precision: Option<CanAsterisk<usize>>,
|
||||
alignment: NumberAlignment,
|
||||
},
|
||||
Float {
|
||||
|
@ -167,6 +169,7 @@ impl Spec {
|
|||
},
|
||||
b'd' | b'i' => Spec::SignedInt {
|
||||
width,
|
||||
precision,
|
||||
alignment: match (minus, zero) {
|
||||
(true, _) => NumberAlignment::Left,
|
||||
(false, true) => NumberAlignment::RightZero,
|
||||
|
@ -197,6 +200,7 @@ impl Spec {
|
|||
};
|
||||
Spec::UnsignedInt {
|
||||
variant,
|
||||
precision,
|
||||
width,
|
||||
alignment,
|
||||
}
|
||||
|
@ -282,10 +286,12 @@ impl Spec {
|
|||
}
|
||||
&Spec::SignedInt {
|
||||
width,
|
||||
precision,
|
||||
positive_sign,
|
||||
alignment,
|
||||
} => {
|
||||
let width = resolve_asterisk(width, &mut args)?.unwrap_or(0);
|
||||
let precision = resolve_asterisk(precision, &mut args)?.unwrap_or(0);
|
||||
|
||||
let arg = next_arg(&mut args)?;
|
||||
let Some(i) = arg.get_i64() else {
|
||||
|
@ -294,6 +300,7 @@ impl Spec {
|
|||
|
||||
num_format::SignedInt {
|
||||
width,
|
||||
precision,
|
||||
positive_sign,
|
||||
alignment,
|
||||
}
|
||||
|
@ -303,9 +310,11 @@ impl Spec {
|
|||
&Spec::UnsignedInt {
|
||||
variant,
|
||||
width,
|
||||
precision,
|
||||
alignment,
|
||||
} => {
|
||||
let width = resolve_asterisk(width, &mut args)?.unwrap_or(0);
|
||||
let precision = resolve_asterisk(precision, &mut args)?.unwrap_or(0);
|
||||
|
||||
let arg = next_arg(args)?;
|
||||
let Some(i) = arg.get_u64() else {
|
||||
|
@ -314,6 +323,7 @@ impl Spec {
|
|||
|
||||
num_format::UnsignedInt {
|
||||
variant,
|
||||
precision,
|
||||
width,
|
||||
alignment,
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue