##// END OF EJS Templates
fileset: basic pattern and boolean support...
Matt Mackall -
r14551:68d814a3 default
parent child Browse files
Show More
@@ -1603,6 +1603,10 b' def debugfileset(ui, repo, expr):'
1603 1603 if ui.verbose:
1604 1604 tree = fileset.parse(expr)[0]
1605 1605 ui.note(tree, "\n")
1606 matcher = lambda x: scmutil.match(repo, x, default='glob')
1607
1608 for f in fileset.getfileset(repo[None], matcher, expr):
1609 ui.write("%s\n" % f)
1606 1610
1607 1611 @command('debugfsinfo', [], _('[PATH]'))
1608 1612 def debugfsinfo(ui, path = "."):
@@ -5,7 +5,7 b''
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 import parser, error
8 import parser, error, match
9 9 from i18n import _
10 10
11 11 elements = {
@@ -27,6 +27,8 b' elements = {'
27 27
28 28 keywords = set(['and', 'or', 'not'])
29 29
30 globchars = ".*{}[]?/\\"
31
30 32 def tokenize(program):
31 33 pos, l = 0, len(program)
32 34 while pos < l:
@@ -56,13 +58,13 b' def tokenize(program):'
56 58 pos += 1
57 59 else:
58 60 raise error.ParseError(_("unterminated string"), s)
59 elif c.isalnum() or c in '.*{}[]?' or ord(c) > 127:
61 elif c.isalnum() or c in globchars or ord(c) > 127:
60 62 # gather up a symbol/keyword
61 63 s = pos
62 64 pos += 1
63 65 while pos < l: # find end of symbol
64 66 d = program[pos]
65 if not (d.isalnum() or d in ".*{}[]?," or ord(d) > 127):
67 if not (d.isalnum() or d in globchars or ord(d) > 127):
66 68 break
67 69 pos += 1
68 70 sym = program[s:pos]
@@ -78,3 +80,63 b' def tokenize(program):'
78 80
79 81 parse = parser.parser(tokenize, elements).parse
80 82
83 def getstring(x, err):
84 if x and (x[0] == 'string' or x[0] == 'symbol'):
85 return x[1]
86 raise error.ParseError(err)
87
88 def getset(mctx, x):
89 if not x:
90 raise error.ParseError(_("missing argument"))
91 return methods[x[0]](mctx, *x[1:])
92
93 def stringset(mctx, x):
94 m = mctx.matcher([x])
95 return [f for f in mctx.subset if m(f)]
96
97 def andset(mctx, x, y):
98 return getset(mctx.narrow(getset(mctx, x)), y)
99
100 def orset(mctx, x, y):
101 # needs optimizing
102 xl = getset(mctx, x)
103 yl = getset(mctx, y)
104 return xl + [f for f in yl if f not in xl]
105
106 def notset(mctx, x):
107 s = set(getset(mctx, x))
108 return [r for r in mctx.subset if r not in s]
109
110 def listset(mctx, a, b):
111 raise error.ParseError(_("can't use a list in this context"))
112
113 methods = {
114 'string': stringset,
115 'symbol': stringset,
116 'and': andset,
117 'or': orset,
118 'list': listset,
119 'group': getset,
120 'not': notset
121 }
122
123 class matchctx(object):
124 def __init__(self, ctx, matchfn, subset=None):
125 self.ctx = ctx
126 self.matchfn = matchfn
127 self.subset = subset
128 if subset is None:
129 self.subset = ctx.walk(matchfn([])) # optimize this later
130 def matcher(self, pattern):
131 return self.matchfn(pattern)
132 def filter(self, files):
133 return [f for f in files if f in self.subset]
134 def narrow(self, files):
135 return matchctx(self.ctx, self.matchfn,
136 self.filter(files))
137
138 def getfileset(ctx, matchfn, expr):
139 tree, pos = parse(expr)
140 if (pos != len(expr)):
141 raise error.ParseError("invalid token", pos)
142 return getset(matchctx(ctx, matchfn), tree)
General Comments 0
You need to be logged in to leave comments. Login now