Commits

Liam Staskawicz  committed b941f93

pattern: wildcard matching

  • Participants
  • Parent commits b9aad9d

Comments (0)

Files changed (2)

 
 func PatternMatch(pattern, test string) bool {
 
-	// we try to iterate where possible, but for ease
-	// of implementation we recurse in several places.
-
 	// indexes into our strings
 	ipattern := 0
 	itest := 0
 			itest++
 
 		case '*':
-			// matches zero or more characters
-			return false
+			result, poffset, toffset := matchWildcard(pattern[ipattern:], test[itest:])
+			if !result {
+				return false
+			}
+			ipattern += poffset
+			itest += toffset
 
 		case ']', '}':
 			// OSCWarning("Spurious %c in pattern \".../%s/...\"",pattern[0], theWholePattern);
 	panic("unreachable - failure in osc.PatternMatch()")
 }
 
+// '*' in the OSC Address Pattern matches any sequence of zero or more characters
+//
+// we assume it's not meaningful to have any other 'special' characters in the
+// pattern string beyond the wildcard - it has already matched everything up
+// to the next / delimited part anyway
+func matchWildcard(pattern, test string) (bool, int, int) {
+
+	// check for next part delimiter
+	pidx := strings.IndexRune(pattern, '/')
+	tidx := strings.IndexRune(test, '/')
+
+	// both have one - move each to it
+	if pidx >= 0 && tidx >= 0 {
+		return true, pidx, tidx
+	}
+
+	// neither have one - move each to their end
+	if pidx < 0 && tidx < 0 {
+		return true, len(pattern), len(test)
+	}
+
+	// mismatched number of parts
+	return false, 0, 0
+}
+
 // spec: "a string of characters in square brackets (e.g., "[string]")
 // in the OSC Address Pattern matches any character in the string."
 func matchSet(pattern string, test rune) (bool, int) {

File pattern_test.go

 	}
 }
 
+func TestWildcard(t *testing.T) {
+
+	if !PatternMatch("/a/*/c", "/a/9sdfhsdgh/c") {
+		t.Error()
+	}
+
+	// test as last element
+	if !PatternMatch("/a/*", "/a/9sdfhsdgh") {
+		t.Error()
+	}
+
+	// different number of message parts
+	if PatternMatch("/a/*", "/a/9sdfhsdgh/c") {
+		t.Error()
+	}
+
+	if PatternMatch("/a/*/z", "/a/9sdfhsdgh") {
+		t.Error()
+	}
+
+	// somewhat silly pattern string - initial * trumps everything to the next delimiter
+	if !PatternMatch("/a/*other/z", "/a/bingo/z") {
+		t.Error()
+	}
+
+	// wildcard partial way through a part
+	if !PatternMatch("/a/prefix*/z", "/a/prefixsuffix/z") {
+		t.Error()
+	}
+}
+
 func TestSet(t *testing.T) {
 
 	// set range is inclusive