77
88use clap:: { Arg , ArgAction , Command } ;
99use std:: fs:: File ;
10- use std:: io:: { BufRead , BufReader , Read , Write , stdin, stdout} ;
10+ use std:: io:: { BufRead , BufReader , BufWriter , Read , Write , stdin, stdout} ;
1111use std:: path:: Path ;
1212use uucore:: display:: Quotable ;
1313use uucore:: error:: { FromIo , UResult , USimpleError } ;
@@ -108,6 +108,8 @@ fn handle_obsolete(args: &[String]) -> (Vec<String>, Option<String>) {
108108}
109109
110110fn fold ( filenames : & [ String ] , bytes : bool , spaces : bool , width : usize ) -> UResult < ( ) > {
111+ let mut output = BufWriter :: new ( stdout ( ) ) ;
112+
111113 for filename in filenames {
112114 let filename: & str = filename;
113115 let mut stdin_buf;
@@ -121,11 +123,15 @@ fn fold(filenames: &[String], bytes: bool, spaces: bool, width: usize) -> UResul
121123 } ) ;
122124
123125 if bytes {
124- fold_file_bytewise ( buffer, spaces, width) ?;
126+ fold_file_bytewise ( buffer, spaces, width, & mut output ) ?;
125127 } else {
126- fold_file ( buffer, spaces, width) ?;
128+ fold_file ( buffer, spaces, width, & mut output ) ?;
127129 }
128130 }
131+
132+ output
133+ . flush ( )
134+ . map_err_context ( || translate ! ( "fold-error-failed-to-write" ) ) ?;
129135 Ok ( ( ) )
130136}
131137
@@ -137,7 +143,12 @@ fn fold(filenames: &[String], bytes: bool, spaces: bool, width: usize) -> UResul
137143/// to all other characters in the stream.
138144///
139145/// If `spaces` is `true`, attempt to break lines at whitespace boundaries.
140- fn fold_file_bytewise < T : Read > ( mut file : BufReader < T > , spaces : bool , width : usize ) -> UResult < ( ) > {
146+ fn fold_file_bytewise < T : Read , W : Write > (
147+ mut file : BufReader < T > ,
148+ spaces : bool ,
149+ width : usize ,
150+ output : & mut W ,
151+ ) -> UResult < ( ) > {
141152 let mut line = Vec :: new ( ) ;
142153
143154 loop {
@@ -150,7 +161,7 @@ fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usiz
150161 }
151162
152163 if line == [ NL ] {
153- println ! ( ) ;
164+ output . write_all ( & [ NL ] ) ? ;
154165 line. truncate ( 0 ) ;
155166 continue ;
156167 }
@@ -189,10 +200,10 @@ fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usiz
189200 let at_eol = i >= len;
190201
191202 if at_eol {
192- stdout ( ) . write_all ( slice) ?;
203+ output . write_all ( slice) ?;
193204 } else {
194- stdout ( ) . write_all ( slice) ?;
195- stdout ( ) . write_all ( & [ NL ] ) ?;
205+ output . write_all ( slice) ?;
206+ output . write_all ( & [ NL ] ) ?;
196207 }
197208 }
198209
@@ -211,7 +222,12 @@ fn fold_file_bytewise<T: Read>(mut file: BufReader<T>, spaces: bool, width: usiz
211222/// If `spaces` is `true`, attempt to break lines at whitespace boundaries.
212223#[ allow( unused_assignments) ]
213224#[ allow( clippy:: cognitive_complexity) ]
214- fn fold_file < T : Read > ( mut file : BufReader < T > , spaces : bool , width : usize ) -> UResult < ( ) > {
225+ fn fold_file < T : Read , W : Write > (
226+ mut file : BufReader < T > ,
227+ spaces : bool ,
228+ width : usize ,
229+ writer : & mut W ,
230+ ) -> UResult < ( ) > {
215231 let mut line = Vec :: new ( ) ;
216232 let mut output = Vec :: new ( ) ;
217233 let mut col_count = 0 ;
@@ -229,8 +245,8 @@ fn fold_file<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) -> URe
229245 None => output. len( ) ,
230246 } ;
231247
232- stdout ( ) . write_all( & output[ ..consume] ) ?;
233- stdout ( ) . write_all( & [ NL ] ) ?;
248+ writer . write_all( & output[ ..consume] ) ?;
249+ writer . write_all( & [ NL ] ) ?;
234250 output. drain( ..consume) ;
235251
236252 // we know there are no tabs left in output, so each char counts
@@ -289,7 +305,7 @@ fn fold_file<T: Read>(mut file: BufReader<T>, spaces: bool, width: usize) -> URe
289305 }
290306
291307 if !output. is_empty ( ) {
292- stdout ( ) . write_all ( & output) ?;
308+ writer . write_all ( & output) ?;
293309 output. truncate ( 0 ) ;
294310 }
295311
0 commit comments