diff options
Diffstat (limited to 'Tools/c-analyzer/cpython/_files.py')
-rw-r--r-- | Tools/c-analyzer/cpython/_files.py | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/Tools/c-analyzer/cpython/_files.py b/Tools/c-analyzer/cpython/_files.py new file mode 100644 index 0000000..3e39788 --- /dev/null +++ b/Tools/c-analyzer/cpython/_files.py @@ -0,0 +1,69 @@ +import os.path + +from c_common.fsutil import expand_filenames, iter_files_by_suffix +from . import REPO_ROOT, INCLUDE_DIRS, SOURCE_DIRS + + +GLOBS = [ + 'Include/*.h', + 'Include/internal/*.h', + 'Modules/**/*.h', + 'Modules/**/*.c', + 'Objects/**/*.h', + 'Objects/**/*.c', + 'Python/**/*.h', + 'Parser/**/*.c', + 'Python/**/*.h', + 'Parser/**/*.c', +] +LEVEL_GLOBS = { + 'stable': 'Include/*.h', + 'cpython': 'Include/cpython/*.h', + 'internal': 'Include/internal/*.h', +} + + +def resolve_filename(filename): + orig = filename + filename = os.path.normcase(os.path.normpath(filename)) + if os.path.isabs(filename): + if os.path.relpath(filename, REPO_ROOT).startswith('.'): + raise Exception(f'{orig!r} is outside the repo ({REPO_ROOT})') + return filename + else: + return os.path.join(REPO_ROOT, filename) + + +def iter_filenames(*, search=False): + if search: + yield from iter_files_by_suffix(INCLUDE_DIRS, ('.h',)) + yield from iter_files_by_suffix(SOURCE_DIRS, ('.c',)) + else: + globs = (os.path.join(REPO_ROOT, file) for file in GLOBS) + yield from expand_filenames(globs) + + +def iter_header_files(filenames=None, *, levels=None): + if not filenames: + if levels: + levels = set(levels) + if 'private' in levels: + levels.add('stable') + levels.add('cpython') + for level, glob in LEVEL_GLOBS.items(): + if level in levels: + yield from expand_filenames([glob]) + else: + yield from iter_files_by_suffix(INCLUDE_DIRS, ('.h',)) + return + + for filename in filenames: + orig = filename + filename = resolve_filename(filename) + if filename.endswith(os.path.sep): + yield from iter_files_by_suffix(INCLUDE_DIRS, ('.h',)) + elif filename.endswith('.h'): + yield filename + else: + # XXX Log it and continue instead? + raise ValueError(f'expected .h file, got {orig!r}') |