• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""
2Generic dylib path manipulation
3"""
4
5import re
6
7__all__ = ['dylib_info']
8
9DYLIB_RE = re.compile(r"""(?x)
10(?P<location>^.*)(?:^|/)
11(?P<name>
12    (?P<shortname>\w+?)
13    (?:\.(?P<version>[^._]+))?
14    (?:_(?P<suffix>[^._]+))?
15    \.dylib$
16)
17""")
18
19def dylib_info(filename):
20    """
21    A dylib name can take one of the following four forms:
22        Location/Name.SomeVersion_Suffix.dylib
23        Location/Name.SomeVersion.dylib
24        Location/Name_Suffix.dylib
25        Location/Name.dylib
26
27    returns None if not found or a mapping equivalent to:
28        dict(
29            location='Location',
30            name='Name.SomeVersion_Suffix.dylib',
31            shortname='Name',
32            version='SomeVersion',
33            suffix='Suffix',
34        )
35
36    Note that SomeVersion and Suffix are optional and may be None
37    if not present.
38    """
39    is_dylib = DYLIB_RE.match(filename)
40    if not is_dylib:
41        return None
42    return is_dylib.groupdict()
43
44
45def test_dylib_info():
46    def d(location=None, name=None, shortname=None, version=None, suffix=None):
47        return dict(
48            location=location,
49            name=name,
50            shortname=shortname,
51            version=version,
52            suffix=suffix
53        )
54    assert dylib_info('completely/invalid') is None
55    assert dylib_info('completely/invalide_debug') is None
56    assert dylib_info('P/Foo.dylib') == d('P', 'Foo.dylib', 'Foo')
57    assert dylib_info('P/Foo_debug.dylib') == d('P', 'Foo_debug.dylib', 'Foo', suffix='debug')
58    assert dylib_info('P/Foo.A.dylib') == d('P', 'Foo.A.dylib', 'Foo', 'A')
59    assert dylib_info('P/Foo_debug.A.dylib') == d('P', 'Foo_debug.A.dylib', 'Foo_debug', 'A')
60    assert dylib_info('P/Foo.A_debug.dylib') == d('P', 'Foo.A_debug.dylib', 'Foo', 'A', 'debug')
61
62if __name__ == '__main__':
63    test_dylib_info()
64