From 33ac58383c499e19e92c3effefa1c4641861851a Mon Sep 17 00:00:00 2001 From: Tommaso Fellegara <96147629+Felle33@users.noreply.github.com> Date: Thu, 9 Jan 2025 09:20:48 +0100 Subject: [PATCH] csplit: fix bug when --suppress-matched flag is active and positive/negative offset is present (#7088) * tests/csplit: modified test test_up_to_match_offset_option_suppress_matched according to issue #7052 and modified also test_up_to_match_negative_offset_option_suppress_matched * csplit: managed the positive and negative offset when the --suppressed-matched flag is active * tests/csplit: modified test test_up_to_match_offset_option_suppress_matched according to issue #7052 and modified also test_up_to_match_negative_offset_option_suppress_matched * csplit: managed the positive and negative offset when the --suppressed-matched flag is active * csplit: swapped if and else blocks for better readability --- src/uu/csplit/src/csplit.rs | 19 ++++++++++++++++++- tests/by-util/test_csplit.rs | 10 +++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/uu/csplit/src/csplit.rs b/src/uu/csplit/src/csplit.rs index 329b06d36..d654c9271 100644 --- a/src/uu/csplit/src/csplit.rs +++ b/src/uu/csplit/src/csplit.rs @@ -372,6 +372,7 @@ impl SplitWriter<'_> { while let Some((ln, line)) = input_iter.next() { let l = line?; if regex.is_match(&l) { + let mut next_line_suppress_matched = false; match (self.options.suppress_matched, offset) { // no offset, add the line to the next split (false, 0) => { @@ -382,6 +383,11 @@ impl SplitWriter<'_> { } // a positive offset, some more lines need to be added to the current split (false, _) => self.writeln(&l)?, + // suppress matched option true, but there is a positive offset, so the line is printed + (true, 1..) => { + next_line_suppress_matched = true; + self.writeln(&l)?; + } _ => (), }; offset -= 1; @@ -402,6 +408,11 @@ impl SplitWriter<'_> { offset -= 1; } self.finish_split(); + + // if we have to suppress one line after we take the next and do nothing + if next_line_suppress_matched { + input_iter.next(); + } return Ok(()); } self.writeln(&l)?; @@ -420,7 +431,12 @@ impl SplitWriter<'_> { for line in input_iter.shrink_buffer_to_size() { self.writeln(&line)?; } - if !self.options.suppress_matched { + if self.options.suppress_matched { + // since offset_usize is for sure greater than 0 + // the first element of the buffer should be removed and this + // line inserted to be coherent with GNU implementation + input_iter.add_line_to_buffer(ln, l); + } else { // add 1 to the buffer size to make place for the matched line input_iter.set_size_of_buffer(offset_usize + 1); assert!( @@ -428,6 +444,7 @@ impl SplitWriter<'_> { "should be big enough to hold every lines" ); } + self.finish_split(); if input_iter.buffer_len() < offset_usize { return Err(CsplitError::LineOutOfRange(pattern_as_str.to_string())); diff --git a/tests/by-util/test_csplit.rs b/tests/by-util/test_csplit.rs index 231571522..9323b9851 100644 --- a/tests/by-util/test_csplit.rs +++ b/tests/by-util/test_csplit.rs @@ -469,14 +469,14 @@ fn test_up_to_match_offset_option_suppress_matched() { let (at, mut ucmd) = at_and_ucmd!(); ucmd.args(&["numbers50.txt", "--suppress-matched", "/10/+4"]) .succeeds() - .stdout_only("27\n111\n"); + .stdout_only("30\n108\n"); let count = glob(&at.plus_as_string("xx*")) .expect("there should be splits created") .count(); assert_eq!(count, 2); - assert_eq!(at.read("xx00"), generate(1, 10) + &generate(11, 14)); - assert_eq!(at.read("xx01"), generate(14, 51)); + assert_eq!(at.read("xx00"), generate(1, 14)); + assert_eq!(at.read("xx01"), generate(15, 51)); } #[test] @@ -484,14 +484,14 @@ fn test_up_to_match_negative_offset_option_suppress_matched() { let (at, mut ucmd) = at_and_ucmd!(); ucmd.args(&["numbers50.txt", "--suppress-matched", "/10/-4"]) .succeeds() - .stdout_only("10\n128\n"); + .stdout_only("10\n129\n"); let count = glob(&at.plus_as_string("xx*")) .expect("there should be splits created") .count(); assert_eq!(count, 2); assert_eq!(at.read("xx00"), generate(1, 6)); - assert_eq!(at.read("xx01"), generate(6, 10) + &generate(11, 51)); + assert_eq!(at.read("xx01"), generate(7, 51)); } #[test]