| 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) |