mercurial/minifileset.py
changeset 43077 687b865b95ad
parent 43075 57875cf423c9
child 48875 6000f5b25c9b
equal deleted inserted replaced
43076:2372284d9457 43077:687b865b95ad
    16 )
    16 )
    17 
    17 
    18 
    18 
    19 def _sizep(x):
    19 def _sizep(x):
    20     # i18n: "size" is a keyword
    20     # i18n: "size" is a keyword
    21     expr = filesetlang.getstring(x, _("size requires an expression"))
    21     expr = filesetlang.getstring(x, _(b"size requires an expression"))
    22     return fileset.sizematcher(expr)
    22     return fileset.sizematcher(expr)
    23 
    23 
    24 
    24 
    25 def _compile(tree):
    25 def _compile(tree):
    26     if not tree:
    26     if not tree:
    27         raise error.ParseError(_("missing argument"))
    27         raise error.ParseError(_(b"missing argument"))
    28     op = tree[0]
    28     op = tree[0]
    29     if op == 'withstatus':
    29     if op == b'withstatus':
    30         return _compile(tree[1])
    30         return _compile(tree[1])
    31     elif op in {'symbol', 'string', 'kindpat'}:
    31     elif op in {b'symbol', b'string', b'kindpat'}:
    32         name = filesetlang.getpattern(tree, {'path'}, _('invalid file pattern'))
    32         name = filesetlang.getpattern(
    33         if name.startswith('**'):  # file extension test, ex. "**.tar.gz"
    33             tree, {b'path'}, _(b'invalid file pattern')
       
    34         )
       
    35         if name.startswith(b'**'):  # file extension test, ex. "**.tar.gz"
    34             ext = name[2:]
    36             ext = name[2:]
    35             for c in pycompat.bytestr(ext):
    37             for c in pycompat.bytestr(ext):
    36                 if c in '*{}[]?/\\':
    38                 if c in b'*{}[]?/\\':
    37                     raise error.ParseError(_('reserved character: %s') % c)
    39                     raise error.ParseError(_(b'reserved character: %s') % c)
    38             return lambda n, s: n.endswith(ext)
    40             return lambda n, s: n.endswith(ext)
    39         elif name.startswith('path:'):  # directory or full path test
    41         elif name.startswith(b'path:'):  # directory or full path test
    40             p = name[5:]  # prefix
    42             p = name[5:]  # prefix
    41             pl = len(p)
    43             pl = len(p)
    42             f = lambda n, s: n.startswith(p) and (
    44             f = lambda n, s: n.startswith(p) and (
    43                 len(n) == pl or n[pl : pl + 1] == '/'
    45                 len(n) == pl or n[pl : pl + 1] == b'/'
    44             )
    46             )
    45             return f
    47             return f
    46         raise error.ParseError(
    48         raise error.ParseError(
    47             _("unsupported file pattern: %s") % name,
    49             _(b"unsupported file pattern: %s") % name,
    48             hint=_('paths must be prefixed with "path:"'),
    50             hint=_(b'paths must be prefixed with "path:"'),
    49         )
    51         )
    50     elif op in {'or', 'patterns'}:
    52     elif op in {b'or', b'patterns'}:
    51         funcs = [_compile(x) for x in tree[1:]]
    53         funcs = [_compile(x) for x in tree[1:]]
    52         return lambda n, s: any(f(n, s) for f in funcs)
    54         return lambda n, s: any(f(n, s) for f in funcs)
    53     elif op == 'and':
    55     elif op == b'and':
    54         func1 = _compile(tree[1])
    56         func1 = _compile(tree[1])
    55         func2 = _compile(tree[2])
    57         func2 = _compile(tree[2])
    56         return lambda n, s: func1(n, s) and func2(n, s)
    58         return lambda n, s: func1(n, s) and func2(n, s)
    57     elif op == 'not':
    59     elif op == b'not':
    58         return lambda n, s: not _compile(tree[1])(n, s)
    60         return lambda n, s: not _compile(tree[1])(n, s)
    59     elif op == 'func':
    61     elif op == b'func':
    60         symbols = {
    62         symbols = {
    61             'all': lambda n, s: True,
    63             b'all': lambda n, s: True,
    62             'none': lambda n, s: False,
    64             b'none': lambda n, s: False,
    63             'size': lambda n, s: _sizep(tree[2])(s),
    65             b'size': lambda n, s: _sizep(tree[2])(s),
    64         }
    66         }
    65 
    67 
    66         name = filesetlang.getsymbol(tree[1])
    68         name = filesetlang.getsymbol(tree[1])
    67         if name in symbols:
    69         if name in symbols:
    68             return symbols[name]
    70             return symbols[name]
    69 
    71 
    70         raise error.UnknownIdentifier(name, symbols.keys())
    72         raise error.UnknownIdentifier(name, symbols.keys())
    71     elif op == 'minus':  # equivalent to 'x and not y'
    73     elif op == b'minus':  # equivalent to 'x and not y'
    72         func1 = _compile(tree[1])
    74         func1 = _compile(tree[1])
    73         func2 = _compile(tree[2])
    75         func2 = _compile(tree[2])
    74         return lambda n, s: func1(n, s) and not func2(n, s)
    76         return lambda n, s: func1(n, s) and not func2(n, s)
    75     elif op == 'list':
    77     elif op == b'list':
    76         raise error.ParseError(
    78         raise error.ParseError(
    77             _("can't use a list in this context"),
    79             _(b"can't use a list in this context"),
    78             hint=_('see \'hg help "filesets.x or y"\''),
    80             hint=_(b'see \'hg help "filesets.x or y"\''),
    79         )
    81         )
    80     raise error.ProgrammingError('illegal tree: %r' % (tree,))
    82     raise error.ProgrammingError(b'illegal tree: %r' % (tree,))
    81 
    83 
    82 
    84 
    83 def compile(text):
    85 def compile(text):
    84     """generate a function (path, size) -> bool from filter specification.
    86     """generate a function (path, size) -> bool from filter specification.
    85 
    87