csplit: do not emit remainder of input after an error

This commit is contained in:
Ben Wiederhake 2024-03-23 23:14:26 +01:00
parent 44fa2e960a
commit 27fd3e5d39
2 changed files with 21 additions and 26 deletions

View file

@ -99,15 +99,17 @@ where
let patterns: Vec<patterns::Pattern> = patterns::get_patterns(&patterns[..])?;
let ret = do_csplit(&mut split_writer, patterns, &mut input_iter);
// consume the rest
input_iter.rewind_buffer();
if let Some((_, line)) = input_iter.next() {
split_writer.new_writer()?;
split_writer.writeln(&line?)?;
for (_, line) in input_iter {
// consume the rest, unless there was an error
if ret.is_ok() {
input_iter.rewind_buffer();
if let Some((_, line)) = input_iter.next() {
split_writer.new_writer()?;
split_writer.writeln(&line?)?;
for (_, line) in input_iter {
split_writer.writeln(&line?)?;
}
split_writer.finish_split();
}
split_writer.finish_split();
}
// delete files on error by default
if ret.is_err() && !options.keep_files {

View file

@ -575,7 +575,7 @@ fn test_skip_to_match_context_underflow() {
let (at, mut ucmd) = at_and_ucmd!();
ucmd.args(&["numbers50.txt", "%5%-10"])
.fails()
.stdout_is("141\n")
.stdout_is("")
.stderr_is("csplit: '%5%-10': line number out of range\n");
let count = glob(&at.plus_as_string("xx*"))
@ -586,14 +586,13 @@ fn test_skip_to_match_context_underflow() {
let (at, mut ucmd) = at_and_ucmd!();
ucmd.args(&["numbers50.txt", "%5%-10", "-k"])
.fails()
.stdout_is("141\n")
.stdout_is("")
.stderr_is("csplit: '%5%-10': line number out of range\n");
let count = glob(&at.plus_as_string("xx*"))
.expect("counting splits")
.count();
assert_eq!(count, 1);
assert_eq!(at.read("xx00"), generate(1, 51));
assert_eq!(count, 0);
}
#[test]
@ -1225,13 +1224,12 @@ fn test_corner_case4() {
assert_eq!(at.read("xx02"), generate(26, 51));
}
// NOTE: differs from gnu's output: the empty split is not written
#[test]
fn test_up_to_match_context_underflow() {
let (at, mut ucmd) = at_and_ucmd!();
ucmd.args(&["numbers50.txt", "/5/-10"])
.fails()
.stdout_is("0\n141\n")
.stdout_is("0\n")
.stderr_is("csplit: '/5/-10': line number out of range\n");
let count = glob(&at.plus_as_string("xx*"))
@ -1242,26 +1240,24 @@ fn test_up_to_match_context_underflow() {
let (at, mut ucmd) = at_and_ucmd!();
ucmd.args(&["numbers50.txt", "/5/-10", "-k"])
.fails()
.stdout_is("0\n141\n")
.stdout_is("0\n")
.stderr_is("csplit: '/5/-10': line number out of range\n");
let count = glob(&at.plus_as_string("xx*"))
.expect("counting splits")
.count();
assert_eq!(count, 2);
assert_eq!(count, 1);
assert_eq!(at.read("xx00"), "");
assert_eq!(at.read("xx01"), generate(1, 51));
}
// the offset is out of range because of the first pattern
// NOTE: output different than gnu's: the empty split is written but the rest of the input file is not
#[test]
fn test_line_num_range_with_up_to_match1() {
let (at, mut ucmd) = at_and_ucmd!();
ucmd.args(&["numbers50.txt", "10", "/12/-5"])
.fails()
.stderr_is("csplit: '/12/-5': line number out of range\n")
.stdout_is("18\n0\n123\n");
.stdout_is("18\n0\n");
let count = glob(&at.plus_as_string("xx*"))
.expect("there should be splits created")
@ -1272,26 +1268,24 @@ fn test_line_num_range_with_up_to_match1() {
ucmd.args(&["numbers50.txt", "10", "/12/-5", "-k"])
.fails()
.stderr_is("csplit: '/12/-5': line number out of range\n")
.stdout_is("18\n0\n123\n");
.stdout_is("18\n0\n");
let count = glob(&at.plus_as_string("xx*"))
.expect("there should be splits created")
.count();
assert_eq!(count, 3);
assert_eq!(count, 2);
assert_eq!(at.read("xx00"), generate(1, 10));
assert_eq!(at.read("xx01"), "");
assert_eq!(at.read("xx02"), generate(10, 51));
}
// the offset is out of range because more lines are needed than physically available
// NOTE: output different than gnu's: the empty split is not written but the rest of the input file is
#[test]
fn test_line_num_range_with_up_to_match2() {
let (at, mut ucmd) = at_and_ucmd!();
ucmd.args(&["numbers50.txt", "10", "/12/-15"])
.fails()
.stderr_is("csplit: '/12/-15': line number out of range\n")
.stdout_is("18\n0\n123\n");
.stdout_is("18\n0\n");
let count = glob(&at.plus_as_string("xx*"))
.expect("there should be splits created")
@ -1302,15 +1296,14 @@ fn test_line_num_range_with_up_to_match2() {
ucmd.args(&["numbers50.txt", "10", "/12/-15", "-k"])
.fails()
.stderr_is("csplit: '/12/-15': line number out of range\n")
.stdout_is("18\n0\n123\n");
.stdout_is("18\n0\n");
let count = glob(&at.plus_as_string("xx*"))
.expect("there should be splits created")
.count();
assert_eq!(count, 3);
assert_eq!(count, 2);
assert_eq!(at.read("xx00"), generate(1, 10));
assert_eq!(at.read("xx01"), "");
assert_eq!(at.read("xx02"), generate(10, 51));
}
// NOTE: output different than gnu's: the pattern /10/ is matched but should not