aboutsummaryrefslogtreecommitdiff
path: root/src/makefile/pattern.rs
diff options
context:
space:
mode:
authorMelody Horn <melody@boringcactus.com>2021-03-28 14:57:03 -0600
committerMelody Horn <melody@boringcactus.com>2021-03-28 14:57:03 -0600
commitbc5038e6c344803bce76add47b13ceaa61a5bde3 (patch)
treeeec9a8fc36562aa4413cf8be8ef22910fdc75cac /src/makefile/pattern.rs
parent82278c3a5aa93204c963a63cc3cfefea1d0fb3fd (diff)
downloadmakers-bc5038e6c344803bce76add47b13ceaa61a5bde3.tar.gz
makers-bc5038e6c344803bce76add47b13ceaa61a5bde3.zip
almost implement all functions
Diffstat (limited to 'src/makefile/pattern.rs')
-rw-r--r--src/makefile/pattern.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/makefile/pattern.rs b/src/makefile/pattern.rs
new file mode 100644
index 0000000..733721e
--- /dev/null
+++ b/src/makefile/pattern.rs
@@ -0,0 +1,49 @@
+use regex::{Captures, Regex};
+
+fn compile_pattern(pattern: &str) -> Regex {
+ let mut result = String::new();
+ for c in pattern.chars() {
+ match c {
+ // This is a nightmare, because we're escaping for regex syntax before we put
+ // things into result.
+
+ // We don't end with a backslash, so this is an unescaped wildcard.
+ '%' if !result.ends_with(r"\\") => {
+ result.push_str(r"(\w*)");
+ }
+
+ // We end with two backslashes, so this is an escaped backslash and then an
+ // unescaped wildcard.
+ '%' if result.ends_with(r"\\\\") => {
+ result = result.strip_suffix(r"\\\\").unwrap().to_string();
+ result.push_str(r"\\(\w*)");
+ }
+
+ // We end with one backslash, so this is an escaped wildcard.
+ '%' if result.ends_with(r"\\") => {
+ result = result.strip_suffix(r"\\").unwrap().to_string();
+ result.push('%');
+ }
+ _ => result.push_str(&regex::escape(&c.to_string())),
+ }
+ }
+ Regex::new(&result).expect("built invalid regex!")
+}
+
+pub(crate) fn r#match<'a>(pattern: &str, text: &'a str) -> Option<Captures<'a>> {
+ compile_pattern(pattern).captures(text)
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn pattern_backslashes() {
+ let test_case = compile_pattern(r"the\%weird\\%pattern\\");
+ assert_eq!(test_case.to_string(), r"the%weird\\(\w*)pattern\\\\");
+
+ let hell = compile_pattern(r"\\\\%");
+ assert_eq!(hell.to_string(), r"\\\\\\(\w*)");
+ }
+}