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