| from c_parser import ( | |
| parse_files as _parse_files, | |
| ) | |
| from c_parser.info import ( | |
| KIND, | |
| TypeDeclaration, | |
| resolve_parsed, | |
| ) | |
| from c_parser.match import ( | |
| filter_by_kind, | |
| group_by_kinds, | |
| ) | |
| from . import ( | |
| analyze as _analyze, | |
| datafiles as _datafiles, | |
| ) | |
| from .info import Analysis | |
| def analyze(filenmes, **kwargs): | |
| results = iter_analysis_results(filenames, **kwargs) | |
| return Analysis.from_results(results) | |
| def iter_analysis_results(filenmes, *, | |
| known=None, | |
| **kwargs | |
| ): | |
| decls = iter_decls(filenames, **kwargs) | |
| yield from analyze_decls(decls, known) | |
| def iter_decls(filenames, *, | |
| kinds=None, | |
| parse_files=_parse_files, | |
| **kwargs | |
| ): | |
| kinds = KIND.DECLS if kinds is None else (KIND.DECLS & set(kinds)) | |
| parse_files = parse_files or _parse_files | |
| parsed = parse_files(filenames, **kwargs) | |
| parsed = filter_by_kind(parsed, kinds) | |
| for item in parsed: | |
| yield resolve_parsed(item) | |
| def analyze_decls(decls, known, *, | |
| analyze_resolved=None, | |
| handle_unresolved=True, | |
| relroot=None, | |
| ): | |
| knowntypes, knowntypespecs = _datafiles.get_known( | |
| known, | |
| handle_unresolved=handle_unresolved, | |
| analyze_resolved=analyze_resolved, | |
| relroot=relroot, | |
| ) | |
| decls = list(decls) | |
| collated = group_by_kinds(decls) | |
| types = {decl: None for decl in collated['type']} | |
| typespecs = _analyze.get_typespecs(types) | |
| def analyze_decl(decl): | |
| return _analyze.analyze_decl( | |
| decl, | |
| typespecs, | |
| knowntypespecs, | |
| types, | |
| knowntypes, | |
| analyze_resolved=analyze_resolved, | |
| ) | |
| _analyze.analyze_type_decls(types, analyze_decl, handle_unresolved) | |
| for decl in decls: | |
| if decl in types: | |
| resolved = types[decl] | |
| else: | |
| resolved = analyze_decl(decl) | |
| if resolved and handle_unresolved: | |
| typedeps, _ = resolved | |
| if not isinstance(typedeps, TypeDeclaration): | |
| if not typedeps or None in typedeps: | |
| raise NotImplementedError((decl, resolved)) | |
| yield decl, resolved | |
| ####################################### | |
| # checks | |
| def check_all(analysis, checks, *, failfast=False): | |
| for check in checks or (): | |
| for data, failure in check(analysis): | |
| if failure is None: | |
| continue | |
| yield data, failure | |
| if failfast: | |
| yield None, None | |
| break | |
| else: | |
| continue | |
| # We failed fast. | |
| break |