You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
3.2 KiB
102 lines
3.2 KiB
import os.path
|
|
|
|
from c_analyzer.common import files
|
|
from c_analyzer.common.info import UNKNOWN, ID
|
|
from c_analyzer.variables import find as _common
|
|
|
|
from . import SOURCE_DIRS, PYTHON, REPO_ROOT
|
|
from .known import (
|
|
from_file as known_from_file,
|
|
DATA_FILE as KNOWN_FILE,
|
|
)
|
|
from .supported import (
|
|
ignored_from_file, IGNORED_FILE, is_supported, _is_object,
|
|
)
|
|
|
|
# XXX need tests:
|
|
# * vars_from_binary()
|
|
# * vars_from_source()
|
|
# * supported_vars()
|
|
|
|
|
|
def _handle_id(filename, funcname, name, *,
|
|
_relpath=os.path.relpath,
|
|
):
|
|
filename = _relpath(filename, REPO_ROOT)
|
|
return ID(filename, funcname, name)
|
|
|
|
|
|
def vars_from_binary(*,
|
|
known=KNOWN_FILE,
|
|
_known_from_file=known_from_file,
|
|
_iter_files=files.iter_files_by_suffix,
|
|
_iter_vars=_common.vars_from_binary,
|
|
):
|
|
"""Yield a Variable for each found Symbol.
|
|
|
|
Details are filled in from the given "known" variables and types.
|
|
"""
|
|
if isinstance(known, str):
|
|
known = _known_from_file(known)
|
|
dirnames = SOURCE_DIRS
|
|
suffixes = ('.c',)
|
|
filenames = _iter_files(dirnames, suffixes)
|
|
# XXX For now we only use known variables (no source lookup).
|
|
filenames = None
|
|
yield from _iter_vars(PYTHON,
|
|
known=known,
|
|
filenames=filenames,
|
|
handle_id=_handle_id,
|
|
check_filename=(lambda n: True),
|
|
)
|
|
|
|
|
|
def vars_from_source(*,
|
|
preprocessed=None,
|
|
known=KNOWN_FILE,
|
|
_known_from_file=known_from_file,
|
|
_iter_files=files.iter_files_by_suffix,
|
|
_iter_vars=_common.vars_from_source,
|
|
):
|
|
"""Yield a Variable for each declaration in the raw source code.
|
|
|
|
Details are filled in from the given "known" variables and types.
|
|
"""
|
|
if isinstance(known, str):
|
|
known = _known_from_file(known)
|
|
dirnames = SOURCE_DIRS
|
|
suffixes = ('.c',)
|
|
filenames = _iter_files(dirnames, suffixes)
|
|
yield from _iter_vars(filenames,
|
|
preprocessed=preprocessed,
|
|
known=known,
|
|
handle_id=_handle_id,
|
|
)
|
|
|
|
|
|
def supported_vars(*,
|
|
known=KNOWN_FILE,
|
|
ignored=IGNORED_FILE,
|
|
skip_objects=False,
|
|
_known_from_file=known_from_file,
|
|
_ignored_from_file=ignored_from_file,
|
|
_iter_vars=vars_from_binary,
|
|
_is_supported=is_supported,
|
|
):
|
|
"""Yield (var, is supported) for each found variable."""
|
|
if isinstance(known, str):
|
|
known = _known_from_file(known)
|
|
if isinstance(ignored, str):
|
|
ignored = _ignored_from_file(ignored)
|
|
|
|
for var in _iter_vars(known=known):
|
|
if not var.isglobal:
|
|
continue
|
|
elif var.vartype == UNKNOWN:
|
|
yield var, None
|
|
# XXX Support proper filters instead.
|
|
elif skip_objects and _is_object(found.vartype):
|
|
continue
|
|
else:
|
|
yield var, _is_supported(var, ignored, known)
|