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