Thread (46 messages) flat view 46 messages, 5 authors, 2016-06-15

Re: [JGIT PATCH v2 11/24] Added the class FNMatchPattern.

From: Shawn O. Pearce <hidden>
Date: 2016-06-15 22:44:36

Florian Koeberle [off-list ref] wrote:
+/**
+ * This class represents a pattern which should work like the fnmatch method.
+ * <code>new FNMatchPattern(exp).matches(input)</code> should do the same like
+ * <code>fnmatch(exp, input, 0) == 0</code>
+ * 
+ * As this isn't a one to one code port, but written based on the documentation
+ * of fnmatch it can be that the behavior of this class differ in some corner
+ * cases from the behavior of the fnmatch function.
+ */
+public class FNMatchPattern {
+
+	private final Pattern regexPattern;
For what it is worth, I got a performance improvement by declaring
that such classes like FNMatchPattern are _not_ threadsafe and
storing a Matcher rather than a Pattern.  Then on each test you
can just reset the Matcher and evaluate it again.

This was worthwhile enough that I went back into RevFilter and
added a clone() method so you can safely clone a RevFilter graph
to create a new set of instances for another thread.

Consider using a Matcher here.  Ignore rule matching with a lot
of patterns will bottleneck things like working directory status
operations.
+	private static String toRegexString(String fnmatchPattern) {
+		final StringBuilder regexStringBuilder = new StringBuilder();
+		char perviosCharacter = 0;
+		for (int i = 0; i < fnmatchPattern.length(); i++) {
+			final char c = fnmatchPattern.charAt(i);
+			switch (c) {
+			case '^':
+				if (perviosCharacter == '[') {
+					regexStringBuilder.append('!');
+				} else {
+					regexStringBuilder.append("\\x5E");
+				}
+				break;
+			case '.':
+				regexStringBuilder.append("\\x2E");
+				break;
+			case '*':
+				regexStringBuilder.append(".*");
+				break;
+			default:
+				regexStringBuilder.append(c);
+			}
+			perviosCharacter = c;
+		}
+		return regexStringBuilder.toString();
Huh.  So the fnmatchPattern of "foo?" will match the name "fo"
in this implementation, but it does not in my C library's fnmatch
function:

	$ cat fnmatch.c 
	#include <fnmatch.h>
	#include <stdio.h>

	int main(int argc, char *argv[]) {
		const char *pattern = argv[1];
		const char *name = argv[2];
		printf("%s on %s = %i\n", pattern, name, fnmatch(pattern, name, 0));
		return 0;
	}
	$ ./fnmatch 'foo?' 'fo'
	foo? on fo = 1

There are plenty more cases like that as too many of the regex
operators are leaking through. All of the regex operators need to
be treated as literals in the regex pattern.

-- 
Shawn.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help