diff --git a/src/uu/cat/src/cat.rs b/src/uu/cat/src/cat.rs index 8aaecb8c1..af55442ca 100644 --- a/src/uu/cat/src/cat.rs +++ b/src/uu/cat/src/cat.rs @@ -463,7 +463,6 @@ fn write_fast(handle: &mut InputHandle) -> CatResult<()> { /// Outputs file contents to stdout in a line-by-line fashion, /// propagating any errors that might occur. -#[allow(clippy::cognitive_complexity)] fn write_lines( handle: &mut InputHandle, options: &OutputOptions, @@ -482,22 +481,7 @@ fn write_lines( while pos < n { // skip empty line_number enumerating them if needed if in_buf[pos] == b'\n' { - // \r followed by \n is printed as ^M when show_ends is enabled, so that \r\n prints as ^M$ - if state.skipped_carriage_return && options.show_ends { - writer.write_all(b"^M")?; - state.skipped_carriage_return = false; - } - if !state.at_line_start || !options.squeeze_blank || !state.one_blank_kept { - state.one_blank_kept = true; - if state.at_line_start && options.number == NumberingMode::All { - write!(writer, "{0:6}\t", state.line_number)?; - state.line_number += 1; - } - writer.write_all(options.end_of_line().as_bytes())?; - if handle.is_interactive { - writer.flush()?; - } - } + write_new_line(&mut writer, options, state, handle.is_interactive)?; state.at_line_start = true; pos += 1; continue; @@ -514,13 +498,8 @@ fn write_lines( } // print to end of line or end of buffer - let offset = if options.show_nonprint { - write_nonprint_to_end(&in_buf[pos..], &mut writer, options.tab().as_bytes()) - } else if options.show_tabs { - write_tab_to_end(&in_buf[pos..], &mut writer) - } else { - write_to_end(&in_buf[pos..], &mut writer) - }; + let offset = write_end(&mut writer, &in_buf[pos..], options); + // end of buffer? if offset + pos == in_buf.len() { state.at_line_start = false; @@ -531,10 +510,11 @@ fn write_lines( } else { assert_eq!(in_buf[pos + offset], b'\n'); // print suitable end of line - writer.write_all(options.end_of_line().as_bytes())?; - if handle.is_interactive { - writer.flush()?; - } + write_end_of_line( + &mut writer, + options.end_of_line().as_bytes(), + handle.is_interactive, + )?; state.at_line_start = true; } pos += offset + 1; @@ -544,6 +524,41 @@ fn write_lines( Ok(()) } +// \r followed by \n is printed as ^M when show_ends is enabled, so that \r\n prints as ^M$ +fn write_new_line( + writer: &mut W, + options: &OutputOptions, + state: &mut OutputState, + is_interactive: bool, +) -> CatResult<()> { + if state.skipped_carriage_return && options.show_ends { + writer.write_all(b"^M")?; + state.skipped_carriage_return = false; + } + if !state.at_line_start || !options.squeeze_blank || !state.one_blank_kept { + state.one_blank_kept = true; + if state.at_line_start && options.number == NumberingMode::All { + write!(writer, "{0:6}\t", state.line_number)?; + state.line_number += 1; + } + writer.write_all(options.end_of_line().as_bytes())?; + if is_interactive { + writer.flush()?; + } + } + Ok(()) +} + +fn write_end(writer: &mut W, in_buf: &[u8], options: &OutputOptions) -> usize { + if options.show_nonprint { + write_nonprint_to_end(in_buf, writer, options.tab().as_bytes()) + } else if options.show_tabs { + write_tab_to_end(in_buf, writer) + } else { + write_to_end(in_buf, writer) + } +} + // write***_to_end methods // Write all symbols till \n or \r or end of buffer is reached // We need to stop at \r because it may be written as ^M depending on the byte after and settings; @@ -610,6 +625,18 @@ fn write_nonprint_to_end(in_buf: &[u8], writer: &mut W, tab: &[u8]) -> count } +fn write_end_of_line( + writer: &mut W, + end_of_line: &[u8], + is_interactive: bool, +) -> CatResult<()> { + writer.write_all(end_of_line)?; + if is_interactive { + writer.flush()?; + } + Ok(()) +} + #[cfg(test)] mod tests { use std::io::{stdout, BufWriter};