builtins/printf: avoid string copies by formatting directly to buffer

Closes #9765.
This commit is contained in:
Xiretza 2023-04-29 18:53:33 +00:00 committed by Mahmoud Al-Qudsi
parent 4771f25102
commit afe2e9d8db

View File

@ -261,20 +261,19 @@ impl<'a> builtin_printf_state_t<'a> {
argument: &wstr, argument: &wstr,
) { ) {
/// Printf macro helper which provides our locale. /// Printf macro helper which provides our locale.
macro_rules! sprintf_loc { macro_rules! append_output_fmt {
( (
$fmt:expr, // format string of type &wstr $fmt:expr, // format string of type &wstr
$($arg:expr),* // arguments $($arg:expr),* // arguments
) => { ) => {
{ // Don't output if we're done.
let mut target = WString::new(); if !self.early_exit {
sprintf_locale( sprintf_locale(
&mut target, &mut self.buff,
$fmt, $fmt,
&self.locale, &self.locale,
&[$($arg.to_arg()),*] &[$($arg.to_arg()),*]
); )
target
} }
} }
} }
@ -307,15 +306,15 @@ impl<'a> builtin_printf_state_t<'a> {
let arg: i64 = string_to_scalar_type(argument, self); let arg: i64 = string_to_scalar_type(argument, self);
if !have_field_width { if !have_field_width {
if !have_precision { if !have_precision {
self.append_output_str(sprintf_loc!(fmt, arg)); append_output_fmt!(fmt, arg);
} else { } else {
self.append_output_str(sprintf_loc!(fmt, precision, arg)); append_output_fmt!(fmt, precision, arg);
} }
} else { } else {
if !have_precision { if !have_precision {
self.append_output_str(sprintf_loc!(fmt, field_width, arg)); append_output_fmt!(fmt, field_width, arg);
} else { } else {
self.append_output_str(sprintf_loc!(fmt, field_width, precision, arg)); append_output_fmt!(fmt, field_width, precision, arg);
} }
} }
} }
@ -323,15 +322,15 @@ impl<'a> builtin_printf_state_t<'a> {
let arg: u64 = string_to_scalar_type(argument, self); let arg: u64 = string_to_scalar_type(argument, self);
if !have_field_width { if !have_field_width {
if !have_precision { if !have_precision {
self.append_output_str(sprintf_loc!(fmt, arg)); append_output_fmt!(fmt, arg);
} else { } else {
self.append_output_str(sprintf_loc!(fmt, precision, arg)); append_output_fmt!(fmt, precision, arg);
} }
} else { } else {
if !have_precision { if !have_precision {
self.append_output_str(sprintf_loc!(fmt, field_width, arg)); append_output_fmt!(fmt, field_width, arg);
} else { } else {
self.append_output_str(sprintf_loc!(fmt, field_width, precision, arg)); append_output_fmt!(fmt, field_width, precision, arg);
} }
} }
} }
@ -340,39 +339,39 @@ impl<'a> builtin_printf_state_t<'a> {
let arg: f64 = string_to_scalar_type(argument, self); let arg: f64 = string_to_scalar_type(argument, self);
if !have_field_width { if !have_field_width {
if !have_precision { if !have_precision {
self.append_output_str(sprintf_loc!(fmt, arg)); append_output_fmt!(fmt, arg);
} else { } else {
self.append_output_str(sprintf_loc!(fmt, precision, arg)); append_output_fmt!(fmt, precision, arg);
} }
} else { } else {
if !have_precision { if !have_precision {
self.append_output_str(sprintf_loc!(fmt, field_width, arg)); append_output_fmt!(fmt, field_width, arg);
} else { } else {
self.append_output_str(sprintf_loc!(fmt, field_width, precision, arg)); append_output_fmt!(fmt, field_width, precision, arg);
} }
} }
} }
'c' => { 'c' => {
if !have_field_width { if !have_field_width {
self.append_output_str(sprintf_loc!(fmt, argument.char_at(0))); append_output_fmt!(fmt, argument.char_at(0));
} else { } else {
self.append_output_str(sprintf_loc!(fmt, field_width, argument.char_at(0))); append_output_fmt!(fmt, field_width, argument.char_at(0));
} }
} }
's' => { 's' => {
if !have_field_width { if !have_field_width {
if !have_precision { if !have_precision {
self.append_output_str(sprintf_loc!(fmt, argument)); append_output_fmt!(fmt, argument);
} else { } else {
self.append_output_str(sprintf_loc!(fmt, precision, argument)); append_output_fmt!(fmt, precision, argument);
} }
} else { } else {
if !have_precision { if !have_precision {
self.append_output_str(sprintf_loc!(fmt, field_width, argument)); append_output_fmt!(fmt, field_width, argument);
} else { } else {
self.append_output_str(sprintf_loc!(fmt, field_width, precision, argument)); append_output_fmt!(fmt, field_width, precision, argument);
} }
} }
} }
@ -763,15 +762,6 @@ impl<'a> builtin_printf_state_t<'a> {
self.buff.push(c); self.buff.push(c);
} }
fn append_output_str<Str: AsRef<wstr>>(&mut self, s: Str) {
// Don't output if we're done.
if self.early_exit {
return;
}
self.buff.push_utfstr(&s);
}
} }
/// The printf builtin. /// The printf builtin.