comparison mercurial/util.py @ 888:e7a943e8c52b

Fix up handling of regexp paths.
author Bryan O'Sullivan <bos@serpentine.com>
date Fri, 12 Aug 2005 16:09:17 -0800
parents 509de8ab6f31
children 391de0bcc722 62ec665759f2
comparison
equal deleted inserted replaced
886:509de8ab6f31 888:e7a943e8c52b
93 else: 93 else:
94 raise Abort('%s not under repository root' % myname) 94 raise Abort('%s not under repository root' % myname)
95 95
96 def matcher(repo, cwd, names, inc, exc, head = ''): 96 def matcher(repo, cwd, names, inc, exc, head = ''):
97 def patkind(name): 97 def patkind(name):
98 for prefix in 're:', 'glob:', 'path:': 98 for prefix in 're:', 'glob:', 'path:', 'relpath:':
99 if name.startswith(prefix): return name.split(':', 1) 99 if name.startswith(prefix): return name.split(':', 1)
100 for c in name: 100 for c in name:
101 if c in _globchars: return 'glob', name 101 if c in _globchars: return 'glob', name
102 return 'relpath', name 102 return 'relpath', name
103 103
104 def regex(name, tail): 104 def regex(kind, name, tail):
105 '''convert a pattern into a regular expression''' 105 '''convert a pattern into a regular expression'''
106 kind, name = patkind(name)
107 if kind == 're': 106 if kind == 're':
108 return name 107 return name
109 elif kind == 'path': 108 elif kind == 'path':
110 return '^' + re.escape(name) + '$' 109 return '^' + re.escape(name) + '(?:/|$)'
110 elif kind == 'relpath':
111 return head + re.escape(name) + tail
111 return head + globre(name, '', tail) 112 return head + globre(name, '', tail)
112 113
113 def matchfn(pats, tail): 114 def matchfn(pats, tail):
114 """build a matching function from a set of patterns""" 115 """build a matching function from a set of patterns"""
115 if pats: 116 if pats:
116 pat = '(?:%s)' % '|'.join([regex(p, tail) for p in pats]) 117 pat = '(?:%s)' % '|'.join([regex(k, p, tail) for (k, p) in pats])
117 return re.compile(pat).match 118 return re.compile(pat).match
118 119
119 def globprefix(pat): 120 def globprefix(pat):
120 '''return the non-glob prefix of a path, e.g. foo/* -> foo''' 121 '''return the non-glob prefix of a path, e.g. foo/* -> foo'''
121 root = [] 122 root = []
130 for kind, name in map(patkind, names): 131 for kind, name in map(patkind, names):
131 if kind in ('glob', 'relpath'): 132 if kind in ('glob', 'relpath'):
132 name = canonpath(repo, cwd, name) 133 name = canonpath(repo, cwd, name)
133 if name == '': 134 if name == '':
134 kind, name = 'glob', '**' 135 kind, name = 'glob', '**'
135 if kind in ('glob', 're'): 136 if kind in ('glob', 'path', 're'):
136 pats.append(name) 137 pats.append((kind, name))
137 if kind == 'glob': 138 if kind == 'glob':
138 root = globprefix(name) 139 root = globprefix(name)
139 if root: roots.append(root) 140 if root: roots.append(root)
140 elif kind == 'relpath': 141 elif kind == 'relpath':
141 files.append(name) 142 files.append((kind, name))
142 roots.append(name) 143 roots.append(name)
143 144
144 patmatch = matchfn(pats, '$') or always 145 patmatch = matchfn(pats, '$') or always
145 filematch = matchfn(files, '(?:/|$)') or always 146 filematch = matchfn(files, '(?:/|$)') or always
146 incmatch = matchfn(inc, '(?:/|$)') or always 147 incmatch = matchfn(map(patkind, inc), '(?:/|$)') or always
147 excmatch = matchfn(exc, '(?:/|$)') or (lambda fn: False) 148 excmatch = matchfn(map(patkind, exc), '(?:/|$)') or (lambda fn: False)
148 149
149 return roots, lambda fn: (incmatch(fn) and not excmatch(fn) and 150 return roots, lambda fn: (incmatch(fn) and not excmatch(fn) and
150 (fn.endswith('/') or 151 (fn.endswith('/') or
151 (not pats and not files) or 152 (not pats and not files) or
152 (pats and patmatch(fn)) or 153 (pats and patmatch(fn)) or