15 |
15 |
16 def _compile(tree): |
16 def _compile(tree): |
17 if not tree: |
17 if not tree: |
18 raise error.ParseError(_("missing argument")) |
18 raise error.ParseError(_("missing argument")) |
19 op = tree[0] |
19 op = tree[0] |
20 if op == 'symbol': |
20 if op in {'symbol', 'string'}: |
21 name = fileset.getstring(tree, _('invalid file pattern')) |
21 name = fileset.getstring(tree, _('invalid file pattern')) |
22 if name.startswith('**'): # file extension test, ex. "**.tar.gz" |
22 if name.startswith('**'): # file extension test, ex. "**.tar.gz" |
23 ext = name[2:] |
23 ext = name[2:] |
24 for c in ext: |
24 for c in ext: |
25 if c in '*{}[]?/\\': |
25 if c in '*{}[]?/\\': |
26 raise error.ParseError(_('reserved character: %s') % c) |
26 raise error.ParseError(_('reserved character: %s') % c) |
27 return lambda n, s: n.endswith(ext) |
27 return lambda n, s: n.endswith(ext) |
28 raise error.ParseError(_('invalid symbol: %s') % name) |
|
29 elif op == 'string': |
|
30 # TODO: teach fileset about 'path:', so that this can be a symbol and |
28 # TODO: teach fileset about 'path:', so that this can be a symbol and |
31 # not require quoting. |
29 # not require quoting. |
32 name = fileset.getstring(tree, _('invalid path literal')) |
30 elif name.startswith('path:'): # directory or full path test |
33 if name.startswith('path:'): # directory or full path test |
|
34 p = name[5:] # prefix |
31 p = name[5:] # prefix |
35 pl = len(p) |
32 pl = len(p) |
36 f = lambda n, s: n.startswith(p) and (len(n) == pl or n[pl] == '/') |
33 f = lambda n, s: n.startswith(p) and (len(n) == pl or n[pl] == '/') |
37 return f |
34 return f |
38 raise error.ParseError(_("invalid string"), |
35 raise error.ParseError(_("unsupported file pattern"), |
39 hint=_('paths must be prefixed with "path:"')) |
36 hint=_('paths must be prefixed with "path:"')) |
40 elif op == 'or': |
37 elif op == 'or': |
41 func1 = _compile(tree[1]) |
38 func1 = _compile(tree[1]) |
42 func2 = _compile(tree[2]) |
39 func2 = _compile(tree[2]) |
43 return lambda n, s: func1(n, s) or func2(n, s) |
40 return lambda n, s: func1(n, s) or func2(n, s) |