--- a/mercurial/revset.py Fri Jun 01 12:35:30 2012 +0200
+++ b/mercurial/revset.py Wed May 30 23:13:33 2012 +0100
@@ -1119,6 +1119,46 @@
l.sort()
return [e[-1] for e in l]
+def _stringmatcher(pattern):
+ """
+ accepts a string, possibly starting with 're:' or 'literal:' prefix.
+ returns the matcher name, pattern, and matcher function.
+ missing or unknown prefixes are treated as literal matches.
+
+ helper for tests:
+ >>> def test(pattern, *tests):
+ ... kind, pattern, matcher = _stringmatcher(pattern)
+ ... return (kind, pattern, [bool(matcher(t)) for t in tests])
+
+ exact matching (no prefix):
+ >>> test('abcdefg', 'abc', 'def', 'abcdefg')
+ ('literal', 'abcdefg', [False, False, True])
+
+ regex matching ('re:' prefix)
+ >>> test('re:a.+b', 'nomatch', 'fooadef', 'fooadefbar')
+ ('re', 'a.+b', [False, False, True])
+
+ force exact matches ('literal:' prefix)
+ >>> test('literal:re:foobar', 'foobar', 're:foobar')
+ ('literal', 're:foobar', [False, True])
+
+ unknown prefixes are ignored and treated as literals
+ >>> test('foo:bar', 'foo', 'bar', 'foo:bar')
+ ('literal', 'foo:bar', [False, False, True])
+ """
+ if pattern.startswith('re:'):
+ pattern = pattern[3:]
+ try:
+ regex = re.compile(pattern)
+ except re.error, e:
+ raise error.ParseError(_('invalid regular expression: %s')
+ % e)
+ return 're', pattern, regex.search
+ elif pattern.startswith('literal:'):
+ pattern = pattern[8:]
+ return 'literal', pattern, pattern.__eq__
+
+
def tag(repo, subset, x):
"""``tag([name])``
The specified tag by name, or all tagged revisions if no name is given.