1import os.path 2 3from c_analyzer.common import files 4from c_analyzer.common.info import UNKNOWN, ID 5from c_analyzer.variables import find as _common 6 7from . import SOURCE_DIRS, PYTHON, REPO_ROOT 8from .known import ( 9 from_file as known_from_file, 10 DATA_FILE as KNOWN_FILE, 11 ) 12from .supported import ( 13 ignored_from_file, IGNORED_FILE, is_supported, _is_object, 14 ) 15 16# XXX need tests: 17# * vars_from_binary() 18# * vars_from_source() 19# * supported_vars() 20 21 22def _handle_id(filename, funcname, name, *, 23 _relpath=os.path.relpath, 24 ): 25 filename = _relpath(filename, REPO_ROOT) 26 return ID(filename, funcname, name) 27 28 29def vars_from_binary(*, 30 known=KNOWN_FILE, 31 _known_from_file=known_from_file, 32 _iter_files=files.iter_files_by_suffix, 33 _iter_vars=_common.vars_from_binary, 34 ): 35 """Yield a Variable for each found Symbol. 36 37 Details are filled in from the given "known" variables and types. 38 """ 39 if isinstance(known, str): 40 known = _known_from_file(known) 41 dirnames = SOURCE_DIRS 42 suffixes = ('.c',) 43 filenames = _iter_files(dirnames, suffixes) 44 # XXX For now we only use known variables (no source lookup). 45 filenames = None 46 yield from _iter_vars(PYTHON, 47 known=known, 48 filenames=filenames, 49 handle_id=_handle_id, 50 check_filename=(lambda n: True), 51 ) 52 53 54def vars_from_source(*, 55 preprocessed=None, 56 known=KNOWN_FILE, 57 _known_from_file=known_from_file, 58 _iter_files=files.iter_files_by_suffix, 59 _iter_vars=_common.vars_from_source, 60 ): 61 """Yield a Variable for each declaration in the raw source code. 62 63 Details are filled in from the given "known" variables and types. 64 """ 65 if isinstance(known, str): 66 known = _known_from_file(known) 67 dirnames = SOURCE_DIRS 68 suffixes = ('.c',) 69 filenames = _iter_files(dirnames, suffixes) 70 yield from _iter_vars(filenames, 71 preprocessed=preprocessed, 72 known=known, 73 handle_id=_handle_id, 74 ) 75 76 77def supported_vars(*, 78 known=KNOWN_FILE, 79 ignored=IGNORED_FILE, 80 skip_objects=False, 81 _known_from_file=known_from_file, 82 _ignored_from_file=ignored_from_file, 83 _iter_vars=vars_from_binary, 84 _is_supported=is_supported, 85 ): 86 """Yield (var, is supported) for each found variable.""" 87 if isinstance(known, str): 88 known = _known_from_file(known) 89 if isinstance(ignored, str): 90 ignored = _ignored_from_file(ignored) 91 92 for var in _iter_vars(known=known): 93 if not var.isglobal: 94 continue 95 elif var.vartype == UNKNOWN: 96 yield var, None 97 # XXX Support proper filters instead. 98 elif skip_objects and _is_object(found.vartype): 99 continue 100 else: 101 yield var, _is_supported(var, ignored, known) 102