17db96d56Sopenharmony_ciimport os.path 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_cifrom c_parser import ( 47db96d56Sopenharmony_ci info as _info, 57db96d56Sopenharmony_ci match as _match, 67db96d56Sopenharmony_ci) 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ci_KIND = _info.KIND 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci# XXX Use known.tsv for these? 137db96d56Sopenharmony_ciSYSTEM_TYPES = { 147db96d56Sopenharmony_ci 'int8_t', 157db96d56Sopenharmony_ci 'uint8_t', 167db96d56Sopenharmony_ci 'int16_t', 177db96d56Sopenharmony_ci 'uint16_t', 187db96d56Sopenharmony_ci 'int32_t', 197db96d56Sopenharmony_ci 'uint32_t', 207db96d56Sopenharmony_ci 'int64_t', 217db96d56Sopenharmony_ci 'uint64_t', 227db96d56Sopenharmony_ci 'size_t', 237db96d56Sopenharmony_ci 'ssize_t', 247db96d56Sopenharmony_ci 'intptr_t', 257db96d56Sopenharmony_ci 'uintptr_t', 267db96d56Sopenharmony_ci 'wchar_t', 277db96d56Sopenharmony_ci '', 287db96d56Sopenharmony_ci # OS-specific 297db96d56Sopenharmony_ci 'pthread_cond_t', 307db96d56Sopenharmony_ci 'pthread_mutex_t', 317db96d56Sopenharmony_ci 'pthread_key_t', 327db96d56Sopenharmony_ci 'atomic_int', 337db96d56Sopenharmony_ci 'atomic_uintptr_t', 347db96d56Sopenharmony_ci '', 357db96d56Sopenharmony_ci # lib-specific 367db96d56Sopenharmony_ci 'WINDOW', # curses 377db96d56Sopenharmony_ci 'XML_LChar', 387db96d56Sopenharmony_ci 'XML_Size', 397db96d56Sopenharmony_ci 'XML_Parser', 407db96d56Sopenharmony_ci 'enum XML_Error', 417db96d56Sopenharmony_ci 'enum XML_Status', 427db96d56Sopenharmony_ci '', 437db96d56Sopenharmony_ci} 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_cidef is_system_type(typespec): 477db96d56Sopenharmony_ci return typespec in SYSTEM_TYPES 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci 507db96d56Sopenharmony_ci################################## 517db96d56Sopenharmony_ci# decl matchers 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_cidef is_public(decl): 547db96d56Sopenharmony_ci if not decl.filename.endswith('.h'): 557db96d56Sopenharmony_ci return False 567db96d56Sopenharmony_ci if 'Include' not in decl.filename.split(os.path.sep): 577db96d56Sopenharmony_ci return False 587db96d56Sopenharmony_ci return True 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_cidef is_process_global(vardecl): 627db96d56Sopenharmony_ci kind, storage, _, _, _ = _info.get_parsed_vartype(vardecl) 637db96d56Sopenharmony_ci if kind is not _KIND.VARIABLE: 647db96d56Sopenharmony_ci raise NotImplementedError(vardecl) 657db96d56Sopenharmony_ci if 'static' in (storage or ''): 667db96d56Sopenharmony_ci return True 677db96d56Sopenharmony_ci 687db96d56Sopenharmony_ci if hasattr(vardecl, 'parent'): 697db96d56Sopenharmony_ci parent = vardecl.parent 707db96d56Sopenharmony_ci else: 717db96d56Sopenharmony_ci parent = vardecl.get('parent') 727db96d56Sopenharmony_ci return not parent 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_cidef is_fixed_type(vardecl): 767db96d56Sopenharmony_ci if not vardecl: 777db96d56Sopenharmony_ci return None 787db96d56Sopenharmony_ci _, _, _, typespec, abstract = _info.get_parsed_vartype(vardecl) 797db96d56Sopenharmony_ci if 'typeof' in typespec: 807db96d56Sopenharmony_ci raise NotImplementedError(vardecl) 817db96d56Sopenharmony_ci elif not abstract: 827db96d56Sopenharmony_ci return True 837db96d56Sopenharmony_ci 847db96d56Sopenharmony_ci if '*' not in abstract: 857db96d56Sopenharmony_ci # XXX What about []? 867db96d56Sopenharmony_ci return True 877db96d56Sopenharmony_ci elif _match._is_funcptr(abstract): 887db96d56Sopenharmony_ci return True 897db96d56Sopenharmony_ci else: 907db96d56Sopenharmony_ci for after in abstract.split('*')[1:]: 917db96d56Sopenharmony_ci if not after.lstrip().startswith('const'): 927db96d56Sopenharmony_ci return False 937db96d56Sopenharmony_ci else: 947db96d56Sopenharmony_ci return True 957db96d56Sopenharmony_ci 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_cidef is_immutable(vardecl): 987db96d56Sopenharmony_ci if not vardecl: 997db96d56Sopenharmony_ci return None 1007db96d56Sopenharmony_ci if not is_fixed_type(vardecl): 1017db96d56Sopenharmony_ci return False 1027db96d56Sopenharmony_ci _, _, typequal, _, _ = _info.get_parsed_vartype(vardecl) 1037db96d56Sopenharmony_ci # If there, it can only be "const" or "volatile". 1047db96d56Sopenharmony_ci return typequal == 'const' 1057db96d56Sopenharmony_ci 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_cidef is_public_api(decl): 1087db96d56Sopenharmony_ci if not is_public(decl): 1097db96d56Sopenharmony_ci return False 1107db96d56Sopenharmony_ci if decl.kind is _KIND.TYPEDEF: 1117db96d56Sopenharmony_ci return True 1127db96d56Sopenharmony_ci elif _match.is_type_decl(decl): 1137db96d56Sopenharmony_ci return not _match.is_forward_decl(decl) 1147db96d56Sopenharmony_ci else: 1157db96d56Sopenharmony_ci return _match.is_external_reference(decl) 1167db96d56Sopenharmony_ci 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_cidef is_public_declaration(decl): 1197db96d56Sopenharmony_ci if not is_public(decl): 1207db96d56Sopenharmony_ci return False 1217db96d56Sopenharmony_ci if decl.kind is _KIND.TYPEDEF: 1227db96d56Sopenharmony_ci return True 1237db96d56Sopenharmony_ci elif _match.is_type_decl(decl): 1247db96d56Sopenharmony_ci return _match.is_forward_decl(decl) 1257db96d56Sopenharmony_ci else: 1267db96d56Sopenharmony_ci return _match.is_external_reference(decl) 1277db96d56Sopenharmony_ci 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_cidef is_public_definition(decl): 1307db96d56Sopenharmony_ci if not is_public(decl): 1317db96d56Sopenharmony_ci return False 1327db96d56Sopenharmony_ci if decl.kind is _KIND.TYPEDEF: 1337db96d56Sopenharmony_ci return True 1347db96d56Sopenharmony_ci elif _match.is_type_decl(decl): 1357db96d56Sopenharmony_ci return not _match.is_forward_decl(decl) 1367db96d56Sopenharmony_ci else: 1377db96d56Sopenharmony_ci return not _match.is_external_reference(decl) 1387db96d56Sopenharmony_ci 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_cidef is_public_impl(decl): 1417db96d56Sopenharmony_ci if not _KIND.is_decl(decl.kind): 1427db96d56Sopenharmony_ci return False 1437db96d56Sopenharmony_ci # See filter_forward() about "is_public". 1447db96d56Sopenharmony_ci return getattr(decl, 'is_public', False) 1457db96d56Sopenharmony_ci 1467db96d56Sopenharmony_ci 1477db96d56Sopenharmony_cidef is_module_global_decl(decl): 1487db96d56Sopenharmony_ci if is_public_impl(decl): 1497db96d56Sopenharmony_ci return False 1507db96d56Sopenharmony_ci if _match.is_forward_decl(decl): 1517db96d56Sopenharmony_ci return False 1527db96d56Sopenharmony_ci return not _match.is_local_var(decl) 1537db96d56Sopenharmony_ci 1547db96d56Sopenharmony_ci 1557db96d56Sopenharmony_ci################################## 1567db96d56Sopenharmony_ci# filtering with matchers 1577db96d56Sopenharmony_ci 1587db96d56Sopenharmony_cidef filter_forward(items, *, markpublic=False): 1597db96d56Sopenharmony_ci if markpublic: 1607db96d56Sopenharmony_ci public = set() 1617db96d56Sopenharmony_ci actual = [] 1627db96d56Sopenharmony_ci for item in items: 1637db96d56Sopenharmony_ci if is_public_api(item): 1647db96d56Sopenharmony_ci public.add(item.id) 1657db96d56Sopenharmony_ci elif not _match.is_forward_decl(item): 1667db96d56Sopenharmony_ci actual.append(item) 1677db96d56Sopenharmony_ci else: 1687db96d56Sopenharmony_ci # non-public duplicate! 1697db96d56Sopenharmony_ci # XXX 1707db96d56Sopenharmony_ci raise Exception(item) 1717db96d56Sopenharmony_ci for item in actual: 1727db96d56Sopenharmony_ci _info.set_flag(item, 'is_public', item.id in public) 1737db96d56Sopenharmony_ci yield item 1747db96d56Sopenharmony_ci else: 1757db96d56Sopenharmony_ci for item in items: 1767db96d56Sopenharmony_ci if _match.is_forward_decl(item): 1777db96d56Sopenharmony_ci continue 1787db96d56Sopenharmony_ci yield item 1797db96d56Sopenharmony_ci 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ci################################## 1827db96d56Sopenharmony_ci# grouping with matchers 1837db96d56Sopenharmony_ci 1847db96d56Sopenharmony_cidef group_by_storage(decls, **kwargs): 1857db96d56Sopenharmony_ci def is_module_global(decl): 1867db96d56Sopenharmony_ci if not is_module_global_decl(decl): 1877db96d56Sopenharmony_ci return False 1887db96d56Sopenharmony_ci if decl.kind == _KIND.VARIABLE: 1897db96d56Sopenharmony_ci if _info.get_effective_storage(decl) == 'static': 1907db96d56Sopenharmony_ci # This is covered by is_static_module_global(). 1917db96d56Sopenharmony_ci return False 1927db96d56Sopenharmony_ci return True 1937db96d56Sopenharmony_ci def is_static_module_global(decl): 1947db96d56Sopenharmony_ci if not _match.is_global_var(decl): 1957db96d56Sopenharmony_ci return False 1967db96d56Sopenharmony_ci return _info.get_effective_storage(decl) == 'static' 1977db96d56Sopenharmony_ci def is_static_local(decl): 1987db96d56Sopenharmony_ci if not _match.is_local_var(decl): 1997db96d56Sopenharmony_ci return False 2007db96d56Sopenharmony_ci return _info.get_effective_storage(decl) == 'static' 2017db96d56Sopenharmony_ci #def is_local(decl): 2027db96d56Sopenharmony_ci # if not _match.is_local_var(decl): 2037db96d56Sopenharmony_ci # return False 2047db96d56Sopenharmony_ci # return _info.get_effective_storage(decl) != 'static' 2057db96d56Sopenharmony_ci categories = { 2067db96d56Sopenharmony_ci #'extern': is_extern, 2077db96d56Sopenharmony_ci 'published': is_public_impl, 2087db96d56Sopenharmony_ci 'module-global': is_module_global, 2097db96d56Sopenharmony_ci 'static-module-global': is_static_module_global, 2107db96d56Sopenharmony_ci 'static-local': is_static_local, 2117db96d56Sopenharmony_ci } 2127db96d56Sopenharmony_ci return _match.group_by_category(decls, categories, **kwargs) 213