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')