197 """``binary()`` |
197 """``binary()`` |
198 File that appears to be binary (contains NUL bytes). |
198 File that appears to be binary (contains NUL bytes). |
199 """ |
199 """ |
200 # i18n: "binary" is a keyword |
200 # i18n: "binary" is a keyword |
201 getargs(x, 0, 0, _("binary takes no arguments")) |
201 getargs(x, 0, 0, _("binary takes no arguments")) |
202 return [f for f in mctx.subset if util.binary(mctx.ctx[f].data())] |
202 return [f for f in mctx.existing() if util.binary(mctx.ctx[f].data())] |
203 |
203 |
204 def exec_(mctx, x): |
204 def exec_(mctx, x): |
205 """``exec()`` |
205 """``exec()`` |
206 File that is marked as executable. |
206 File that is marked as executable. |
207 """ |
207 """ |
208 # i18n: "exec" is a keyword |
208 # i18n: "exec" is a keyword |
209 getargs(x, 0, 0, _("exec takes no arguments")) |
209 getargs(x, 0, 0, _("exec takes no arguments")) |
210 return [f for f in mctx.subset if mctx.ctx.flags(f) == 'x'] |
210 return [f for f in mctx.existing() if mctx.ctx.flags(f) == 'x'] |
211 |
211 |
212 def symlink(mctx, x): |
212 def symlink(mctx, x): |
213 """``symlink()`` |
213 """``symlink()`` |
214 File that is marked as a symlink. |
214 File that is marked as a symlink. |
215 """ |
215 """ |
216 # i18n: "symlink" is a keyword |
216 # i18n: "symlink" is a keyword |
217 getargs(x, 0, 0, _("symlink takes no arguments")) |
217 getargs(x, 0, 0, _("symlink takes no arguments")) |
218 return [f for f in mctx.subset if mctx.ctx.flags(f) == 'l'] |
218 return [f for f in mctx.existing() if mctx.ctx.flags(f) == 'l'] |
219 |
219 |
220 def resolved(mctx, x): |
220 def resolved(mctx, x): |
221 """``resolved()`` |
221 """``resolved()`` |
222 File that is marked resolved according to the resolve state. |
222 File that is marked resolved according to the resolve state. |
223 """ |
223 """ |
251 """``grep(regex)`` |
251 """``grep(regex)`` |
252 File contains the given regular expression. |
252 File contains the given regular expression. |
253 """ |
253 """ |
254 pat = getstring(x, _("grep requires a pattern")) |
254 pat = getstring(x, _("grep requires a pattern")) |
255 r = re.compile(pat) |
255 r = re.compile(pat) |
256 return [f for f in mctx.subset if r.search(mctx.ctx[f].data())] |
256 return [f for f in mctx.existing() if r.search(mctx.ctx[f].data())] |
257 |
257 |
258 _units = dict(k=2**10, K=2**10, kB=2**10, KB=2**10, |
258 _units = dict(k=2**10, K=2**10, kB=2**10, KB=2**10, |
259 M=2**20, MB=2**20, G=2**30, GB=2**30) |
259 M=2**20, MB=2**20, G=2**30, GB=2**30) |
260 |
260 |
261 def _sizetoint(s): |
261 def _sizetoint(s): |
318 b = _sizetomax(expr) |
318 b = _sizetomax(expr) |
319 m = lambda x: x >= a and x <= b |
319 m = lambda x: x >= a and x <= b |
320 else: |
320 else: |
321 raise error.ParseError(_("couldn't parse size: %s") % expr) |
321 raise error.ParseError(_("couldn't parse size: %s") % expr) |
322 |
322 |
323 return [f for f in mctx.subset if m(mctx.ctx[f].size())] |
323 return [f for f in mctx.existing() if m(mctx.ctx[f].size())] |
324 |
324 |
325 def encoding(mctx, x): |
325 def encoding(mctx, x): |
326 """``encoding(name)`` |
326 """``encoding(name)`` |
327 File can be successfully decoded with the given character |
327 File can be successfully decoded with the given character |
328 encoding. May not be useful for encodings other than ASCII and |
328 encoding. May not be useful for encodings other than ASCII and |
331 |
331 |
332 # i18n: "encoding" is a keyword |
332 # i18n: "encoding" is a keyword |
333 enc = getstring(x, _("encoding requires an encoding name")) |
333 enc = getstring(x, _("encoding requires an encoding name")) |
334 |
334 |
335 s = [] |
335 s = [] |
336 for f in mctx.subset: |
336 for f in mctx.existing(): |
337 d = mctx.ctx[f].data() |
337 d = mctx.ctx[f].data() |
338 try: |
338 try: |
339 d.decode(enc) |
339 d.decode(enc) |
340 except LookupError: |
340 except LookupError: |
341 raise util.Abort(_("unknown encoding '%s'") % enc) |
341 raise util.Abort(_("unknown encoding '%s'") % enc) |
398 return self._status |
398 return self._status |
399 def matcher(self, patterns): |
399 def matcher(self, patterns): |
400 return self.ctx.match(patterns) |
400 return self.ctx.match(patterns) |
401 def filter(self, files): |
401 def filter(self, files): |
402 return [f for f in files if f in self.subset] |
402 return [f for f in files if f in self.subset] |
|
403 def existing(self): |
|
404 return (f for f in self.subset if f in self.ctx) |
403 def narrow(self, files): |
405 def narrow(self, files): |
404 return matchctx(self.ctx, self.filter(files), self._status) |
406 return matchctx(self.ctx, self.filter(files), self._status) |
405 |
407 |
406 def _intree(funcs, tree): |
408 def _intree(funcs, tree): |
407 if isinstance(tree, tuple): |
409 if isinstance(tree, tuple): |