#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (c) 2024 Huawei Device Co., Ltd. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import absolute_import import os import file_parser import make_file_base # pylint:disable=huawei-redefined-outer-name # ------------------------------------------------------------------------------------------------------# def make_capi_static_funcs(funcs, indent, defined_names, translate_map): new_list = [] old_list = make_file_base.get_func_name_list(funcs) result = '' for func in funcs: if func.get_retval().get_type().is_result_string(): result += indent + '// The resulting string must be freed by calling cef_string_userfree_free().\n' suffix = '' new_list = make_file_base.get_func_name_count(func.get_capi_name(), old_list, new_list) if new_list.count(func.get_capi_name()) != 0: suffix = str(new_list.count(func.get_capi_name())) result += '\n' + indent + 'ARK_WEB_EXPORT ' + func.get_capi_proto(defined_names, suffix) + ';\n' return result # ------------------------------------------------------------------------------------------------------# def make_capi_class_funcs(funcs, indent, defined_names, translate_map): new_list = [] old_list = make_file_base.get_func_name_list(funcs) result = '' for func in funcs: result += '\n' if func.get_retval().get_type().is_result_string(): result += indent + '// The resulting string must be freed by calling cef_string_userfree_free().\n' suffix = '' new_list = make_file_base.get_func_name_count(func.get_capi_name(), old_list, new_list) if new_list.count(func.get_capi_name()) != 0: suffix = str(new_list.count(func.get_capi_name())) elif file_parser.check_func_name_is_key_work(func.get_capi_name()): suffix = '0' parts = func.get_capi_parts() result += indent+parts['retval']+' (ARK_WEB_CALLBACK *'+parts['name'] + suffix + \ ')('+', '.join(parts['args'])+');\n' return result # ------------------------------------------------------------------------------------------------------# def make_capi_include_file(clses, header, file_name, all_declares): result = '' # identify all includes and forward declarations internal_includes = set([]) translated_includes = set([]) for cls in clses: includes = cls.get_includes() for include in includes: translated_includes.add(include) declares = cls.get_forward_declares() for declare in declares: declare_cls = header.get_class(declare) if declare_cls is None: raise Exception('Unknown class: %s' % declare) all_declares.add(declare_cls.get_capi_name()) # output translated includes flag = True if len(translated_includes) > 0: sorted_includes = sorted(translated_includes) for include in sorted_includes: if include == 'base/include/ark_web_base_ref_counted' and flag: flag = False result += '#include "base/capi/ark_web_base_ref_counted_capi.h"\n' elif include == 'base/include/ark_web_types' or include == 'ohos_nweb/include/ark_web_value' \ or include == 'ohos_nweb/include/ark_web_message' or include == 'ohos_nweb/include/ark_web_nweb_structs' \ or include == 'ohos_adapter/include/ark_web_adapter_structs' or include.endswith('_vector'): result += '#include "' + include + '.h"\n' else: if include.startswith('ohos_nweb/include/') and flag: flag = False result += '#include "base/capi/ark_web_base_ref_counted_capi.h"\n' result += '#include "' + include.replace('/include/', '/capi/') + '_capi.h"\n' else: result += '#include "base/capi/ark_web_base_ref_counted_capi.h"\n' # output internal includes if len(internal_includes) > 0: sorted_includes = sorted(internal_includes) for include in sorted_includes: result += '#include "include/' + include + '.h"\n' return result # ------------------------------------------------------------------------------------------------------# def make_capi_class_body(clses, header, file_name, all_declares): result = '' # output forward declarations if len(all_declares) > 0: sorted_declares = sorted(all_declares) for declare in sorted_declares: result += '\n' + \ 'typedef struct _' + declare + ' ' + declare + ';\n' # structure names that have already been defined defined_names = header.get_defined_structs() # map of strings that will be changed in C++ comments translate_map = header.get_capi_translations() # output classes for cls in clses: # virtual functions are inside the structure capi_name = cls.get_capi_name() result += '\n' + \ 'typedef struct _' + capi_name + ' {\n' + \ ' /**\n' + \ ' * @brief Base structure.\n' + \ ' */\n' + \ ' ' + cls.get_parent_capi_name() + ' base;\n' funcs = cls.get_virtual_funcs() result += make_capi_class_funcs(funcs, ' ', defined_names, translate_map) result += '} ' + capi_name + ';\n' defined_names.append(capi_name) # static functions become global funcs = cls.get_static_funcs() if len(funcs) > 0: result += make_capi_static_funcs(funcs, '', defined_names, translate_map) # output global functions funcs = header.get_funcs(file_name) if len(funcs) > 0: result += make_capi_static_funcs(funcs, '', defined_names, translate_map) + '\n' return result # ------------------------------------------------------------------------------------------------------# def make_capi_header_file(header, dir_path, dir_name, file_name): # header string content = make_file_base.get_copyright() content += \ """ #ifndef $GUARD$ #define $GUARD$ #pragma once """ content += '\n' clses = header.get_classes(file_name) all_declares = set([]) content += make_capi_include_file(clses, header, file_name, all_declares) content += \ """ #ifdef __cplusplus extern "C" { #endif """ content += make_capi_class_body(clses, header, file_name, all_declares) # footer string content += \ """ #ifdef __cplusplus } #endif #endif // $GUARD$ """ # add the guard string guard = file_name.replace('/', '_').replace('.', '_capi_').upper() + '_' content = content.replace('$GUARD$', guard) absolute_dir = os.path.join(os.path.join(dir_path, dir_name), 'capi') absolute_path = os.path.join(absolute_dir, file_name.replace('.', '_capi.')) return (content, absolute_path)