From 1107fadca9e263b8aa976d82ac61be7952d068ae Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 19 Sep 2023 10:47:00 +0200 Subject: [PATCH 1/2] nl: increase line number over multiple files --- src/uu/nl/src/nl.rs | 33 ++++++++++++++++++++++++--------- tests/by-util/test_nl.rs | 13 +++++++++++++ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/uu/nl/src/nl.rs b/src/uu/nl/src/nl.rs index 61a0a9f35f4..3568822377f 100644 --- a/src/uu/nl/src/nl.rs +++ b/src/uu/nl/src/nl.rs @@ -55,6 +55,20 @@ impl Default for Settings { } } +struct Stats { + line_number: i64, + consecutive_empty_lines: u64, +} + +impl Stats { + fn new(starting_line_number: i64) -> Self { + Self { + line_number: starting_line_number, + consecutive_empty_lines: 0, + } + } +} + // NumberingStyle stores which lines are to be numbered. // The possible options are: // 1. Number all lines @@ -160,6 +174,8 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { None => vec!["-".to_owned()], }; + let mut stats = Stats::new(settings.starting_line_number); + for file in &files { if file == "-" { // If both file names and '-' are specified, we choose to treat first all @@ -170,12 +186,12 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let path = Path::new(file); let reader = File::open(path).map_err_context(|| file.to_string())?; let mut buffer = BufReader::new(reader); - nl(&mut buffer, &settings)?; + nl(&mut buffer, &mut stats, &settings)?; } if read_stdin { let mut buffer = BufReader::new(stdin()); - nl(&mut buffer, &settings)?; + nl(&mut buffer, &mut stats, &settings)?; } Ok(()) } @@ -285,10 +301,9 @@ pub fn uu_app() -> Command { } // nl implements the main functionality for an individual buffer. -fn nl(reader: &mut BufReader, settings: &Settings) -> UResult<()> { +fn nl(reader: &mut BufReader, stats: &mut Stats, settings: &Settings) -> UResult<()> { let mut current_numbering_style = &settings.body_numbering; - let mut line_no = settings.starting_line_number; - let mut consecutive_empty_lines = 0; + let mut consecutive_empty_lines = stats.consecutive_empty_lines; for line in reader.lines() { let line = line.map_err_context(|| "could not read line".to_string())?; @@ -312,7 +327,7 @@ fn nl(reader: &mut BufReader, settings: &Settings) -> UResult<()> { if let Some(new_style) = new_numbering_style { current_numbering_style = new_style; if settings.renumber { - line_no = settings.starting_line_number; + stats.line_number = settings.starting_line_number; } println!(); } else { @@ -336,13 +351,13 @@ fn nl(reader: &mut BufReader, settings: &Settings) -> UResult<()> { "{}{}{}", settings .number_format - .format(line_no, settings.number_width), + .format(stats.line_number, settings.number_width), settings.number_separator, line ); // update line number for the potential next line - match line_no.checked_add(settings.line_increment) { - Some(new_line_no) => line_no = new_line_no, + match stats.line_number.checked_add(settings.line_increment) { + Some(new_line_number) => stats.line_number = new_line_number, None => return Err(USimpleError::new(1, "line number overflow")), } } else { diff --git a/tests/by-util/test_nl.rs b/tests/by-util/test_nl.rs index b58c0c206fb..336ab4c29af 100644 --- a/tests/by-util/test_nl.rs +++ b/tests/by-util/test_nl.rs @@ -311,6 +311,19 @@ fn test_default_body_numbering() { .stdout_is(" 1\ta\n \n 2\tb\n"); } +#[test] +fn test_default_body_numbering_multiple_files() { + let (at, mut ucmd) = at_and_ucmd!(); + + at.write("a.txt", "a"); + at.write("b.txt", "b"); + at.write("c.txt", "c"); + + ucmd.args(&["a.txt", "b.txt", "c.txt"]) + .succeeds() + .stdout_is(" 1\ta\n 2\tb\n 3\tc\n"); +} + #[test] fn test_body_numbering_all_lines_without_delimiter() { for arg in ["-ba", "--body-numbering=a"] { From 1a30a1b8b656afe0deb674a4b848f7b311a18c81 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 19 Sep 2023 10:47:20 +0200 Subject: [PATCH 2/2] nl: support --join-blank-lines over multiple files --- src/uu/nl/src/nl.rs | 7 +++---- tests/by-util/test_nl.rs | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/uu/nl/src/nl.rs b/src/uu/nl/src/nl.rs index 3568822377f..fef9c030a2e 100644 --- a/src/uu/nl/src/nl.rs +++ b/src/uu/nl/src/nl.rs @@ -303,15 +303,14 @@ pub fn uu_app() -> Command { // nl implements the main functionality for an individual buffer. fn nl(reader: &mut BufReader, stats: &mut Stats, settings: &Settings) -> UResult<()> { let mut current_numbering_style = &settings.body_numbering; - let mut consecutive_empty_lines = stats.consecutive_empty_lines; for line in reader.lines() { let line = line.map_err_context(|| "could not read line".to_string())?; if line.is_empty() { - consecutive_empty_lines += 1; + stats.consecutive_empty_lines += 1; } else { - consecutive_empty_lines = 0; + stats.consecutive_empty_lines = 0; }; // FIXME section delimiters are hardcoded and settings.section_delimiter is ignored @@ -336,7 +335,7 @@ fn nl(reader: &mut BufReader, stats: &mut Stats, settings: &Settings // for numbering, and only number the last one NumberingStyle::All if line.is_empty() - && consecutive_empty_lines % settings.join_blank_lines != 0 => + && stats.consecutive_empty_lines % settings.join_blank_lines != 0 => { false } diff --git a/tests/by-util/test_nl.rs b/tests/by-util/test_nl.rs index 336ab4c29af..b008c61de77 100644 --- a/tests/by-util/test_nl.rs +++ b/tests/by-util/test_nl.rs @@ -284,6 +284,31 @@ fn test_join_blank_lines() { } } +#[test] +fn test_join_blank_lines_multiple_files() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + at.write("a.txt", "\n\n"); + at.write("b.txt", "\n\n"); + at.write("c.txt", "\n\n"); + + for arg in ["-l3", "--join-blank-lines=3"] { + scene + .ucmd() + .args(&[arg, "--body-numbering=a", "a.txt", "b.txt", "c.txt"]) + .succeeds() + .stdout_is(concat!( + " \n", + " \n", + " 1\t\n", + " \n", + " \n", + " 2\t\n", + )); + } +} + #[test] fn test_join_blank_lines_zero() { for arg in ["-l0", "--join-blank-lines=0"] {