Merge branch 'printf-float-alternate-fix' into 'master'
printf: fix '%#.0e' to always print the radix character See merge request redox-os/relibc!1177
This commit is contained in:
@@ -444,9 +444,23 @@ fn pad<W: Write>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn float_string(float: c_double, precision: usize, trim: bool) -> String {
|
||||
fn float_string(float: c_double, precision: usize, trim: bool, alternate: bool) -> String {
|
||||
// The Rust format! macro doesn't keep the dot on precision = 0 and alternate = true,
|
||||
// so we have to perform a fix-up
|
||||
//
|
||||
// POSIX.1-2024 says "... if the precision is zero and no '#' flag is present,
|
||||
// no radix character shall appear."
|
||||
//
|
||||
// This case is covered here.
|
||||
let mut string = format!("{:.p$}", float, p = precision);
|
||||
if trim && string.contains('.') {
|
||||
//
|
||||
// Additionally, it says "For a, A, e, E, f, F, g, and G conversion specifiers,
|
||||
// the result shall always contain a radix character, even if no digits follow
|
||||
// the radix character."
|
||||
//
|
||||
if alternate && precision == 0 {
|
||||
string.push('.');
|
||||
} else if trim && string.contains('.') {
|
||||
let truncate = {
|
||||
let slice = string.trim_end_matches('0');
|
||||
let mut truncate = slice.len();
|
||||
@@ -477,6 +491,7 @@ fn fmt_float_exp<W: Write>(
|
||||
w: &mut W,
|
||||
exp_fmt: char,
|
||||
trim: bool,
|
||||
alternate: bool,
|
||||
precision: usize,
|
||||
float: c_double,
|
||||
exp: isize,
|
||||
@@ -491,7 +506,7 @@ fn fmt_float_exp<W: Write>(
|
||||
exp_len += 1;
|
||||
}
|
||||
|
||||
let string = float_string(float, precision, trim);
|
||||
let string = float_string(float, precision, trim, alternate);
|
||||
let len = string.len() + 2 + 2.max(exp_len);
|
||||
|
||||
pad(w, !left, b' ', len..pad_space)?;
|
||||
@@ -512,13 +527,14 @@ fn fmt_float_exp<W: Write>(
|
||||
fn fmt_float_normal<W: Write>(
|
||||
w: &mut W,
|
||||
trim: bool,
|
||||
alternate: bool,
|
||||
precision: usize,
|
||||
float: c_double,
|
||||
left: bool,
|
||||
pad_space: usize,
|
||||
pad_zero: usize,
|
||||
) -> io::Result<usize> {
|
||||
let string = float_string(float, precision, trim);
|
||||
let string = float_string(float, precision, trim, alternate);
|
||||
|
||||
pad(w, !left, b' ', string.len()..pad_space)?;
|
||||
let bytes = if string.starts_with('-') {
|
||||
@@ -968,7 +984,7 @@ pub(crate) unsafe fn inner_printf<T: c_str::Kind>(
|
||||
let precision = precision.unwrap_or(6);
|
||||
|
||||
fmt_float_exp(
|
||||
w, fmt, false, precision, float, exp, left, pad_space, pad_zero,
|
||||
w, fmt, false, alternate, precision, float, exp, left, pad_space, pad_zero,
|
||||
)?;
|
||||
} else {
|
||||
fmt_float_nonfinite(w, float, fmtcase.unwrap(), left, pad_space, pad_zero)?;
|
||||
@@ -985,7 +1001,9 @@ pub(crate) unsafe fn inner_printf<T: c_str::Kind>(
|
||||
if float.is_finite() {
|
||||
let precision = precision.unwrap_or(6);
|
||||
|
||||
fmt_float_normal(w, false, precision, float, left, pad_space, pad_zero)?;
|
||||
fmt_float_normal(
|
||||
w, false, alternate, precision, float, left, pad_space, pad_zero,
|
||||
)?;
|
||||
} else {
|
||||
fmt_float_nonfinite(w, float, fmtcase.unwrap(), left, pad_space, pad_zero)?;
|
||||
}
|
||||
@@ -1010,7 +1028,8 @@ pub(crate) unsafe fn inner_printf<T: c_str::Kind>(
|
||||
// because that's how x/floor(log10(x)) works
|
||||
let precision = precision.saturating_sub(1);
|
||||
fmt_float_exp(
|
||||
w, exp_fmt, !alternate, precision, log, exp, left, pad_space, pad_zero,
|
||||
w, exp_fmt, !alternate, alternate, precision, log, exp, left,
|
||||
pad_space, pad_zero,
|
||||
)?;
|
||||
} else {
|
||||
// Length of integral part will be the exponent of
|
||||
@@ -1020,7 +1039,7 @@ pub(crate) unsafe fn inner_printf<T: c_str::Kind>(
|
||||
let len = 1 + cmp::max(0, exp) as usize;
|
||||
let precision = precision.saturating_sub(len);
|
||||
fmt_float_normal(
|
||||
w, !alternate, precision, float, left, pad_space, pad_zero,
|
||||
w, !alternate, alternate, precision, float, left, pad_space, pad_zero,
|
||||
)?;
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user