• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# Copyright (c) 2020-2021 Huawei Device Co., Ltd.
5#
6# HDF is dual licensed: you can use it either under the terms of
7# the GPL, or the BSD license, at your option.
8# See the LICENSE file in the root of this repository for complete details.
9
10import json
11import os
12import re
13import sys
14
15
16class IdlType(object):
17    INTERFACE = 1
18    CALLBACK = 2
19    TYPES = 3
20
21
22def translate_file_name(file_name):
23    name = file_name[1:] if file_name.startswith("I") else file_name
24    translate_name = ""
25    num = 0
26    for c in name:
27        if c >= 'A' and c <= 'Z':
28            if num > 1:
29                translate_name += "_"
30            translate_name += c.lower()
31        else:
32            translate_name += c
33        num += 1
34    return translate_name
35
36
37def get_idl_file_type(file_path):
38    idl_type = IdlType.TYPES
39    idl_file = open(file_path, "r")
40    file_str = idl_file.read()
41    idl_file.close()
42
43    # delete comment information
44    file_str = re.sub(r'//[^\r\n]*', "\n", file_str)
45    file_str = re.sub(r'(/\*[\s|\S]*?\*/)', "\n", file_str)
46
47    interface_index = file_str.find("interface")
48    if interface_index != -1:
49        if file_str.find("[callback]", 0, interface_index) != -1:
50            idl_type = IdlType.CALLBACK
51        else:
52            idl_type = IdlType.INTERFACE
53    return idl_type
54
55
56def c_interface_file_translate(idl_file, out_dir, part, outputs):
57    get_file_name = idl_file.split("/")[-1]
58    file_name = translate_file_name(get_file_name.split(".")[0])
59
60    iface_header_file = os.path.join(out_dir, "i" + file_name + ".h")
61    client_proxy_source_file = os.path.join(out_dir, file_name + "_proxy.c")
62    server_driver_source_file = os.path.join(out_dir, file_name + "_driver.c")
63    server_stub_header_file = os.path.join(out_dir, file_name + "_stub.h")
64    server_stub_source_file = os.path.join(out_dir, file_name + "_stub.c")
65    server_impl_header_file = os.path.join(out_dir, file_name + "_service.h")
66    server_impl_source_file = os.path.join(out_dir, file_name + "_service.c")
67
68    if part == "-c":
69        outputs.append(iface_header_file)
70        outputs.append(client_proxy_source_file)
71    elif part == "-s":
72        outputs.append(iface_header_file)
73        outputs.append(server_stub_header_file)
74        outputs.append(server_stub_source_file)
75    else:
76        outputs.append(iface_header_file)
77        outputs.append(client_proxy_source_file)
78        outputs.append(server_driver_source_file)
79        outputs.append(server_stub_header_file)
80        outputs.append(server_stub_source_file)
81        outputs.append(server_impl_header_file)
82        outputs.append(server_impl_source_file)
83
84
85def c_callback_file_translate(idl_file, out_dir, part, outputs):
86    get_file_name = idl_file.split("/")[-1]
87    file_name = translate_file_name(get_file_name.split(".")[0])
88
89    iface_header_file = os.path.join(out_dir, "i" + file_name + ".h")
90    client_proxy_source_file = os.path.join(out_dir, file_name + "_proxy.c")
91    server_stub_header_file = os.path.join(out_dir, file_name + "_stub.h")
92    server_stub_source_file = os.path.join(out_dir, file_name + "_stub.c")
93    server_impl_header_file = os.path.join(out_dir, file_name + "_service.h")
94    server_impl_source_file = os.path.join(out_dir, file_name + "_service.c")
95
96    if part == "-c":
97        outputs.append(iface_header_file)
98        outputs.append(server_stub_header_file)
99        outputs.append(server_stub_source_file)
100    elif part == "-s":
101        outputs.append(iface_header_file)
102        outputs.append(client_proxy_source_file)
103    else:
104        outputs.append(iface_header_file)
105        outputs.append(client_proxy_source_file)
106        outputs.append(server_stub_header_file)
107        outputs.append(server_stub_source_file)
108        outputs.append(server_impl_header_file)
109        outputs.append(server_impl_source_file)
110
111
112def c_types_file_translate(idl_file, out_dir, outputs):
113    get_file_name = idl_file.split("/")[-1]
114    file_name = translate_file_name(get_file_name.split(".")[0])
115
116    types_header_file = os.path.join(out_dir, file_name + ".h")
117    types_source_file = os.path.join(out_dir, file_name + ".c")
118
119    outputs.append(types_header_file)
120    outputs.append(types_source_file)
121
122
123def cpp_interface_file_translate(idl_file, out_dir, part, outputs):
124    get_file_name = idl_file.split("/")[-1]
125    file_name = translate_file_name(get_file_name.split(".")[0])
126
127    iface_header_file = os.path.join(out_dir, "i" + file_name + ".h")
128    client_proxy_header_file = os.path.join(out_dir, file_name + "_proxy.h")
129    client_proxy_source_file = os.path.join(out_dir, file_name + "_proxy.cpp")
130    server_driver_source_file = os.path.join(out_dir, file_name + "_driver.cpp")
131    server_stub_header_file = os.path.join(out_dir, file_name + "_stub.h")
132    server_stub_source_file = os.path.join(out_dir, file_name + "_stub.cpp")
133    server_impl_header_file = os.path.join(out_dir, file_name + "_service.h")
134    server_impl_source_file = os.path.join(out_dir, file_name + "_service.cpp")
135
136    if part == "-c":
137        outputs.append(iface_header_file)
138        outputs.append(client_proxy_header_file)
139        outputs.append(client_proxy_source_file)
140    elif part == "-s":
141        outputs.append(iface_header_file)
142        outputs.append(server_stub_header_file)
143        outputs.append(server_stub_source_file)
144    else:
145        outputs.append(iface_header_file)
146        outputs.append(client_proxy_header_file)
147        outputs.append(client_proxy_source_file)
148        outputs.append(server_driver_source_file)
149        outputs.append(server_stub_header_file)
150        outputs.append(server_stub_source_file)
151        outputs.append(server_impl_header_file)
152        outputs.append(server_impl_source_file)
153
154
155def cpp_callback_file_translate(idl_file, out_dir, part, outputs):
156    get_file_name = idl_file.split("/")[-1]
157    file_name = translate_file_name(get_file_name.split(".")[0])
158
159    iface_header_file = os.path.join(out_dir, "i" + file_name + ".h")
160    client_proxy_header_file = os.path.join(out_dir, file_name + "_proxy.h")
161    client_proxy_source_file = os.path.join(out_dir, file_name + "_proxy.cpp")
162    server_stub_header_file = os.path.join(out_dir, file_name + "_stub.h")
163    server_stub_source_file = os.path.join(out_dir, file_name + "_stub.cpp")
164    server_impl_header_file = os.path.join(out_dir, file_name + "_service.h")
165    server_impl_source_file = os.path.join(out_dir, file_name + "_service.cpp")
166
167    if part == "-c":
168        outputs.append(iface_header_file)
169        outputs.append(server_stub_header_file)
170        outputs.append(server_stub_source_file)
171    elif part == "-s":
172        outputs.append(iface_header_file)
173        outputs.append(client_proxy_header_file)
174        outputs.append(client_proxy_source_file)
175    else:
176        outputs.append(iface_header_file)
177        outputs.append(client_proxy_header_file)
178        outputs.append(client_proxy_source_file)
179        outputs.append(server_stub_header_file)
180        outputs.append(server_stub_source_file)
181        outputs.append(server_impl_header_file)
182        outputs.append(server_impl_source_file)
183
184
185def cpp_types_file_translate(idl_file, out_dir, outputs):
186    get_file_name = idl_file.split("/")[-1]
187    file_name = translate_file_name(get_file_name.split(".")[0])
188
189    types_header_file = os.path.join(out_dir, file_name + ".h")
190    types_source_file = os.path.join(out_dir, file_name + ".cpp")
191
192    outputs.append(types_header_file)
193    outputs.append(types_source_file)
194
195
196def c_get_compile_source_file(idl_files, out_dir, part):
197    outputs = []
198    for idl_file in idl_files:
199        idl_file_type = get_idl_file_type(idl_file)
200        if idl_file_type == IdlType.INTERFACE:
201            c_interface_file_translate(idl_file, out_dir, part, outputs)
202        elif idl_file_type == IdlType.CALLBACK:
203            c_callback_file_translate(idl_file, out_dir, part, outputs)
204        elif idl_file_type == IdlType.TYPES:
205            c_types_file_translate(idl_file, out_dir, outputs)
206    return outputs
207
208
209def cpp_get_compile_source_file(idl_files, out_dir, part):
210    outputs = []
211    for idl_file in idl_files:
212        idl_file_type = get_idl_file_type(idl_file)
213        if idl_file_type == IdlType.INTERFACE:
214            cpp_interface_file_translate(idl_file, out_dir, part, outputs)
215        elif idl_file_type == IdlType.CALLBACK:
216            cpp_callback_file_translate(idl_file, out_dir, part, outputs)
217        elif idl_file_type == IdlType.TYPES:
218            cpp_types_file_translate(idl_file, out_dir, outputs)
219    return outputs
220
221
222def get_compile_source_file(idl_files, language, out_dir, part):
223    outputs = []
224    if language == "c":
225        outputs = c_get_compile_source_file(idl_files, out_dir, part)
226    elif language == "cpp":
227        outputs = cpp_get_compile_source_file(idl_files, out_dir, part)
228    return outputs
229
230
231# ./build_hdi_files.py -o <language> <gen_dir> <part> <idl_files>
232def get_output_files(argv):
233    result = []
234    if len(argv) >= 5:
235        language = argv[2]
236        gen_dir = argv[3]
237        part = argv[4]
238        idl_files = argv[5:]
239
240        result = get_compile_source_file(idl_files, language, gen_dir, part)
241    sys.stdout.write('\n'.join(result))
242
243
244# parse package name of this idl file
245def parse_file_package(file_path):
246    package_str = ""
247    idl_file = open(file_path, "r")
248    file_str = idl_file.read()
249    result = re.findall(r'package\s(\w+(?:\.\w+)*);', file_str)
250    if (len(result) > 0):
251        package_str = result[0]
252    idl_file.close()
253    return package_str
254
255
256# search all idl files and parse package name
257def parse_package(idl_files):
258    package_str = ""
259    for idl_file in idl_files:
260        idl_file_type = get_idl_file_type(idl_file)
261        if idl_file_type == IdlType.INTERFACE:
262            package_str = parse_file_package(idl_file)
263            break
264    return package_str
265
266
267# parse version from package name
268def parse_version(package_str):
269    # the version is empty by default
270    version_str = ""
271    result = re.findall(r'\w+(?:\.\w+)*\.[V|v](\d+)_(\d+)', package_str)
272    if len(result) > 0:
273        major_version = result[0][0]
274        minor_version = result[0][1]
275        version_str = str(major_version) + "." + str(minor_version)
276    return version_str
277
278
279def parse_out_dir(gen_dir, package_str, path_map):
280    package_path_vec = path_map.split(":")
281    if (len(package_path_vec) != 2):
282        return gen_dir
283
284    root_package = package_path_vec[0]
285    root_package_path = package_path_vec[1]
286
287    temp_dir = package_str.replace(root_package, root_package_path)
288    temp_dir = temp_dir.replace(".", "/")
289    return gen_dir.replace(temp_dir, "")
290
291
292def parse_root_package_dir(gen_dir, package_str, path_map):
293    package_path_vec = path_map.split(":")
294    if (len(package_path_vec) != 2):
295        return gen_dir
296
297    root_package = package_path_vec[0]
298    root_package_path = package_path_vec[1]
299
300    temp_dir = package_str.replace(root_package, "")
301    temp_dir = temp_dir.replace(".", "/")
302    return gen_dir.replace(temp_dir, "")
303
304
305def parse_version_dir(gen_dir, version_str):
306    version_dir_name = "v" + version_str.replace(".", "_")
307    return gen_dir.replace(version_dir_name, "")
308
309
310# get information of package, version and generation files from idl files
311# ./build_hdi_files.py -i <language> <gen_dir> <path_mapping> <idl_files>
312def get_information(argv):
313    result = {}
314    if len(argv) >= 5:
315        language = argv[2]
316        gen_dir = argv[3]
317        path_map = argv[4]
318        idl_files = argv[5:]
319
320        package_str = parse_package(idl_files)
321        version_str = parse_version(package_str)
322
323        out_dir = parse_out_dir(gen_dir, package_str, path_map)
324
325        root_package_dir = parse_root_package_dir(gen_dir, package_str, path_map)
326
327        version_dir = parse_version_dir(gen_dir, version_str)
328
329        result = {
330            "package" : package_str,
331            "version" : version_str,
332            "out_dir" : out_dir,
333            "root_package_dir" : root_package_dir,
334            "version_dir" : version_dir,
335        }
336    sys.stdout.write(json.dumps(result))
337
338
339if __name__ == "__main__":
340    if len(sys.argv) < 1:
341        sys.stdout.write('\n')
342    option = sys.argv[1]
343    if option == "-i":
344        get_information(sys.argv)
345    elif option == "-o":
346        get_output_files(sys.argv)
347    else:
348        sys.stdout.write('\n')