15f9996aaSopenharmony_ci#!/usr/bin/env python 25f9996aaSopenharmony_ci# -*- coding: utf-8 -*- 35f9996aaSopenharmony_ci 45f9996aaSopenharmony_ci# 55f9996aaSopenharmony_ci# Copyright (c) 2023 Huawei Device Co., Ltd. 65f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 75f9996aaSopenharmony_ci# you may not use this file except in compliance with the License. 85f9996aaSopenharmony_ci# You may obtain a copy of the License at 95f9996aaSopenharmony_ci# 105f9996aaSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 115f9996aaSopenharmony_ci# 125f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 135f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 145f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 155f9996aaSopenharmony_ci# See the License for the specific language governing permissions and 165f9996aaSopenharmony_ci# limitations under the License. 175f9996aaSopenharmony_ci 185f9996aaSopenharmony_ciimport os 195f9996aaSopenharmony_ciimport re 205f9996aaSopenharmony_cifrom collections import defaultdict 215f9996aaSopenharmony_ci 225f9996aaSopenharmony_cifrom util.io_util import IoUtil 235f9996aaSopenharmony_cifrom exceptions.ohos_exception import OHOSException 245f9996aaSopenharmony_cifrom resources.config import Config 255f9996aaSopenharmony_cifrom containers.status import throw_exception 265f9996aaSopenharmony_ci 275f9996aaSopenharmony_cifrom hb.helper.no_instance import NoInstance 285f9996aaSopenharmony_ci 295f9996aaSopenharmony_ci 305f9996aaSopenharmony_ciclass ProductUtil(metaclass=NoInstance): 315f9996aaSopenharmony_ci 325f9996aaSopenharmony_ci @staticmethod 335f9996aaSopenharmony_ci def get_products(): 345f9996aaSopenharmony_ci config = Config() 355f9996aaSopenharmony_ci # ext products configuration 365f9996aaSopenharmony_ci _ext_scan_path = os.path.join(config.root_path, 375f9996aaSopenharmony_ci 'out/products_ext/vendor') 385f9996aaSopenharmony_ci if os.path.exists(_ext_scan_path): 395f9996aaSopenharmony_ci for company in os.listdir(_ext_scan_path): 405f9996aaSopenharmony_ci company_path = os.path.join(_ext_scan_path, company) 415f9996aaSopenharmony_ci if not os.path.isdir(company_path): 425f9996aaSopenharmony_ci continue 435f9996aaSopenharmony_ci 445f9996aaSopenharmony_ci for product in os.listdir(company_path): 455f9996aaSopenharmony_ci p_config_path = os.path.join(company_path, product) 465f9996aaSopenharmony_ci config_path = os.path.join(p_config_path, 'config.json') 475f9996aaSopenharmony_ci 485f9996aaSopenharmony_ci if os.path.isfile(config_path): 495f9996aaSopenharmony_ci info = IoUtil.read_json_file(config_path) 505f9996aaSopenharmony_ci product_name = info.get('product_name') 515f9996aaSopenharmony_ci if info.get('product_path'): 525f9996aaSopenharmony_ci product_path = os.path.join( 535f9996aaSopenharmony_ci config.root_path, info.get('product_path')) 545f9996aaSopenharmony_ci else: 555f9996aaSopenharmony_ci product_path = p_config_path 565f9996aaSopenharmony_ci if product_name is not None: 575f9996aaSopenharmony_ci subsystem_config_overlay_path = os.path.join(product_path, 585f9996aaSopenharmony_ci 'subsystem_config_overlay.json') 595f9996aaSopenharmony_ci if os.path.isfile(subsystem_config_overlay_path): 605f9996aaSopenharmony_ci yield { 615f9996aaSopenharmony_ci 'company': company, 625f9996aaSopenharmony_ci "name": product_name, 635f9996aaSopenharmony_ci 'product_config_path': p_config_path, 645f9996aaSopenharmony_ci 'product_path': product_path, 655f9996aaSopenharmony_ci 'version': info.get('version', '3.0'), 665f9996aaSopenharmony_ci 'os_level': info.get('type', "mini"), 675f9996aaSopenharmony_ci 'build_out_path': info.get('build_out_path'), 685f9996aaSopenharmony_ci 'subsystem_config_json': 695f9996aaSopenharmony_ci info.get('subsystem_config_json'), 705f9996aaSopenharmony_ci 'subsystem_config_overlay_json': 715f9996aaSopenharmony_ci subsystem_config_overlay_path, 725f9996aaSopenharmony_ci 'config': config_path, 735f9996aaSopenharmony_ci 'component_type': info.get('component_type', '') 745f9996aaSopenharmony_ci } 755f9996aaSopenharmony_ci else: 765f9996aaSopenharmony_ci yield { 775f9996aaSopenharmony_ci 'company': company, 785f9996aaSopenharmony_ci "name": product_name, 795f9996aaSopenharmony_ci 'product_config_path': p_config_path, 805f9996aaSopenharmony_ci 'product_path': product_path, 815f9996aaSopenharmony_ci 'version': info.get('version', '3.0'), 825f9996aaSopenharmony_ci 'os_level': info.get('type', "mini"), 835f9996aaSopenharmony_ci 'build_out_path': info.get('build_out_path'), 845f9996aaSopenharmony_ci 'subsystem_config_json': 855f9996aaSopenharmony_ci info.get('subsystem_config_json'), 865f9996aaSopenharmony_ci 'config': config_path, 875f9996aaSopenharmony_ci 'component_type': info.get('component_type', '') 885f9996aaSopenharmony_ci } 895f9996aaSopenharmony_ci if config.vendor_path != '': 905f9996aaSopenharmony_ci for company in os.listdir(config.vendor_path): 915f9996aaSopenharmony_ci company_path = os.path.join(config.vendor_path, company) 925f9996aaSopenharmony_ci if not os.path.isdir(company_path): 935f9996aaSopenharmony_ci continue 945f9996aaSopenharmony_ci 955f9996aaSopenharmony_ci for product in os.listdir(company_path): 965f9996aaSopenharmony_ci product_path = os.path.join(company_path, product) 975f9996aaSopenharmony_ci config_path = os.path.join(product_path, 'config.json') 985f9996aaSopenharmony_ci 995f9996aaSopenharmony_ci if os.path.isfile(config_path): 1005f9996aaSopenharmony_ci info = IoUtil.read_json_file(config_path) 1015f9996aaSopenharmony_ci product_name = info.get('product_name') 1025f9996aaSopenharmony_ci if product_name is not None: 1035f9996aaSopenharmony_ci yield { 1045f9996aaSopenharmony_ci 'company': company, 1055f9996aaSopenharmony_ci "name": product_name, 1065f9996aaSopenharmony_ci 'product_config_path': product_path, 1075f9996aaSopenharmony_ci 'product_path': product_path, 1085f9996aaSopenharmony_ci 'version': info.get('version', '3.0'), 1095f9996aaSopenharmony_ci 'os_level': info.get('type', "mini"), 1105f9996aaSopenharmony_ci 'config': config_path, 1115f9996aaSopenharmony_ci 'component_type': info.get('component_type', '') 1125f9996aaSopenharmony_ci } 1135f9996aaSopenharmony_ci bip_path = config.built_in_product_path 1145f9996aaSopenharmony_ci for item in os.listdir(bip_path): 1155f9996aaSopenharmony_ci if item[0] in ".": 1165f9996aaSopenharmony_ci continue 1175f9996aaSopenharmony_ci else: 1185f9996aaSopenharmony_ci product_name = item[0:-len('.json') 1195f9996aaSopenharmony_ci ] if item.endswith('.json') else item 1205f9996aaSopenharmony_ci config_path = os.path.join(bip_path, item) 1215f9996aaSopenharmony_ci info = IoUtil.read_json_file(config_path) 1225f9996aaSopenharmony_ci yield { 1235f9996aaSopenharmony_ci 'company': 'built-in', 1245f9996aaSopenharmony_ci "name": product_name, 1255f9996aaSopenharmony_ci 'product_config_path': bip_path, 1265f9996aaSopenharmony_ci 'product_path': bip_path, 1275f9996aaSopenharmony_ci 'version': info.get('version', '2.0'), 1285f9996aaSopenharmony_ci 'os_level': info.get('type', 'standard'), 1295f9996aaSopenharmony_ci 'config': config_path, 1305f9996aaSopenharmony_ci 'component_type': info.get('component_type', '') 1315f9996aaSopenharmony_ci } 1325f9996aaSopenharmony_ci 1335f9996aaSopenharmony_ci bipl_path = config.built_in_product_path_for_llvm 1345f9996aaSopenharmony_ci if os.path.isdir(bipl_path): 1355f9996aaSopenharmony_ci for item in os.listdir(bipl_path): 1365f9996aaSopenharmony_ci if item[0] in ".": 1375f9996aaSopenharmony_ci continue 1385f9996aaSopenharmony_ci else: 1395f9996aaSopenharmony_ci product_name = item[0:-len('.json') 1405f9996aaSopenharmony_ci ] if item.endswith('.json') else item 1415f9996aaSopenharmony_ci config_path = os.path.join(bipl_path, item) 1425f9996aaSopenharmony_ci info = IoUtil.read_json_file(config_path) 1435f9996aaSopenharmony_ci yield { 1445f9996aaSopenharmony_ci 'company': 'built-in', 1455f9996aaSopenharmony_ci "name": product_name, 1465f9996aaSopenharmony_ci 'product_config_path': bipl_path, 1475f9996aaSopenharmony_ci 'product_path': bipl_path, 1485f9996aaSopenharmony_ci 'version': info.get('version', '2.0'), 1495f9996aaSopenharmony_ci 'os_level': info.get('type', 'standard'), 1505f9996aaSopenharmony_ci 'config': config_path, 1515f9996aaSopenharmony_ci 'component_type': info.get('component_type', '') 1525f9996aaSopenharmony_ci } 1535f9996aaSopenharmony_ci 1545f9996aaSopenharmony_ci @staticmethod 1555f9996aaSopenharmony_ci @throw_exception 1565f9996aaSopenharmony_ci def get_device_info(product_json: str): 1575f9996aaSopenharmony_ci info = IoUtil.read_json_file(product_json) 1585f9996aaSopenharmony_ci config = Config() 1595f9996aaSopenharmony_ci version = info.get('version', '3.0') 1605f9996aaSopenharmony_ci 1615f9996aaSopenharmony_ci if version == '3.0': 1625f9996aaSopenharmony_ci device_company = info.get('device_company') 1635f9996aaSopenharmony_ci board = info.get('board') 1645f9996aaSopenharmony_ci _board_path = info.get('board_path') 1655f9996aaSopenharmony_ci if _board_path and os.path.exists( 1665f9996aaSopenharmony_ci os.path.join(config.root_path, _board_path)): 1675f9996aaSopenharmony_ci board_path = os.path.join(config.root_path, _board_path) 1685f9996aaSopenharmony_ci else: 1695f9996aaSopenharmony_ci board_path = os.path.join(config.root_path, 'device', 1705f9996aaSopenharmony_ci device_company, board) 1715f9996aaSopenharmony_ci # board and soc decoupling feature will add boards 1725f9996aaSopenharmony_ci # directory path here. 1735f9996aaSopenharmony_ci if not os.path.exists(board_path): 1745f9996aaSopenharmony_ci board_path = os.path.join(config.root_path, 'device', 1755f9996aaSopenharmony_ci 'board', device_company, board) 1765f9996aaSopenharmony_ci board_config_path = None 1775f9996aaSopenharmony_ci if info.get('board_config_path'): 1785f9996aaSopenharmony_ci board_config_path = os.path.join(config.root_path, 1795f9996aaSopenharmony_ci info.get('board_config_path')) 1805f9996aaSopenharmony_ci 1815f9996aaSopenharmony_ci return { 1825f9996aaSopenharmony_ci 'board': info.get('board'), 1835f9996aaSopenharmony_ci 'kernel': info.get('kernel_type'), 1845f9996aaSopenharmony_ci 'kernel_version': info.get('kernel_version'), 1855f9996aaSopenharmony_ci 'company': info.get('device_company'), 1865f9996aaSopenharmony_ci 'board_path': board_path, 1875f9996aaSopenharmony_ci 'board_config_path': board_config_path, 1885f9996aaSopenharmony_ci 'target_cpu': info.get('target_cpu'), 1895f9996aaSopenharmony_ci 'target_os': info.get('target_os'), 1905f9996aaSopenharmony_ci 'support_cpu': info.get('support_cpu'), 1915f9996aaSopenharmony_ci } 1925f9996aaSopenharmony_ci else: 1935f9996aaSopenharmony_ci raise OHOSException(f'wrong version number in {product_json}') 1945f9996aaSopenharmony_ci 1955f9996aaSopenharmony_ci @staticmethod 1965f9996aaSopenharmony_ci @throw_exception 1975f9996aaSopenharmony_ci def get_all_components(product_json: str): 1985f9996aaSopenharmony_ci if not os.path.isfile(product_json): 1995f9996aaSopenharmony_ci raise OHOSException(f'features {product_json} not found') 2005f9996aaSopenharmony_ci 2015f9996aaSopenharmony_ci config = Config() 2025f9996aaSopenharmony_ci # Get all inherit files 2035f9996aaSopenharmony_ci files = [os.path.join(config.root_path, file) for file in IoUtil.read_json_file( 2045f9996aaSopenharmony_ci product_json).get('inherit', [])] 2055f9996aaSopenharmony_ci # Add the product config file to last with highest priority 2065f9996aaSopenharmony_ci files.append(product_json) 2075f9996aaSopenharmony_ci 2085f9996aaSopenharmony_ci # Read all parts in order 2095f9996aaSopenharmony_ci all_parts = {} 2105f9996aaSopenharmony_ci for _file in files: 2115f9996aaSopenharmony_ci if not os.path.isfile(_file): 2125f9996aaSopenharmony_ci continue 2135f9996aaSopenharmony_ci _info = IoUtil.read_json_file(_file) 2145f9996aaSopenharmony_ci parts = _info.get('parts') 2155f9996aaSopenharmony_ci if parts: 2165f9996aaSopenharmony_ci all_parts.update(parts) 2175f9996aaSopenharmony_ci else: 2185f9996aaSopenharmony_ci # v3 config files 2195f9996aaSopenharmony_ci all_parts.update(ProductUtil.get_vendor_parts_list(_info)) 2205f9996aaSopenharmony_ci 2215f9996aaSopenharmony_ci return all_parts 2225f9996aaSopenharmony_ci 2235f9996aaSopenharmony_ci @staticmethod 2245f9996aaSopenharmony_ci @throw_exception 2255f9996aaSopenharmony_ci def get_features(product_json: str): 2265f9996aaSopenharmony_ci if not os.path.isfile(product_json): 2275f9996aaSopenharmony_ci raise OHOSException(f'features {product_json} not found') 2285f9996aaSopenharmony_ci 2295f9996aaSopenharmony_ci config = Config() 2305f9996aaSopenharmony_ci # Get all inherit files 2315f9996aaSopenharmony_ci files = [os.path.join(config.root_path, file) for file in IoUtil.read_json_file( 2325f9996aaSopenharmony_ci product_json).get('inherit', [])] 2335f9996aaSopenharmony_ci # Add the product config file to last with highest priority 2345f9996aaSopenharmony_ci files.append(product_json) 2355f9996aaSopenharmony_ci 2365f9996aaSopenharmony_ci # Read all parts in order 2375f9996aaSopenharmony_ci all_parts = {} 2385f9996aaSopenharmony_ci for _file in files: 2395f9996aaSopenharmony_ci if not os.path.isfile(_file): 2405f9996aaSopenharmony_ci continue 2415f9996aaSopenharmony_ci _info = IoUtil.read_json_file(_file) 2425f9996aaSopenharmony_ci parts = _info.get('parts') 2435f9996aaSopenharmony_ci if parts: 2445f9996aaSopenharmony_ci all_parts.update(parts) 2455f9996aaSopenharmony_ci else: 2465f9996aaSopenharmony_ci # v3 config files 2475f9996aaSopenharmony_ci all_parts.update(ProductUtil.get_vendor_parts_list(_info)) 2485f9996aaSopenharmony_ci 2495f9996aaSopenharmony_ci # Get all features 2505f9996aaSopenharmony_ci features_list = [] 2515f9996aaSopenharmony_ci for part, value in all_parts.items(): 2525f9996aaSopenharmony_ci if "features" not in value: 2535f9996aaSopenharmony_ci continue 2545f9996aaSopenharmony_ci for key, val in value["features"].items(): 2555f9996aaSopenharmony_ci _item = '' 2565f9996aaSopenharmony_ci if isinstance(val, bool): 2575f9996aaSopenharmony_ci _item = f'{key}={str(val).lower()}' 2585f9996aaSopenharmony_ci elif isinstance(val, int): 2595f9996aaSopenharmony_ci _item = f'{key}={val}' 2605f9996aaSopenharmony_ci elif isinstance(val, str): 2615f9996aaSopenharmony_ci _item = f'{key}="{val}"' 2625f9996aaSopenharmony_ci else: 2635f9996aaSopenharmony_ci raise Exception( 2645f9996aaSopenharmony_ci "part feature '{key}:{val}' type not support.") 2655f9996aaSopenharmony_ci features_list.append(_item) 2665f9996aaSopenharmony_ci return features_list 2675f9996aaSopenharmony_ci 2685f9996aaSopenharmony_ci @staticmethod 2695f9996aaSopenharmony_ci @throw_exception 2705f9996aaSopenharmony_ci def get_features_dict(product_json: str): 2715f9996aaSopenharmony_ci all_parts = ProductUtil.get_all_components(product_json) 2725f9996aaSopenharmony_ci features_dict = {} 2735f9996aaSopenharmony_ci for part, value in all_parts.items(): 2745f9996aaSopenharmony_ci if "features" not in value: 2755f9996aaSopenharmony_ci continue 2765f9996aaSopenharmony_ci for key, val in value["features"].items(): 2775f9996aaSopenharmony_ci if type(val) in [bool, int, str]: 2785f9996aaSopenharmony_ci features_dict[key] = val 2795f9996aaSopenharmony_ci else: 2805f9996aaSopenharmony_ci raise Exception( 2815f9996aaSopenharmony_ci "part feature '{key}:{val}' type not support.") 2825f9996aaSopenharmony_ci return features_dict 2835f9996aaSopenharmony_ci 2845f9996aaSopenharmony_ci @staticmethod 2855f9996aaSopenharmony_ci @throw_exception 2865f9996aaSopenharmony_ci def get_components(product_json: str, subsystems: str): 2875f9996aaSopenharmony_ci if not os.path.isfile(product_json): 2885f9996aaSopenharmony_ci raise OHOSException(f'{product_json} not found') 2895f9996aaSopenharmony_ci 2905f9996aaSopenharmony_ci components_dict = defaultdict(list) 2915f9996aaSopenharmony_ci product_data = IoUtil.read_json_file(product_json) 2925f9996aaSopenharmony_ci for subsystem in product_data.get('subsystems', []): 2935f9996aaSopenharmony_ci sname = subsystem.get('subsystem', '') 2945f9996aaSopenharmony_ci if not len(subsystems) or sname in subsystems: 2955f9996aaSopenharmony_ci components_dict[sname] += [ 2965f9996aaSopenharmony_ci comp['component'] 2975f9996aaSopenharmony_ci for comp in subsystem.get('components', []) 2985f9996aaSopenharmony_ci ] 2995f9996aaSopenharmony_ci 3005f9996aaSopenharmony_ci return components_dict, product_data.get('board', ''),\ 3015f9996aaSopenharmony_ci product_data.get('kernel_type', '') 3025f9996aaSopenharmony_ci 3035f9996aaSopenharmony_ci @staticmethod 3045f9996aaSopenharmony_ci @throw_exception 3055f9996aaSopenharmony_ci def get_product_info(product_name: str, company=None): 3065f9996aaSopenharmony_ci for product_info in ProductUtil.get_products(): 3075f9996aaSopenharmony_ci cur_company = product_info['company'] 3085f9996aaSopenharmony_ci cur_product = product_info['name'] 3095f9996aaSopenharmony_ci if company: 3105f9996aaSopenharmony_ci if cur_company == company and cur_product == product_name: 3115f9996aaSopenharmony_ci return product_info 3125f9996aaSopenharmony_ci else: 3135f9996aaSopenharmony_ci if cur_product == product_name: 3145f9996aaSopenharmony_ci return product_info 3155f9996aaSopenharmony_ci 3165f9996aaSopenharmony_ci raise OHOSException(f'product {product_name}@{company} not found') 3175f9996aaSopenharmony_ci 3185f9996aaSopenharmony_ci @staticmethod 3195f9996aaSopenharmony_ci @throw_exception 3205f9996aaSopenharmony_ci def get_compiler(config_path: str): 3215f9996aaSopenharmony_ci config = os.path.join(config_path, 'config.gni') 3225f9996aaSopenharmony_ci if not os.path.isfile(config): 3235f9996aaSopenharmony_ci return '' 3245f9996aaSopenharmony_ci compiler_pattern = r'board_toolchain_type ?= ?"(\w+)"' 3255f9996aaSopenharmony_ci with open(config, 'rt', encoding='utf-8') as config_file: 3265f9996aaSopenharmony_ci data = config_file.read() 3275f9996aaSopenharmony_ci compiler_list = re.findall(compiler_pattern, data) 3285f9996aaSopenharmony_ci if not len(compiler_list): 3295f9996aaSopenharmony_ci raise OHOSException(f'board_toolchain_type is None in {config}') 3305f9996aaSopenharmony_ci 3315f9996aaSopenharmony_ci return compiler_list[0] 3325f9996aaSopenharmony_ci 3335f9996aaSopenharmony_ci @staticmethod 3345f9996aaSopenharmony_ci def get_vendor_parts_list(config: dict): 3355f9996aaSopenharmony_ci return _transform(config).get('parts') 3365f9996aaSopenharmony_ci 3375f9996aaSopenharmony_ci @staticmethod 3385f9996aaSopenharmony_ci def has_component(product_name: str) -> bool: 3395f9996aaSopenharmony_ci pass 3405f9996aaSopenharmony_ci 3415f9996aaSopenharmony_ci 3425f9996aaSopenharmony_cidef _transform(config: dict): 3435f9996aaSopenharmony_ci subsystems = config.get('subsystems') 3445f9996aaSopenharmony_ci if subsystems: 3455f9996aaSopenharmony_ci config.pop('subsystems') 3465f9996aaSopenharmony_ci parts = _from_ss_to_parts(subsystems) 3475f9996aaSopenharmony_ci config['parts'] = parts 3485f9996aaSopenharmony_ci return config 3495f9996aaSopenharmony_ci 3505f9996aaSopenharmony_ci 3515f9996aaSopenharmony_cidef _from_ss_to_parts(subsystems: dict): 3525f9996aaSopenharmony_ci parts = dict() 3535f9996aaSopenharmony_ci for subsystem in subsystems: 3545f9996aaSopenharmony_ci ss_name = subsystem.get('subsystem') 3555f9996aaSopenharmony_ci components = subsystem.get('components') 3565f9996aaSopenharmony_ci if components: 3575f9996aaSopenharmony_ci for com in components: 3585f9996aaSopenharmony_ci com_name = com.get('component') 3595f9996aaSopenharmony_ci features = com.get('features') 3605f9996aaSopenharmony_ci syscap = com.get('syscap') 3615f9996aaSopenharmony_ci exclusions = com.get('exclusions') 3625f9996aaSopenharmony_ci if features: 3635f9996aaSopenharmony_ci pairs = get_features(features) 3645f9996aaSopenharmony_ci parts['{}:{}'.format(ss_name, com_name)] = pairs 3655f9996aaSopenharmony_ci else: 3665f9996aaSopenharmony_ci parts['{}:{}'.format(ss_name, com_name)] = dict() 3675f9996aaSopenharmony_ci if syscap: 3685f9996aaSopenharmony_ci pairs = get_syscap(syscap) 3695f9996aaSopenharmony_ci parts.get('{}:{}'.format(ss_name, com_name)).update(pairs) 3705f9996aaSopenharmony_ci if exclusions: 3715f9996aaSopenharmony_ci pairs = get_exclusion_modules(exclusions) 3725f9996aaSopenharmony_ci parts.get('{}:{}'.format(ss_name, com_name)).update(pairs) 3735f9996aaSopenharmony_ci # Copy other key-values 3745f9996aaSopenharmony_ci for key, val in com.items(): 3755f9996aaSopenharmony_ci if key in ['component', 'features', 'syscap', 'exclusions']: 3765f9996aaSopenharmony_ci continue 3775f9996aaSopenharmony_ci parts.get('{}:{}'.format(ss_name, com_name)).update(key=val) 3785f9996aaSopenharmony_ci return parts 3795f9996aaSopenharmony_ci 3805f9996aaSopenharmony_ci 3815f9996aaSopenharmony_cidef get_features(features: dict): 3825f9996aaSopenharmony_ci feats = {} 3835f9996aaSopenharmony_ci for feat in features: 3845f9996aaSopenharmony_ci if not feat: 3855f9996aaSopenharmony_ci continue 3865f9996aaSopenharmony_ci match = feat.index("=") 3875f9996aaSopenharmony_ci if match <= 0: 3885f9996aaSopenharmony_ci print("Warning: invalid feature [{}]".format(feat)) 3895f9996aaSopenharmony_ci continue 3905f9996aaSopenharmony_ci key = feat[:match].strip() 3915f9996aaSopenharmony_ci val = feat[match + 1:].strip().strip('"') 3925f9996aaSopenharmony_ci if val == 'true': 3935f9996aaSopenharmony_ci feats[key] = True 3945f9996aaSopenharmony_ci elif val == 'false': 3955f9996aaSopenharmony_ci feats[key] = False 3965f9996aaSopenharmony_ci elif re.match(r'[0-9]+', val): 3975f9996aaSopenharmony_ci feats[key] = int(val) 3985f9996aaSopenharmony_ci else: 3995f9996aaSopenharmony_ci feats[key] = val.replace('\"', '"') 4005f9996aaSopenharmony_ci 4015f9996aaSopenharmony_ci pairs = dict() 4025f9996aaSopenharmony_ci pairs['features'] = feats 4035f9996aaSopenharmony_ci return pairs 4045f9996aaSopenharmony_ci 4055f9996aaSopenharmony_ci 4065f9996aaSopenharmony_cidef get_syscap(syscap: dict): 4075f9996aaSopenharmony_ci feats = {} 4085f9996aaSopenharmony_ci for feat in syscap: 4095f9996aaSopenharmony_ci if not feat: 4105f9996aaSopenharmony_ci continue 4115f9996aaSopenharmony_ci if '=' not in feat: 4125f9996aaSopenharmony_ci raise Exception("Error: invalid syscap [{}]".format(feat)) 4135f9996aaSopenharmony_ci match = feat.index("=") 4145f9996aaSopenharmony_ci key = feat[:match].strip() 4155f9996aaSopenharmony_ci val = feat[match + 1:].strip().strip('"') 4165f9996aaSopenharmony_ci if val == 'true': 4175f9996aaSopenharmony_ci feats[key] = True 4185f9996aaSopenharmony_ci elif val == 'false': 4195f9996aaSopenharmony_ci feats[key] = False 4205f9996aaSopenharmony_ci elif re.match(r'[0-9]+', val): 4215f9996aaSopenharmony_ci feats[key] = int(val) 4225f9996aaSopenharmony_ci else: 4235f9996aaSopenharmony_ci feats[key] = val.replace('\"', '"') 4245f9996aaSopenharmony_ci 4255f9996aaSopenharmony_ci pairs = dict() 4265f9996aaSopenharmony_ci pairs['syscap'] = feats 4275f9996aaSopenharmony_ci return pairs 4285f9996aaSopenharmony_ci 4295f9996aaSopenharmony_ci 4305f9996aaSopenharmony_cidef get_exclusion_modules(exclusions: str): 4315f9996aaSopenharmony_ci pairs = dict() 4325f9996aaSopenharmony_ci pairs['exclusions'] = exclusions 4335f9996aaSopenharmony_ci return pairs 434