Show More
@@ -1603,6 +1603,10 def debugfileset(ui, repo, expr): | |||||
1603 | if ui.verbose: |
|
1603 | if ui.verbose: | |
1604 | tree = fileset.parse(expr)[0] |
|
1604 | tree = fileset.parse(expr)[0] | |
1605 | ui.note(tree, "\n") |
|
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 | @command('debugfsinfo', [], _('[PATH]')) |
|
1611 | @command('debugfsinfo', [], _('[PATH]')) | |
1608 | def debugfsinfo(ui, path = "."): |
|
1612 | def debugfsinfo(ui, path = "."): |
@@ -5,7 +5,7 | |||||
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 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | import parser, error |
|
8 | import parser, error, match | |
9 | from i18n import _ |
|
9 | from i18n import _ | |
10 |
|
10 | |||
11 | elements = { |
|
11 | elements = { | |
@@ -27,6 +27,8 elements = { | |||||
27 |
|
27 | |||
28 | keywords = set(['and', 'or', 'not']) |
|
28 | keywords = set(['and', 'or', 'not']) | |
29 |
|
29 | |||
|
30 | globchars = ".*{}[]?/\\" | |||
|
31 | ||||
30 | def tokenize(program): |
|
32 | def tokenize(program): | |
31 | pos, l = 0, len(program) |
|
33 | pos, l = 0, len(program) | |
32 | while pos < l: |
|
34 | while pos < l: | |
@@ -56,13 +58,13 def tokenize(program): | |||||
56 | pos += 1 |
|
58 | pos += 1 | |
57 | else: |
|
59 | else: | |
58 | raise error.ParseError(_("unterminated string"), s) |
|
60 | raise error.ParseError(_("unterminated string"), s) | |
59 |
elif c.isalnum() or c in |
|
61 | elif c.isalnum() or c in globchars or ord(c) > 127: | |
60 | # gather up a symbol/keyword |
|
62 | # gather up a symbol/keyword | |
61 | s = pos |
|
63 | s = pos | |
62 | pos += 1 |
|
64 | pos += 1 | |
63 | while pos < l: # find end of symbol |
|
65 | while pos < l: # find end of symbol | |
64 | d = program[pos] |
|
66 | d = program[pos] | |
65 |
if not (d.isalnum() or d in |
|
67 | if not (d.isalnum() or d in globchars or ord(d) > 127): | |
66 | break |
|
68 | break | |
67 | pos += 1 |
|
69 | pos += 1 | |
68 | sym = program[s:pos] |
|
70 | sym = program[s:pos] | |
@@ -78,3 +80,63 def tokenize(program): | |||||
78 |
|
80 | |||
79 | parse = parser.parser(tokenize, elements).parse |
|
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