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 sys
21import file_parser
22import system_util
23import make_capi_header
24import make_cpptoc_impl
25import make_ctocpp_impl
26import make_cpptoc_header
27import make_ctocpp_header
28
29# pylint:disable=huawei-redefined-outer-name
30
31# cannot be loaded as a module
32if __name__ != "__main__":
33  sys.stderr.write('This file cannot be loaded as a module!')
34  sys.exit()
35
36root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
37
38module_name = ''
39if len(sys.argv) - 1 > 0:
40  module_name = sys.argv[1]
41
42if len(sys.argv) - 2 > 0:
43  dir_names = (sys.argv[2], '')
44else:
45  dir_names = ('ohos_adapter', 'ohos_nweb', '')
46
47# Track the number of files that were written.
48file_count = 0
49
50# ------------------------------------------------------------------------------------------------------#
51
52def update_file(contents, file_path):
53  if contents[-1:] != "\n":
54    # Add newline at end of file.
55    contents += "\n"
56
57  file_dir = os.path.split(file_path)[0]
58  if not os.path.isdir(file_dir):
59    system_util.make_dirs(file_dir)
60
61  system_util.write_file(file_path, contents)
62  sys.stdout.write('Finish to write file ' + os.path.basename(file_path) + '...\n')
63
64  global file_count
65  file_count += 1
66
67# ------------------------------------------------------------------------------------------------------#
68
69def is_same_side(header, class_name):
70  cls = header.get_class(class_name)
71  if cls is None:
72    raise Exception('Class does not exist: ' + class_name)
73
74  if cls.is_webview_side():
75     return module_name == "webview"
76
77  return module_name == "webcore"
78
79# ------------------------------------------------------------------------------------------------------#
80
81def update_capi_file(header, dir_name, work_dir):
82  dir_path = os.path.join(os.path.join(work_dir, dir_name), 'capi')
83
84  # build the list of file name to make
85  file_names = sorted(header.get_file_names())
86  if len(file_names) != 0:
87    sys.stdout.write('In C API header directory ' + dir_path + '...\n')
88
89  for file_name in file_names:
90    sys.stdout.write('Generating ' + file_name + ' C API header...\n')
91    update_file(*make_capi_header.make_capi_header_file(header, work_dir, dir_name, file_name))
92
93# ------------------------------------------------------------------------------------------------------#
94
95def update_cpptoc_file(header, dir_name, work_dir):
96  dir_path = os.path.join(os.path.join(work_dir, dir_name), 'cpptoc')
97
98  # build the list of class name to make
99  class_names = sorted(header.get_class_names())
100  if len(class_names) != 0:
101    sys.stdout.write('In CppToC directory ' + dir_path + '...\n')
102
103  for class_name in class_names:
104    if len(module_name) != 0 and not is_same_side(header, class_name):
105      continue
106
107    sys.stdout.write('Generating ' + class_name + 'CppToC class header...\n')
108    update_file(*make_cpptoc_header.make_cpptoc_header_file(header, work_dir, dir_name, class_name))
109
110    sys.stdout.write('Generating ' + class_name + 'CppToC class implementation...\n')
111    update_file(*make_cpptoc_impl.make_cpptoc_impl_file(header, work_dir, dir_name, class_name))
112
113# ------------------------------------------------------------------------------------------------------#
114
115def update_ctocpp_file(header, dir_name, work_dir):
116  dir_path = os.path.join(os.path.join(work_dir, dir_name), 'ctocpp')
117
118  # build the list of class name to make
119  class_names = sorted(header.get_class_names())
120  if len(class_names) != 0:
121    sys.stdout.write('In CToCpp directory ' + dir_path + '...\n')
122
123  for class_name in class_names:
124    if len(module_name) != 0 and is_same_side(header, class_name):
125      continue
126
127    sys.stdout.write('Generating ' + class_name + 'CToCpp class header...\n')
128    update_file(*make_ctocpp_header.make_ctocpp_header_file(header, work_dir, dir_name, class_name))
129
130    sys.stdout.write('Generating ' + class_name + 'CToCpp class implementation...\n')
131    update_file(*make_ctocpp_impl.make_ctocpp_impl_file(header, work_dir, dir_name, class_name))
132
133# ------------------------------------------------------------------------------------------------------#
134
135def translate_dir(dir_name):
136  global file_count
137  file_count = 0
138
139  # make sure the header directory exists
140  include_file_dir = os.path.join(os.path.join(root_dir, dir_name), 'include')
141  if not system_util.path_exists(include_file_dir):
142    sys.stderr.write('Directory ' + include_file_dir + ' does not exist.\n')
143    return
144
145  # create the header object
146  sys.stdout.write('Parsing C++ headers from ' + include_file_dir + '...\n')
147  header = file_parser.obj_header()
148
149  # add include files to be processed
150  header.set_root_directory(include_file_dir)
151  header.add_directory(include_file_dir)
152
153  # output the C API header file
154  update_capi_file(header, dir_name, root_dir)
155
156  # output the CppToC class file
157  update_cpptoc_file(header, dir_name, root_dir)
158
159  # output the CToCpp class file
160  update_ctocpp_file(header, dir_name, root_dir)
161
162  sys.stdout.write('Done - Wrote ' + str(file_count) + ' files.\n')
163
164# ------------------------------------------------------------------------------------------------------#
165
166for dir_name in dir_names:
167  if len(dir_name) > 0:
168    translate_dir(dir_name)
169