From afe2e9d8db6dd7f99a794259aadbdbedf1e578ef Mon Sep 17 00:00:00 2001 From: Xiretza Date: Sat, 29 Apr 2023 18:53:33 +0000 Subject: [PATCH] builtins/printf: avoid string copies by formatting directly to buffer Closes #9765. --- fish-rust/src/builtins/printf.rs | 56 +++++++++++++------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/fish-rust/src/builtins/printf.rs b/fish-rust/src/builtins/printf.rs index 11c7e07bc..c76efc976 100644 --- a/fish-rust/src/builtins/printf.rs +++ b/fish-rust/src/builtins/printf.rs @@ -261,20 +261,19 @@ fn print_direc( argument: &wstr, ) { /// Printf macro helper which provides our locale. - macro_rules! sprintf_loc { + macro_rules! append_output_fmt { ( $fmt:expr, // format string of type &wstr $($arg:expr),* // arguments ) => { - { - let mut target = WString::new(); + // Don't output if we're done. + if !self.early_exit { sprintf_locale( - &mut target, + &mut self.buff, $fmt, &self.locale, &[$($arg.to_arg()),*] - ); - target + ) } } } @@ -307,15 +306,15 @@ macro_rules! sprintf_loc { let arg: i64 = string_to_scalar_type(argument, self); if !have_field_width { if !have_precision { - self.append_output_str(sprintf_loc!(fmt, arg)); + append_output_fmt!(fmt, arg); } else { - self.append_output_str(sprintf_loc!(fmt, precision, arg)); + append_output_fmt!(fmt, precision, arg); } } else { if !have_precision { - self.append_output_str(sprintf_loc!(fmt, field_width, arg)); + append_output_fmt!(fmt, field_width, arg); } else { - self.append_output_str(sprintf_loc!(fmt, field_width, precision, arg)); + append_output_fmt!(fmt, field_width, precision, arg); } } } @@ -323,15 +322,15 @@ macro_rules! sprintf_loc { let arg: u64 = string_to_scalar_type(argument, self); if !have_field_width { if !have_precision { - self.append_output_str(sprintf_loc!(fmt, arg)); + append_output_fmt!(fmt, arg); } else { - self.append_output_str(sprintf_loc!(fmt, precision, arg)); + append_output_fmt!(fmt, precision, arg); } } else { if !have_precision { - self.append_output_str(sprintf_loc!(fmt, field_width, arg)); + append_output_fmt!(fmt, field_width, arg); } else { - self.append_output_str(sprintf_loc!(fmt, field_width, precision, arg)); + append_output_fmt!(fmt, field_width, precision, arg); } } } @@ -340,39 +339,39 @@ macro_rules! sprintf_loc { let arg: f64 = string_to_scalar_type(argument, self); if !have_field_width { if !have_precision { - self.append_output_str(sprintf_loc!(fmt, arg)); + append_output_fmt!(fmt, arg); } else { - self.append_output_str(sprintf_loc!(fmt, precision, arg)); + append_output_fmt!(fmt, precision, arg); } } else { if !have_precision { - self.append_output_str(sprintf_loc!(fmt, field_width, arg)); + append_output_fmt!(fmt, field_width, arg); } else { - self.append_output_str(sprintf_loc!(fmt, field_width, precision, arg)); + append_output_fmt!(fmt, field_width, precision, arg); } } } 'c' => { if !have_field_width { - self.append_output_str(sprintf_loc!(fmt, argument.char_at(0))); + append_output_fmt!(fmt, argument.char_at(0)); } 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' => { if !have_field_width { if !have_precision { - self.append_output_str(sprintf_loc!(fmt, argument)); + append_output_fmt!(fmt, argument); } else { - self.append_output_str(sprintf_loc!(fmt, precision, argument)); + append_output_fmt!(fmt, precision, argument); } } else { if !have_precision { - self.append_output_str(sprintf_loc!(fmt, field_width, argument)); + append_output_fmt!(fmt, field_width, argument); } else { - self.append_output_str(sprintf_loc!(fmt, field_width, precision, argument)); + append_output_fmt!(fmt, field_width, precision, argument); } } } @@ -763,15 +762,6 @@ fn append_output(&mut self, c: char) { self.buff.push(c); } - - fn append_output_str>(&mut self, s: Str) { - // Don't output if we're done. - if self.early_exit { - return; - } - - self.buff.push_utfstr(&s); - } } /// The printf builtin.