• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from c_parser import (
2    parse_files as _parse_files,
3)
4from c_parser.info import (
5    KIND,
6    TypeDeclaration,
7    resolve_parsed,
8)
9from c_parser.match import (
10    filter_by_kind,
11    group_by_kinds,
12)
13from . import (
14    analyze as _analyze,
15    datafiles as _datafiles,
16)
17from .info import Analysis
18
19
20def analyze(filenmes, **kwargs):
21    results = iter_analyis_results(filenames, **kwargs)
22    return Analysis.from_results(results)
23
24
25def iter_analysis_results(filenmes, *,
26                          known=None,
27                          **kwargs
28                          ):
29    decls = iter_decls(filenames, **kwargs)
30    yield from analyze_decls(decls, known)
31
32
33def iter_decls(filenames, *,
34               kinds=None,
35               parse_files=_parse_files,
36               **kwargs
37               ):
38    kinds = KIND.DECLS if kinds is None else (KIND.DECLS & set(kinds))
39    parse_files = parse_files or _parse_files
40
41    parsed = parse_files(filenames, **kwargs)
42    parsed = filter_by_kind(parsed, kinds)
43    for item in parsed:
44        yield resolve_parsed(item)
45
46
47def analyze_decls(decls, known, *,
48                  analyze_resolved=None,
49                  handle_unresolved=True,
50                  relroot=None,
51                  ):
52    knowntypes, knowntypespecs = _datafiles.get_known(
53        known,
54        handle_unresolved=handle_unresolved,
55        analyze_resolved=analyze_resolved,
56        relroot=relroot,
57    )
58
59    decls = list(decls)
60    collated = group_by_kinds(decls)
61
62    types = {decl: None for decl in collated['type']}
63    typespecs = _analyze.get_typespecs(types)
64
65    def analyze_decl(decl):
66        return _analyze.analyze_decl(
67            decl,
68            typespecs,
69            knowntypespecs,
70            types,
71            knowntypes,
72            analyze_resolved=analyze_resolved,
73        )
74    _analyze.analyze_type_decls(types, analyze_decl, handle_unresolved)
75    for decl in decls:
76        if decl in types:
77            resolved = types[decl]
78        else:
79            resolved = analyze_decl(decl)
80            if resolved and handle_unresolved:
81                typedeps, _ = resolved
82                if not isinstance(typedeps, TypeDeclaration):
83                    if not typedeps or None in typedeps:
84                        raise NotImplementedError((decl, resolved))
85
86        yield decl, resolved
87
88
89#######################################
90# checks
91
92def check_all(analysis, checks, *, failfast=False):
93    for check in checks or ():
94        for data, failure in check(analysis):
95            if failure is None:
96                continue
97
98            yield data, failure
99            if failfast:
100                yield None, None
101                break
102        else:
103            continue
104        # We failed fast.
105        break
106