bpo-45952: Get the C analyzer tool working again. by ericsnowcurrently · Pull Request #29882 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 14 additions & 62 deletions Tools/c-analyzer/TODO
34 changes: 30 additions & 4 deletions Tools/c-analyzer/c_parser/__init__.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
from c_common.fsutil import match_glob as _match_glob
from .parser import parse as _parse
from .preprocessor import get_preprocessor as _get_preprocessor


def parse_file(filename, *,
match_kind=None,
get_file_preprocessor=None,
file_maxsizes=None,
):
if get_file_preprocessor is None:
get_file_preprocessor = _get_preprocessor()
yield from _parse_file(filename, match_kind, get_file_preprocessor)
yield from _parse_file(
filename, match_kind, get_file_preprocessor, file_maxsizes)


def parse_files(filenames, *,
match_kind=None,
get_file_preprocessor=None,
file_maxsizes=None,
):
if get_file_preprocessor is None:
get_file_preprocessor = _get_preprocessor()
for filename in filenames:
yield from _parse_file(filename, match_kind, get_file_preprocessor)
yield from _parse_file(
filename, match_kind, get_file_preprocessor, file_maxsizes)


def _parse_file(filename, match_kind, get_file_preprocessor):
def _parse_file(filename, match_kind, get_file_preprocessor, maxsizes):
srckwargs = {}
maxsize = _resolve_max_size(filename, maxsizes)
if maxsize:
srckwargs['maxtext'], srckwargs['maxlines'] = maxsize

# Preprocess the file.
preprocess = get_file_preprocessor(filename)
preprocessed = preprocess()
Expand All @@ -30,14 +40,30 @@ def _parse_file(filename, match_kind, get_file_preprocessor):

# Parse the lines.
srclines = ((l.file, l.data) for l in preprocessed if l.kind == 'source')
for item in _parse(srclines):
for item in _parse(srclines, **srckwargs):
if match_kind is not None and not match_kind(item.kind):
continue
if not item.filename:
raise NotImplementedError(repr(item))
yield item


def _resolve_max_size(filename, maxsizes):
for pattern, maxsize in (maxsizes.items() if maxsizes else ()):
if _match_glob(filename, pattern):
break
else:
return None
if not maxsize:
return None, None
maxtext, maxlines = maxsize
if maxtext is not None:
maxtext = int(maxtext)
if maxlines is not None:
maxlines = int(maxlines)
return maxtext, maxlines


def parse_signature(text):
raise NotImplementedError

Expand Down
14 changes: 8 additions & 6 deletions Tools/c-analyzer/c_parser/parser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,12 @@
from ._info import SourceInfo


def parse(srclines):
def parse(srclines, **srckwargs):
if isinstance(srclines, str): # a filename
raise NotImplementedError

anon_name = anonymous_names()
for result in _parse(srclines, anon_name):
for result in _parse(srclines, anon_name, **srckwargs):
yield ParsedItem.from_raw(result)


Expand All @@ -152,17 +152,19 @@ def anon_name(prefix='anon-'):
_logger = logging.getLogger(__name__)


def _parse(srclines, anon_name):
def _parse(srclines, anon_name, **srckwargs):
from ._global import parse_globals

source = _iter_source(srclines)
#source = _iter_source(srclines, showtext=True)
source = _iter_source(srclines, **srckwargs)
for result in parse_globals(source, anon_name):
# XXX Handle blocks here instead of in parse_globals().
yield result


def _iter_source(lines, *, maxtext=20_000, maxlines=700, showtext=False):
# We use defaults that cover most files. Files with bigger declarations
# are covered elsewhere (MAX_SIZES in cpython/_parser.py).

def _iter_source(lines, *, maxtext=10_000, maxlines=200, showtext=False):
maxtext = maxtext if maxtext and maxtext > 0 else None
maxlines = maxlines if maxlines and maxlines > 0 else None
filestack = []
Expand Down
2 changes: 1 addition & 1 deletion Tools/c-analyzer/c_parser/preprocessor/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def add_common_cli(parser, *, get_preprocessor=_get_preprocessor):
def process_args(args, *, argv):
ns = vars(args)

process_fail_arg(args, argv)
process_fail_arg(args, argv=argv)
ignore_exc = ns.pop('ignore_exc')
# We later pass ignore_exc to _get_preprocessor().

Expand Down
3 changes: 3 additions & 0 deletions Tools/c-analyzer/cpython/__main__.py
Loading