From b3d16cc0e18711ea8f8dbaaeb250f5bc18e80250 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 4 Oct 2025 09:41:44 +0200 Subject: [PATCH] fold: improve the performances - now same as GNU --- src/uu/fold/src/fold.rs | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index b439f20a9..bbaac56be 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -7,7 +7,7 @@ use clap::{Arg, ArgAction, Command}; use std::fs::File; -use std::io::{BufRead, BufReader, Read, Write, stdin, stdout}; +use std::io::{BufRead, BufReader, BufWriter, Read, Write, stdin, stdout}; use std::path::Path; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError}; @@ -108,6 +108,8 @@ fn handle_obsolete(args: &[String]) -> (Vec, Option) { } fn fold(filenames: &[String], bytes: bool, spaces: bool, width: usize) -> UResult<()> { + let mut output = BufWriter::new(stdout()); + for filename in filenames { let filename: &str = filename; let mut stdin_buf; @@ -121,11 +123,15 @@ fn fold(filenames: &[String], bytes: bool, spaces: bool, width: usize) -> UResul }); if bytes { - fold_file_bytewise(buffer, spaces, width)?; + fold_file_bytewise(buffer, spaces, width, &mut output)?; } else { - fold_file(buffer, spaces, width)?; + fold_file(buffer, spaces, width, &mut output)?; } } + + output + .flush() + .map_err_context(|| translate!("fold-error-failed-to-write"))?; Ok(()) } @@ -137,7 +143,12 @@ fn fold(filenames: &[String], bytes: bool, spaces: bool, width: usize) -> UResul /// to all other characters in the stream. /// /// If `spaces` is `true`, attempt to break lines at whitespace boundaries. -fn fold_file_bytewise(mut file: BufReader, spaces: bool, width: usize) -> UResult<()> { +fn fold_file_bytewise( + mut file: BufReader, + spaces: bool, + width: usize, + output: &mut W, +) -> UResult<()> { let mut line = Vec::new(); loop { @@ -150,7 +161,7 @@ fn fold_file_bytewise(mut file: BufReader, spaces: bool, width: usiz } if line == [NL] { - println!(); + output.write_all(&[NL])?; line.truncate(0); continue; } @@ -189,10 +200,10 @@ fn fold_file_bytewise(mut file: BufReader, spaces: bool, width: usiz let at_eol = i >= len; if at_eol { - stdout().write_all(slice)?; + output.write_all(slice)?; } else { - stdout().write_all(slice)?; - stdout().write_all(&[NL])?; + output.write_all(slice)?; + output.write_all(&[NL])?; } } @@ -211,7 +222,12 @@ fn fold_file_bytewise(mut file: BufReader, spaces: bool, width: usiz /// If `spaces` is `true`, attempt to break lines at whitespace boundaries. #[allow(unused_assignments)] #[allow(clippy::cognitive_complexity)] -fn fold_file(mut file: BufReader, spaces: bool, width: usize) -> UResult<()> { +fn fold_file( + mut file: BufReader, + spaces: bool, + width: usize, + writer: &mut W, +) -> UResult<()> { let mut line = Vec::new(); let mut output = Vec::new(); let mut col_count = 0; @@ -229,8 +245,8 @@ fn fold_file(mut file: BufReader, spaces: bool, width: usize) -> URe None => output.len(), }; - stdout().write_all(&output[..consume])?; - stdout().write_all(&[NL])?; + writer.write_all(&output[..consume])?; + writer.write_all(&[NL])?; output.drain(..consume); // we know there are no tabs left in output, so each char counts @@ -289,7 +305,7 @@ fn fold_file(mut file: BufReader, spaces: bool, width: usize) -> URe } if !output.is_empty() { - stdout().write_all(&output)?; + writer.write_all(&output)?; output.truncate(0); }