From 44fa2e960aed29151d78f3de635db72202ba4391 Mon Sep 17 00:00:00 2001 From: Ben Wiederhake Date: Sat, 23 Mar 2024 22:27:09 +0100 Subject: [PATCH 1/2] csplit: correctly handle repeated arguments --- src/uu/csplit/src/csplit.rs | 1 + tests/by-util/test_csplit.rs | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/uu/csplit/src/csplit.rs b/src/uu/csplit/src/csplit.rs index e4d7c243c..b5004c362 100644 --- a/src/uu/csplit/src/csplit.rs +++ b/src/uu/csplit/src/csplit.rs @@ -585,6 +585,7 @@ pub fn uu_app() -> Command { .version(crate_version!()) .about(ABOUT) .override_usage(format_usage(USAGE)) + .args_override_self(true) .infer_long_args(true) .arg( Arg::new(options::SUFFIX_FORMAT) diff --git a/tests/by-util/test_csplit.rs b/tests/by-util/test_csplit.rs index b52c44b0e..5bd384de3 100644 --- a/tests/by-util/test_csplit.rs +++ b/tests/by-util/test_csplit.rs @@ -1376,3 +1376,39 @@ fn no_such_file() { .fails() .stderr_contains("cannot access 'in': No such file or directory"); } + +#[test] +fn repeat_everything() { + let (at, mut ucmd) = at_and_ucmd!(); + ucmd.args(&[ + "numbers50.txt", + "--suppress-matched", + "--suppress-matched", + "-kzsn", // spell-checker:disable-line + "2", + "-szkn3", // spell-checker:disable-line + "-b", + "%03d", + "-b%03x", + "-f", + "xxy_", + "-fxxz_", // spell-checker:disable-line + "/13/", + "9", + "{5}", + ]) + .fails() + .no_stdout() + .code_is(1) + .stderr_only("csplit: '9': line number out of range on repetition 5\n"); + let count = glob(&at.plus_as_string("xx*")) + .expect("there should be some splits created") + .count(); + assert_eq!(count, 6); + assert_eq!(at.read("xxz_000"), generate(1, 12 + 1)); + assert_eq!(at.read("xxz_001"), generate(14, 17 + 1)); // FIXME: GNU starts at 15 + assert_eq!(at.read("xxz_002"), generate(19, 26 + 1)); + assert_eq!(at.read("xxz_003"), generate(28, 35 + 1)); + assert_eq!(at.read("xxz_004"), generate(37, 44 + 1)); + assert_eq!(at.read("xxz_005"), generate(46, 50 + 1)); +} From 27fd3e5d3918570fc621a23e98166e28b4533bc1 Mon Sep 17 00:00:00 2001 From: Ben Wiederhake Date: Sat, 23 Mar 2024 23:14:26 +0100 Subject: [PATCH 2/2] csplit: do not emit remainder of input after an error --- src/uu/csplit/src/csplit.rs | 16 +++++++++------- tests/by-util/test_csplit.rs | 31 ++++++++++++------------------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/uu/csplit/src/csplit.rs b/src/uu/csplit/src/csplit.rs index b5004c362..cd55ef7df 100644 --- a/src/uu/csplit/src/csplit.rs +++ b/src/uu/csplit/src/csplit.rs @@ -99,15 +99,17 @@ where let patterns: Vec = 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 { diff --git a/tests/by-util/test_csplit.rs b/tests/by-util/test_csplit.rs index 5bd384de3..03b8c92fc 100644 --- a/tests/by-util/test_csplit.rs +++ b/tests/by-util/test_csplit.rs @@ -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