1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# Copyright (c) 2024 Huawei Device Co., Ltd. 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17from __future__ import absolute_import 18 19import os 20import file_parser 21import make_file_base 22 23# pylint:disable=huawei-redefined-outer-name 24 25# ------------------------------------------------------------------------------------------------------# 26 27def make_capi_static_funcs(funcs, indent, defined_names, translate_map): 28 new_list = [] 29 old_list = make_file_base.get_func_name_list(funcs) 30 31 result = '' 32 for func in funcs: 33 if func.get_retval().get_type().is_result_string(): 34 result += indent + '// The resulting string must be freed by calling cef_string_userfree_free().\n' 35 36 suffix = '' 37 new_list = make_file_base.get_func_name_count(func.get_capi_name(), old_list, new_list) 38 if new_list.count(func.get_capi_name()) != 0: 39 suffix = str(new_list.count(func.get_capi_name())) 40 41 result += '\n' + indent + 'ARK_WEB_EXPORT ' + func.get_capi_proto(defined_names, suffix) + ';\n' 42 43 return result 44 45# ------------------------------------------------------------------------------------------------------# 46 47def make_capi_class_funcs(funcs, indent, defined_names, translate_map): 48 new_list = [] 49 old_list = make_file_base.get_func_name_list(funcs) 50 51 result = '' 52 for func in funcs: 53 result += '\n' 54 if func.get_retval().get_type().is_result_string(): 55 result += indent + '// The resulting string must be freed by calling cef_string_userfree_free().\n' 56 57 suffix = '' 58 new_list = make_file_base.get_func_name_count(func.get_capi_name(), old_list, new_list) 59 if new_list.count(func.get_capi_name()) != 0: 60 suffix = str(new_list.count(func.get_capi_name())) 61 elif file_parser.check_func_name_is_key_work(func.get_capi_name()): 62 suffix = '0' 63 64 parts = func.get_capi_parts() 65 result += indent+parts['retval']+' (ARK_WEB_CALLBACK *'+parts['name'] + suffix + \ 66 ')('+', '.join(parts['args'])+');\n' 67 68 return result 69 70# ------------------------------------------------------------------------------------------------------# 71 72def make_capi_include_file(clses, header, file_name, all_declares): 73 result = '' 74 75 # identify all includes and forward declarations 76 internal_includes = set([]) 77 translated_includes = set([]) 78 for cls in clses: 79 includes = cls.get_includes() 80 for include in includes: 81 translated_includes.add(include) 82 83 declares = cls.get_forward_declares() 84 for declare in declares: 85 declare_cls = header.get_class(declare) 86 if declare_cls is None: 87 raise Exception('Unknown class: %s' % declare) 88 89 all_declares.add(declare_cls.get_capi_name()) 90 91 funcs = cls.get_virtual_funcs() 92 for func in funcs: 93 raw_type = func.get_retval().get_raw_type() 94 if raw_type.find("<" + cls.get_name() + ">") != -1: 95 all_declares.add(cls.get_capi_name()) 96 break 97 98 # output translated includes 99 flag = True 100 if len(translated_includes) > 0: 101 sorted_includes = sorted(translated_includes) 102 for include in sorted_includes: 103 if include == 'base/include/ark_web_base_ref_counted' and flag: 104 flag = False 105 result += '#include "base/capi/ark_web_base_ref_counted_capi.h"\n' 106 elif include == 'base/include/ark_web_types' or include == 'ohos_nweb/include/ark_web_value' \ 107 or include == 'ohos_nweb/include/ark_web_message' or include == 'ohos_nweb/include/ark_web_nweb_structs' \ 108 or include == 'ohos_adapter/include/ark_web_adapter_structs' or include.endswith('_vector'): 109 result += '#include "' + include + '.h"\n' 110 else: 111 if include.startswith('ohos_nweb/include/') and flag: 112 flag = False 113 result += '#include "base/capi/ark_web_base_ref_counted_capi.h"\n' 114 result += '#include "' + include.replace('/include/', '/capi/') + '_capi.h"\n' 115 else: 116 result += '#include "base/capi/ark_web_base_ref_counted_capi.h"\n' 117 118 # output internal includes 119 if len(internal_includes) > 0: 120 sorted_includes = sorted(internal_includes) 121 for include in sorted_includes: 122 result += '#include "include/' + include + '.h"\n' 123 124 return result 125 126# ------------------------------------------------------------------------------------------------------# 127 128def make_capi_class_body(clses, header, file_name, all_declares): 129 result = '' 130 131 # output forward declarations 132 if len(all_declares) > 0: 133 sorted_declares = sorted(all_declares) 134 for declare in sorted_declares: 135 result += '\n' + \ 136 'typedef struct _' + declare + ' ' + declare + ';\n' 137 138 # structure names that have already been defined 139 defined_names = header.get_defined_structs() 140 141 # map of strings that will be changed in C++ comments 142 translate_map = header.get_capi_translations() 143 144 # output classes 145 for cls in clses: 146 # virtual functions are inside the structure 147 capi_name = cls.get_capi_name() 148 result += '\n' + \ 149 'typedef struct _' + capi_name + ' {\n' + \ 150 ' /**\n' + \ 151 ' * @brief Base structure.\n' + \ 152 ' */\n' + \ 153 ' ' + cls.get_parent_capi_name() + ' base;\n' 154 funcs = cls.get_virtual_funcs() 155 result += make_capi_class_funcs(funcs, ' ', defined_names, translate_map) 156 result += '} ' + capi_name + ';\n' 157 158 defined_names.append(capi_name) 159 160 # static functions become global 161 funcs = cls.get_static_funcs() 162 if len(funcs) > 0: 163 result += make_capi_static_funcs(funcs, '', defined_names, translate_map) 164 165 # output global functions 166 funcs = header.get_funcs(file_name) 167 if len(funcs) > 0: 168 result += make_capi_static_funcs(funcs, '', defined_names, translate_map) + '\n' 169 170 return result 171 172# ------------------------------------------------------------------------------------------------------# 173 174def make_capi_header_file(header, dir_path, dir_name, file_name): 175 # header string 176 content = make_file_base.get_copyright() 177 178 content += \ 179""" 180#ifndef $GUARD$ 181#define $GUARD$ 182#pragma once 183""" 184 content += '\n' 185 186 clses = header.get_classes(file_name) 187 188 all_declares = set([]) 189 content += make_capi_include_file(clses, header, file_name, all_declares) 190 191 content += \ 192""" 193#ifdef __cplusplus 194extern "C" { 195#endif 196""" 197 198 content += make_capi_class_body(clses, header, file_name, all_declares) 199 200 # footer string 201 content += \ 202""" 203#ifdef __cplusplus 204} 205#endif 206 207#endif // $GUARD$ 208""" 209 210 # add the guard string 211 guard = file_name.replace('/', '_').replace('.', '_capi_').upper() + '_' 212 content = content.replace('$GUARD$', guard) 213 214 absolute_dir = os.path.join(os.path.join(dir_path, dir_name), 'capi') 215 absolute_path = os.path.join(absolute_dir, file_name.replace('.', '_capi.')) 216 217 return (content, absolute_path) 218 219