5 # This software may be used and distributed according to the terms of the |
5 # This software may be used and distributed according to the terms of the |
6 # GNU General Public License version 2, incorporated herein by reference. |
6 # GNU General Public License version 2, incorporated herein by reference. |
7 |
7 |
8 import util, re |
8 import util, re |
9 |
9 |
10 class _match(object): |
10 class match(object): |
11 def __init__(self, root, cwd, files, mf, ap): |
11 def __init__(self, root, cwd, patterns, include=[], exclude=[], |
|
12 default='glob', exact=False): |
|
13 """build an object to match a set of file patterns |
|
14 |
|
15 arguments: |
|
16 root - the canonical root of the tree you're matching against |
|
17 cwd - the current working directory, if relevant |
|
18 patterns - patterns to find |
|
19 include - patterns to include |
|
20 exclude - patterns to exclude |
|
21 default - if a pattern in names has no explicit type, assume this one |
|
22 exact - patterns are actually literals |
|
23 |
|
24 a pattern is one of: |
|
25 'glob:<glob>' - a glob relative to cwd |
|
26 're:<regexp>' - a regular expression |
|
27 'path:<path>' - a path relative to canonroot |
|
28 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs) |
|
29 'relpath:<path>' - a path relative to cwd |
|
30 'relre:<regexp>' - a regexp that needn't match the start of a name |
|
31 '<something>' - a pattern of the specified default type |
|
32 """ |
|
33 |
12 self._root = root |
34 self._root = root |
13 self._cwd = cwd |
35 self._cwd = cwd |
14 self._files = files |
36 self._files = [] |
15 self._fmap = set(files) |
37 self._anypats = bool(include or exclude) |
16 self.matchfn = mf |
38 |
17 self._anypats = ap |
39 if include: |
|
40 im = _buildmatch(_normalize(include, 'glob', root, cwd), '(?:/|$)') |
|
41 if exclude: |
|
42 em = _buildmatch(_normalize(exclude, 'glob', root, cwd), '(?:/|$)') |
|
43 if exact: |
|
44 self._files = patterns |
|
45 pm = self.exact |
|
46 elif patterns: |
|
47 pats = _normalize(patterns, default, root, cwd) |
|
48 self._files = _roots(pats) |
|
49 self._anypats = self._anypats or _anypats(pats) |
|
50 pm = _buildmatch(pats, '$') |
|
51 |
|
52 if patterns or exact: |
|
53 if include: |
|
54 if exclude: |
|
55 m = lambda f: im(f) and not em(f) and pm(f) |
|
56 else: |
|
57 m = lambda f: im(f) and pm(f) |
|
58 else: |
|
59 if exclude: |
|
60 m = lambda f: not em(f) and pm(f) |
|
61 else: |
|
62 m = pm |
|
63 else: |
|
64 if include: |
|
65 if exclude: |
|
66 m = lambda f: im(f) and not em(f) |
|
67 else: |
|
68 m = im |
|
69 else: |
|
70 if exclude: |
|
71 m = lambda f: not em(f) |
|
72 else: |
|
73 m = lambda f: True |
|
74 |
|
75 self.matchfn = m |
|
76 self._fmap = set(self._files) |
|
77 |
18 def __call__(self, fn): |
78 def __call__(self, fn): |
19 return self.matchfn(fn) |
79 return self.matchfn(fn) |
20 def __iter__(self): |
80 def __iter__(self): |
21 for f in self._files: |
81 for f in self._files: |
22 yield f |
82 yield f |
32 return util.pathto(self._root, self._cwd, f) |
92 return util.pathto(self._root, self._cwd, f) |
33 def files(self): |
93 def files(self): |
34 return self._files |
94 return self._files |
35 def anypats(self): |
95 def anypats(self): |
36 return self._anypats |
96 return self._anypats |
37 |
|
38 class match(_match): |
|
39 def __init__(self, root, cwd, patterns, include=[], exclude=[], |
|
40 default='glob', exact=False): |
|
41 """build an object to match a set of file patterns |
|
42 |
|
43 arguments: |
|
44 root - the canonical root of the tree you're matching against |
|
45 cwd - the current working directory, if relevant |
|
46 patterns - patterns to find |
|
47 include - patterns to include |
|
48 exclude - patterns to exclude |
|
49 default - if a pattern in names has no explicit type, assume this one |
|
50 exact - patterns are actually literals |
|
51 |
|
52 a pattern is one of: |
|
53 'glob:<glob>' - a glob relative to cwd |
|
54 're:<regexp>' - a regular expression |
|
55 'path:<path>' - a path relative to canonroot |
|
56 'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs) |
|
57 'relpath:<path>' - a path relative to cwd |
|
58 'relre:<regexp>' - a regexp that doesn't have to match the start of a name |
|
59 '<something>' - one of the cases above, selected by the dflt_pat argument |
|
60 """ |
|
61 |
|
62 roots = [] |
|
63 anypats = bool(include or exclude) |
|
64 |
|
65 if include: |
|
66 im = _buildmatch(_normalize(include, 'glob', root, cwd), '(?:/|$)') |
|
67 if exclude: |
|
68 em = _buildmatch(_normalize(exclude, 'glob', root, cwd), '(?:/|$)') |
|
69 if exact: |
|
70 roots = patterns |
|
71 pm = self.exact |
|
72 elif patterns: |
|
73 pats = _normalize(patterns, default, root, cwd) |
|
74 roots = _roots(pats) |
|
75 anypats = anypats or _anypats(pats) |
|
76 pm = _buildmatch(pats, '$') |
|
77 |
|
78 if patterns or exact: |
|
79 if include: |
|
80 if exclude: |
|
81 m = lambda f: im(f) and not em(f) and pm(f) |
|
82 else: |
|
83 m = lambda f: im(f) and pm(f) |
|
84 else: |
|
85 if exclude: |
|
86 m = lambda f: not em(f) and pm(f) |
|
87 else: |
|
88 m = pm |
|
89 else: |
|
90 if include: |
|
91 if exclude: |
|
92 m = lambda f: im(f) and not em(f) |
|
93 else: |
|
94 m = im |
|
95 else: |
|
96 if exclude: |
|
97 m = lambda f: not em(f) |
|
98 else: |
|
99 m = lambda f: True |
|
100 |
|
101 _match.__init__(self, root, cwd, roots, m, anypats) |
|
102 |
97 |
103 class exact(match): |
98 class exact(match): |
104 def __init__(self, root, cwd, files): |
99 def __init__(self, root, cwd, files): |
105 match.__init__(self, root, cwd, files, exact = True) |
100 match.__init__(self, root, cwd, files, exact = True) |
106 |
101 |