diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2020-10-23 00:42:51 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-23 00:42:51 (GMT) |
commit | 345cd37abe324ad4f60f80e2c3133b8849e54e9b (patch) | |
tree | 5d965e662dca9dcac19e7eddd63a3d9d0b816fed /Tools/c-analyzer/c_analyzer/common/files.py | |
parent | ec388cfb4ede56dace2bb78851ff6f38fa2a6abe (diff) | |
download | cpython-345cd37abe324ad4f60f80e2c3133b8849e54e9b.zip cpython-345cd37abe324ad4f60f80e2c3133b8849e54e9b.tar.gz cpython-345cd37abe324ad4f60f80e2c3133b8849e54e9b.tar.bz2 |
bpo-36876: Fix the C analyzer tool. (GH-22841)
The original tool wasn't working right and it was simpler to create a new one, partially re-using some of the old code. At this point the tool runs properly on the master. (Try: ./python Tools/c-analyzer/c-analyzer.py analyze.) It take ~40 seconds on my machine to analyze the full CPython code base.
Note that we'll need to iron out some OS-specific stuff (e.g. preprocessor). We're okay though since this tool isn't used yet in our workflow. We will also need to verify the analysis results in detail before activating the check in CI, though I'm pretty sure it's close.
https://bugs.python.org/issue36876
Diffstat (limited to 'Tools/c-analyzer/c_analyzer/common/files.py')
-rw-r--r-- | Tools/c-analyzer/c_analyzer/common/files.py | 124 |
1 files changed, 0 insertions, 124 deletions
diff --git a/Tools/c-analyzer/c_analyzer/common/files.py b/Tools/c-analyzer/c_analyzer/common/files.py deleted file mode 100644 index a8a0447..0000000 --- a/Tools/c-analyzer/c_analyzer/common/files.py +++ /dev/null @@ -1,124 +0,0 @@ -import glob -import os -import os.path - -# XXX need tests: -# * walk_tree() -# * glob_tree() -# * iter_files_by_suffix() - - -C_SOURCE_SUFFIXES = ('.c', '.h') - - -def _walk_tree(root, *, - _walk=os.walk, - ): - # A wrapper around os.walk that resolves the filenames. - for parent, _, names in _walk(root): - for name in names: - yield os.path.join(parent, name) - - -def walk_tree(root, *, - suffix=None, - walk=_walk_tree, - ): - """Yield each file in the tree under the given directory name. - - If "suffix" is provided then only files with that suffix will - be included. - """ - if suffix and not isinstance(suffix, str): - raise ValueError('suffix must be a string') - - for filename in walk(root): - if suffix and not filename.endswith(suffix): - continue - yield filename - - -def glob_tree(root, *, - suffix=None, - _glob=glob.iglob, - _escape=glob.escape, - _join=os.path.join, - ): - """Yield each file in the tree under the given directory name. - - If "suffix" is provided then only files with that suffix will - be included. - """ - suffix = suffix or '' - if not isinstance(suffix, str): - raise ValueError('suffix must be a string') - - for filename in _glob(_join(_escape(root), f'*{suffix}')): - yield filename - for filename in _glob(_join(_escape(root), f'**/*{suffix}')): - yield filename - - -def iter_files(root, suffix=None, relparent=None, *, - get_files=None, - _glob=glob_tree, - _walk=walk_tree, - ): - """Yield each file in the tree under the given directory name. - - If "root" is a non-string iterable then do the same for each of - those trees. - - If "suffix" is provided then only files with that suffix will - be included. - - if "relparent" is provided then it is used to resolve each - filename as a relative path. - """ - if get_files is None: - get_files = os.walk - if not isinstance(root, str): - roots = root - for root in roots: - yield from iter_files(root, suffix, relparent, - get_files=get_files, - _glob=_glob, _walk=_walk) - return - - # Use the right "walk" function. - if get_files in (glob.glob, glob.iglob, glob_tree): - get_files = _glob - else: - _files = _walk_tree if get_files in (os.walk, walk_tree) else get_files - get_files = (lambda *a, **k: _walk(*a, walk=_files, **k)) - - # Handle a single suffix. - if suffix and not isinstance(suffix, str): - filenames = get_files(root) - suffix = tuple(suffix) - else: - filenames = get_files(root, suffix=suffix) - suffix = None - - for filename in filenames: - if suffix and not isinstance(suffix, str): # multiple suffixes - if not filename.endswith(suffix): - continue - if relparent: - filename = os.path.relpath(filename, relparent) - yield filename - - -def iter_files_by_suffix(root, suffixes, relparent=None, *, - walk=walk_tree, - _iter_files=iter_files, - ): - """Yield each file in the tree that has the given suffixes. - - Unlike iter_files(), the results are in the original suffix order. - """ - if isinstance(suffixes, str): - suffixes = [suffixes] - # XXX Ignore repeated suffixes? - for suffix in suffixes: - yield from _iter_files(root, suffix, relparent) |