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