aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonas Maier <jonas@x77.dev>2026-06-01 22:40:04 +0200
committerJonas Maier <jonas@x77.dev>2026-06-01 22:40:04 +0200
commite662dfa3a074a7603cbb9de473bf8bb45b4bb960 (patch)
tree1bbb800bebfe137e82d64da47bca487abdfb786f
parentc73ed9310d8162b71183688de62bf8c1fc8420df (diff)
downloadpish-e662dfa3a074a7603cbb9de473bf8bb45b4bb960.tar.gz
some more regex tests
-rw-r--r--src/parse/regex/mod.rs18
-rw-r--r--test-cases/case1/script.sh80
-rw-r--r--test-cases/case1/stdout.txt0
-rw-r--r--tests/scripts.rs5
4 files changed, 102 insertions, 1 deletions
diff --git a/src/parse/regex/mod.rs b/src/parse/regex/mod.rs
index 98056cb..51527ae 100644
--- a/src/parse/regex/mod.rs
+++ b/src/parse/regex/mod.rs
@@ -107,7 +107,7 @@ fn parse_rep(s: &mut super::Cursor<'_>) -> Result<Pattern> {
// TODO: non-greedy
}
-const SYMBOLS: &[u8] = b"{}[]()*+-?|. ";
+const SYMBOLS: &[u8] = b"{}[]()*+-?|.\\ ";
fn is_symbol(x: u8) -> bool {
SYMBOLS.contains(&x)
}
@@ -183,6 +183,22 @@ fn parse_atom(s: &mut super::Cursor<'_>) -> Result<Pattern> {
s.highlight_from(begin, OtherHighlights::RegexSymbol);
Ok(Pattern::Range(0, 127))
}
+ b'\\' => {
+ s.adv();
+ if s.has() {
+ let escaped = s.adv();
+ s.highlight_from(begin, OtherHighlights::RegexSymbol);
+
+ if is_symbol(escaped) {
+ Ok(Pattern::Byte(escaped))
+ } else {
+ // TODO interpret \w and others
+ Err(ParseError::Unknown(escaped))
+ }
+ } else {
+ Err(ParseError::Eof)
+ }
+ }
x if is_symbol(x) => Ok(Pattern::Nothing),
ch => {
s.adv();
diff --git a/test-cases/case1/script.sh b/test-cases/case1/script.sh
new file mode 100644
index 0000000..ed9de13
--- /dev/null
+++ b/test-cases/case1/script.sh
@@ -0,0 +1,80 @@
+case foo {
+ [fF][oO][oO] {}
+ .* {
+ echo 'failed foo [fF][oO][oO]'
+ }
+}
+
+case fOo {
+ [fF][oO][oO] {}
+ .* {
+ echo 'failed fOo [fF][oO][oO]'
+ }
+}
+
+case foo {
+ foo+ {}
+ .* {
+ echo 'failed foo+'
+ }
+}
+
+case foo {
+ fo+ {}
+ .* {
+ echo 'failed fo+'
+ }
+}
+
+case foo {
+ fo* {}
+ .* {
+ echo 'failed fo*'
+ }
+}
+
+case foo {
+ fo {
+ echo 'failed fo'
+ }
+ .* {}
+}
+
+case '[]' {
+ .. {}
+ .* {
+ echo 'failed [] ..'
+ }
+}
+
+case '[]' {
+ \[\] {}
+ .* {
+ echo 'failed [] \[\]'
+ }
+}
+
+fun match_ip {
+ case $1 {
+ ([0-9][0-9]?[0-9]?)\.([0-9]?[0-9]?[0-9])\.([0-9]?[0-9]?[0-9])\.([0-9]?[0-9]?[0-9]) {
+ if [ $2 != yes ] {
+ echo "$1 should not match but it did"
+ }
+ }
+ .* {
+ if [ $2 = yes ] {
+ echo "$1 should match but it did not"
+ }
+ }
+ }
+}
+
+match_ip 192.168.1.1 yes
+match_ip 999.999.999.999 yes # the IP regex is not very good but we are testing the regex engine not IP parsing.
+match_ip foo no
+match_ip ::1 no
+match_ip 192..168.1.1 no
+match_ip 192.168.1.1.1 no
+match_ip 0.0.0.0 yes
+match_ip 01.1.1.1 yes
+match_ip 1234.0.0.1 no
diff --git a/test-cases/case1/stdout.txt b/test-cases/case1/stdout.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test-cases/case1/stdout.txt
diff --git a/tests/scripts.rs b/tests/scripts.rs
index 93034c4..8ee5f0e 100644
--- a/tests/scripts.rs
+++ b/tests/scripts.rs
@@ -7,6 +7,11 @@ fn case0() {
}
#[test]
+fn case1() {
+ common::test_case("case1", include_bytes!("../test-cases/case1/script.sh"), include_bytes!("../test-cases/case1/stdout.txt"));
+}
+
+#[test]
fn comment() {
common::test_case("comment", include_bytes!("../test-cases/comment/script.sh"), include_bytes!("../test-cases/comment/stdout.txt"));
}