From f62b8d79759650ff00bdc691249ca8eb7304e65e Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 27 Dec 2024 16:08:48 +0100 Subject: [PATCH] csplit: allow offset without sign in pattern --- src/uu/csplit/src/patterns.rs | 34 +++++++++++++++++++------- tests/by-util/test_csplit.rs | 45 ++++++++++++++++++++--------------- 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/src/uu/csplit/src/patterns.rs b/src/uu/csplit/src/patterns.rs index bd6c4fbfaef..edd632d08fc 100644 --- a/src/uu/csplit/src/patterns.rs +++ b/src/uu/csplit/src/patterns.rs @@ -106,7 +106,7 @@ pub fn get_patterns(args: &[String]) -> Result, CsplitError> { fn extract_patterns(args: &[String]) -> Result, CsplitError> { let mut patterns = Vec::with_capacity(args.len()); let to_match_reg = - Regex::new(r"^(/(?P.+)/|%(?P.+)%)(?P[\+-]\d+)?$").unwrap(); + Regex::new(r"^(/(?P.+)/|%(?P.+)%)(?P[\+-]?\d+)?$").unwrap(); let execute_ntimes_reg = Regex::new(r"^\{(?P\d+)|\*\}$").unwrap(); let mut iter = args.iter().peekable(); @@ -219,14 +219,15 @@ mod tests { "{*}", "/test3.*end$/", "{4}", - "/test4.*end$/+3", - "/test5.*end$/-3", + "/test4.*end$/3", + "/test5.*end$/+3", + "/test6.*end$/-3", ] .into_iter() .map(|v| v.to_string()) .collect(); let patterns = get_patterns(input.as_slice()).unwrap(); - assert_eq!(patterns.len(), 5); + assert_eq!(patterns.len(), 6); match patterns.first() { Some(Pattern::UpToMatch(reg, 0, ExecutePattern::Times(1))) => { let parsed_reg = format!("{reg}"); @@ -256,12 +257,19 @@ mod tests { _ => panic!("expected UpToMatch pattern"), }; match patterns.get(4) { - Some(Pattern::UpToMatch(reg, -3, ExecutePattern::Times(1))) => { + Some(Pattern::UpToMatch(reg, 3, ExecutePattern::Times(1))) => { let parsed_reg = format!("{reg}"); assert_eq!(parsed_reg, "test5.*end$"); } _ => panic!("expected UpToMatch pattern"), }; + match patterns.get(5) { + Some(Pattern::UpToMatch(reg, -3, ExecutePattern::Times(1))) => { + let parsed_reg = format!("{reg}"); + assert_eq!(parsed_reg, "test6.*end$"); + } + _ => panic!("expected UpToMatch pattern"), + }; } #[test] @@ -273,14 +281,15 @@ mod tests { "{*}", "%test3.*end$%", "{4}", - "%test4.*end$%+3", - "%test5.*end$%-3", + "%test4.*end$%3", + "%test5.*end$%+3", + "%test6.*end$%-3", ] .into_iter() .map(|v| v.to_string()) .collect(); let patterns = get_patterns(input.as_slice()).unwrap(); - assert_eq!(patterns.len(), 5); + assert_eq!(patterns.len(), 6); match patterns.first() { Some(Pattern::SkipToMatch(reg, 0, ExecutePattern::Times(1))) => { let parsed_reg = format!("{reg}"); @@ -310,12 +319,19 @@ mod tests { _ => panic!("expected SkipToMatch pattern"), }; match patterns.get(4) { - Some(Pattern::SkipToMatch(reg, -3, ExecutePattern::Times(1))) => { + Some(Pattern::SkipToMatch(reg, 3, ExecutePattern::Times(1))) => { let parsed_reg = format!("{reg}"); assert_eq!(parsed_reg, "test5.*end$"); } _ => panic!("expected SkipToMatch pattern"), }; + match patterns.get(5) { + Some(Pattern::SkipToMatch(reg, -3, ExecutePattern::Times(1))) => { + let parsed_reg = format!("{reg}"); + assert_eq!(parsed_reg, "test6.*end$"); + } + _ => panic!("expected SkipToMatch pattern"), + }; } #[test] diff --git a/tests/by-util/test_csplit.rs b/tests/by-util/test_csplit.rs index 10ead0b4544..2315715228d 100644 --- a/tests/by-util/test_csplit.rs +++ b/tests/by-util/test_csplit.rs @@ -130,17 +130,21 @@ fn test_up_to_match_sequence() { #[test] fn test_up_to_match_offset() { - let (at, mut ucmd) = at_and_ucmd!(); - ucmd.args(&["numbers50.txt", "/9$/+3"]) - .succeeds() - .stdout_only("24\n117\n"); + for offset in ["3", "+3"] { + let (at, mut ucmd) = at_and_ucmd!(); + ucmd.args(&["numbers50.txt", &format!("/9$/{offset}")]) + .succeeds() + .stdout_only("24\n117\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, 12)); - assert_eq!(at.read("xx01"), generate(12, 51)); + 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, 12)); + assert_eq!(at.read("xx01"), generate(12, 51)); + at.remove("xx00"); + at.remove("xx01"); + } } #[test] @@ -316,16 +320,19 @@ fn test_skip_to_match_sequence4() { #[test] fn test_skip_to_match_offset() { - let (at, mut ucmd) = at_and_ucmd!(); - ucmd.args(&["numbers50.txt", "%23%+3"]) - .succeeds() - .stdout_only("75\n"); + for offset in ["3", "+3"] { + let (at, mut ucmd) = at_and_ucmd!(); + ucmd.args(&["numbers50.txt", &format!("%23%{offset}")]) + .succeeds() + .stdout_only("75\n"); - let count = glob(&at.plus_as_string("xx*")) - .expect("there should be splits created") - .count(); - assert_eq!(count, 1); - assert_eq!(at.read("xx00"), generate(26, 51)); + let count = glob(&at.plus_as_string("xx*")) + .expect("there should be splits created") + .count(); + assert_eq!(count, 1); + assert_eq!(at.read("xx00"), generate(26, 51)); + at.remove("xx00"); + } } #[test]