diff --git a/src/cat/cat.rs b/src/cat/cat.rs index 48587ffe3..41b0e7547 100644 --- a/src/cat/cat.rs +++ b/src/cat/cat.rs @@ -304,9 +304,10 @@ fn write_fast(files: Vec) -> CatResult<()> { fn write_lines(files: Vec, options: &OutputOptions) -> CatResult<()> { let mut line_counter: usize = 1; let mut error_count = 0; + let mut at_line_start = true; for file in files { - let written = write_file_lines(&file[..], options, line_counter); + let written = write_file_lines(&file[..], options, line_counter, &mut at_line_start); line_counter += match written { Ok(lines) => lines, Err(error) => { @@ -326,16 +327,13 @@ fn write_lines(files: Vec, options: &OutputOptions) -> CatResult<()> { /// Outputs file and returns result with the number of lines to stdout /// from `file`. If line numbering is enabled, then start output /// numbering at `line_number`. -/// -/// # Arguments -/// -/// * `files` - There is no short circuit when encountiner an error -/// reading a file in this vector -fn write_file_lines(file: &str, options: &OutputOptions, line_number: usize) -> CatResult { +fn write_file_lines(file: &str, + options: &OutputOptions, + line_number: usize, + at_line_start: &mut bool) -> CatResult { let mut handle = open(&file[..])?; let mut in_buf = [0; 1024 * 31]; let mut writer = BufWriter::with_capacity(1024 * 64, stdout()); - let mut at_line_start = true; let mut one_blank_kept = false; let mut lines = 0; @@ -349,9 +347,9 @@ fn write_file_lines(file: &str, options: &OutputOptions, line_number: usize) -> while pos < n { // skip empty line_number enumerating them if needed if in_buf[pos] == '\n' as u8 { - if !at_line_start || ! options.squeeze_blank || !one_blank_kept { + if !*at_line_start || ! options.squeeze_blank || !one_blank_kept { one_blank_kept = true; - if at_line_start && options.number == NumberingMode::NumberAll { + if *at_line_start && options.number == NumberingMode::NumberAll { write!(&mut writer, "{0:6}\t", line_number + lines)?; lines += 1; } @@ -360,12 +358,12 @@ fn write_file_lines(file: &str, options: &OutputOptions, line_number: usize) -> writer.flush().context(&file[..])?; } } - at_line_start = true; + *at_line_start = true; pos += 1; continue; } one_blank_kept = false; - if at_line_start && options.number != NumberingMode::NumberNone { + if *at_line_start && options.number != NumberingMode::NumberNone { write!(&mut writer, "{0:6}\t", line_number + lines)?; lines += 1; } @@ -380,7 +378,7 @@ fn write_file_lines(file: &str, options: &OutputOptions, line_number: usize) -> }; // end of buffer? if offset == 0 { - at_line_start = false; + *at_line_start = false; break; } // print suitable end of line @@ -388,7 +386,7 @@ fn write_file_lines(file: &str, options: &OutputOptions, line_number: usize) -> if handle.is_interactive { writer.flush()?; } - at_line_start = true; + *at_line_start = true; pos += offset; } } diff --git a/tests/fixtures/cat/nonewline.txt b/tests/fixtures/cat/nonewline.txt new file mode 100644 index 000000000..320b95eaf --- /dev/null +++ b/tests/fixtures/cat/nonewline.txt @@ -0,0 +1 @@ +text without a trailing newline \ No newline at end of file diff --git a/tests/test_cat.rs b/tests/test_cat.rs index c476bb2c0..027bfddd1 100644 --- a/tests/test_cat.rs +++ b/tests/test_cat.rs @@ -22,6 +22,15 @@ fn test_output_multi_files_print_all_chars() { pM-qM-rM-sM-tM-uM-vM-wM-xM-yM-zM-{M-|M-}M-~M-^?"); } +#[test] +fn test_numbered_lines_no_trailing_newline() { + new_ucmd!() + .args(&["nonewline.txt", "alpha.txt", "-n"]) + .succeeds() + .stdout_only(" 1\ttext without a trailing newlineabcde\n 2\tfghij\n \ + 3\tklmno\n 4\tpqrst\n 5\tuvwxyz\n"); +} + #[test] fn test_stdin_show_nonprinting() { for same_param in vec!["-v", "--show-nonprinting"] {