changeset 742:092937de2ad7

Refactor matchpats and walk Move core match function code to util Add some comments and whitespace Simplify options Use lambdas instead of always and never
author mpm@selenic.com
date Thu, 21 Jul 2005 12:21:33 -0500
parents 156dc2f3be7f
children b0ba1866d6b5
files mercurial/commands.py mercurial/util.py
diffstat 2 files changed, 42 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py	Wed Jul 20 20:11:23 2005 -0500
+++ b/mercurial/commands.py	Thu Jul 21 12:21:33 2005 -0500
@@ -39,40 +39,16 @@
                 for x in args]
     return args
 
-def matchpats(ui, cwd, pats = [], opts = {}, emptyok = True):
-    if not pats and not emptyok:
-        raise Abort('at least one file name or pattern required')
-    head = ''
-    if opts.get('rootless'): head = '(?:.*/|)'
-    def reify(name, tail):
-        if name.startswith('re:'):
-            return name[3:]
-        elif name.startswith('glob:'):
-            return head + util.globre(name[5:], '', tail)
-        elif name.startswith('path:'):
-            return '^' + re.escape(name[5:]) + '$'
-        return head + util.globre(name, '', tail)
-    cwdsep = cwd + os.sep
-    def under(fn):
-        if not cwd or fn.startswith(cwdsep): return True
-    def matchfn(pats, tail, ifempty = util.always):
-        if not pats: return ifempty
-        pat = '(?:%s)' % '|'.join([reify(p, tail) for p in pats])
-        if cwd: pat = re.escape(cwd + os.sep) + pat
-        ui.debug('regexp: %s\n' % pat)
-        return re.compile(pat).match
-    patmatch = matchfn(pats, '$')
-    incmatch = matchfn(opts.get('include'), '(?:/|$)', under)
-    excmatch = matchfn(opts.get('exclude'), '(?:/|$)', util.never)
-    return lambda fn: (incmatch(fn) and not excmatch(fn) and
-                       (fn.endswith('/') or patmatch(fn)))
+def matchpats(cwd, pats = [], opts = {}, head = ''):
+    return util.matcher(cwd, pats, opts.get('include'),
+                        opts.get('exclude'), head)
 
-def walk(repo, pats, opts, emptyok = True):
+def walk(repo, pats, opts, head = ''):
     cwd = repo.getcwd()
+    c = 0
     if cwd: c = len(cwd) + 1
-    for src, fn in repo.walk(match = matchpats(repo.ui, cwd, pats, opts, emptyok)):
-        if cwd: yield src, fn, fn[c:]
-        else: yield src, fn, fn
+    for src, fn in repo.walk(match = matchpats(cwd, pats, opts, head)):
+        yield src, fn, fn[c:]
 
 revrangesep = ':'
 
@@ -709,10 +685,10 @@
 
 def locate(ui, repo, *pats, **opts):
     """locate files matching specific patterns"""
+    end = '\n'
     if opts['print0']: end = '\0'
-    else: end = '\n'
-    opts['rootless'] = True
-    for src, abs, rel in walk(repo, pats, opts):
+
+    for src, abs, rel in walk(repo, pats, opts, '(?:.*/|)'):
         if repo.dirstate.state(abs) == '?': continue
         if opts['fullpath']:
             ui.write(os.path.join(repo.root, abs), end)
@@ -998,8 +974,7 @@
     R = removed
     ? = not tracked'''
 
-    (c, a, d, u) = repo.changes(match = matchpats(ui, repo.getcwd(),
-                                                  pats, opts))
+    (c, a, d, u) = repo.changes(match = matchpats(repo.getcwd(), pats, opts))
     (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
 
     for f in c:
--- a/mercurial/util.py	Wed Jul 20 20:11:23 2005 -0500
+++ b/mercurial/util.py	Thu Jul 21 12:21:33 2005 -0500
@@ -79,6 +79,37 @@
             res += re.escape(c)
     return head + res + tail
 
+def matcher(cwd, pats, inc, exc, head = ''):
+    def regex(name, tail):
+        '''convert a pattern into a regular expression'''
+        if name.startswith('re:'):
+            return name[3:]
+        elif name.startswith('path:'):
+            return '^' + re.escape(name[5:]) + '$'
+        elif name.startswith('glob:'):
+            return head + globre(name[5:], '', tail)
+        return head + globre(name, '', tail)
+
+    def under(fn):
+        """check if fn is under our cwd"""
+        return not cwd or fn.startswith(cwdsep)
+
+    def matchfn(pats, tail):
+        """build a matching function from a set of patterns"""
+        if pats:
+            pat = '(?:%s)' % '|'.join([regex(p, tail) for p in pats])
+            if cwd:
+                pat = re.escape(cwd + os.sep) + pat
+            return re.compile(pat).match
+
+    cwdsep = cwd + os.sep
+    patmatch = matchfn(pats, '$') or (lambda fn: True)
+    incmatch = matchfn(inc, '(?:/|$)') or under
+    excmatch = matchfn(exc, '(?:/|$)') or (lambda fn: False)
+
+    return lambda fn: (incmatch(fn) and not excmatch(fn) and
+                       (fn.endswith('/') or patmatch(fn)))
+
 def system(cmd, errprefix=None):
     """execute a shell command that must succeed"""
     rc = os.system(cmd)