• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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