• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import os.path
2
3from c_common.fsutil import expand_filenames, iter_files_by_suffix
4from . import REPO_ROOT, INCLUDE_DIRS, SOURCE_DIRS
5
6
7GLOBS = [
8    'Include/*.h',
9    # Technically, this is covered by "Include/*.h":
10    #'Include/cpython/*.h',
11    'Include/internal/*.h',
12    'Include/internal/mimalloc/**/*.h',
13    'Modules/**/*.h',
14    'Modules/**/*.c',
15    'Objects/**/*.h',
16    'Objects/**/*.c',
17    'Parser/**/*.h',
18    'Parser/**/*.c',
19    'Python/**/*.h',
20    'Python/**/*.c',
21]
22LEVEL_GLOBS = {
23    'stable': 'Include/*.h',
24    'cpython': 'Include/cpython/*.h',
25    'internal': 'Include/internal/*.h',
26}
27
28
29def resolve_filename(filename):
30    orig = filename
31    filename = os.path.normcase(os.path.normpath(filename))
32    if os.path.isabs(filename):
33        if os.path.relpath(filename, REPO_ROOT).startswith('.'):
34            raise Exception(f'{orig!r} is outside the repo ({REPO_ROOT})')
35        return filename
36    else:
37        return os.path.join(REPO_ROOT, filename)
38
39
40def iter_filenames(*, search=False):
41    if search:
42        yield from iter_files_by_suffix(INCLUDE_DIRS, ('.h',))
43        yield from iter_files_by_suffix(SOURCE_DIRS, ('.c',))
44    else:
45        globs = (os.path.join(REPO_ROOT, file) for file in GLOBS)
46        yield from expand_filenames(globs)
47
48
49def iter_header_files(filenames=None, *, levels=None):
50    if not filenames:
51        if levels:
52            levels = set(levels)
53            if 'private' in levels:
54                levels.add('stable')
55                levels.add('cpython')
56            for level, glob in LEVEL_GLOBS.items():
57                if level in levels:
58                    yield from expand_filenames([glob])
59        else:
60            yield from iter_files_by_suffix(INCLUDE_DIRS, ('.h',))
61        return
62
63    for filename in filenames:
64        orig = filename
65        filename = resolve_filename(filename)
66        if filename.endswith(os.path.sep):
67            yield from iter_files_by_suffix(INCLUDE_DIRS, ('.h',))
68        elif filename.endswith('.h'):
69            yield filename
70        else:
71            # XXX Log it and continue instead?
72            raise ValueError(f'expected .h file, got {orig!r}')
73