• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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