From 84f7f8258cf2306ad262faa55f376fe28bc14f99 Mon Sep 17 00:00:00 2001 From: yue Date: Fri, 3 Dec 2021 10:44:14 +0800 Subject: [PATCH] feat:integrate hdi into the ohos compiling system Signed-off-by: yue --- tools/hdi-gen/BUILD.gn | 22 ++ tools/hdi-gen/Makefile | 3 +- tools/hdi-gen/ast/ast_interface_type.cpp | 2 +- tools/hdi-gen/build_hdi_files.py | 292 ++++++++++++++++++ .../codegen/c_client_proxy_code_emitter.cpp | 232 +++++++------- .../codegen/c_client_proxy_code_emitter.h | 14 +- .../codegen/c_custom_types_code_emitter.cpp | 2 +- .../codegen/c_interface_code_emitter.cpp | 141 +++++++++ .../codegen/c_interface_code_emitter.h | 45 +++ .../codegen/c_service_driver_code_emitter.cpp | 63 ++-- .../codegen/c_service_impl_code_emitter.cpp | 49 +-- .../codegen/c_service_stub_code_emitter.cpp | 243 ++++++++++++--- .../codegen/c_service_stub_code_emitter.h | 14 +- tools/hdi-gen/codegen/code_generator.cpp | 34 +- .../codegen/cpp_client_proxy_code_emitter.cpp | 32 +- .../codegen/cpp_client_proxy_code_emitter.h | 2 + tools/hdi-gen/codegen/cpp_code_emitter.cpp | 14 + tools/hdi-gen/codegen/cpp_code_emitter.h | 4 + .../codegen/cpp_interface_code_emitter.cpp | 220 +++++++++++++ .../codegen/cpp_interface_code_emitter.h | 57 ++++ .../cpp_service_driver_code_emitter.cpp | 50 +-- .../codegen/cpp_service_impl_code_emitter.cpp | 54 +++- .../codegen/cpp_service_impl_code_emitter.h | 8 + .../codegen/cpp_service_stub_code_emitter.cpp | 210 ++++++++++--- .../codegen/cpp_service_stub_code_emitter.h | 12 +- tools/hdi-gen/main.cpp | 12 +- tools/hdi-gen/parser/module_parser.cpp | 45 ++- tools/hdi-gen/parser/module_parser.h | 4 + tools/hdi-gen/util/options.cpp | 62 ++-- tools/hdi-gen/util/options.h | 40 ++- 30 files changed, 1554 insertions(+), 428 deletions(-) create mode 100755 tools/hdi-gen/BUILD.gn create mode 100755 tools/hdi-gen/build_hdi_files.py create mode 100755 tools/hdi-gen/codegen/c_interface_code_emitter.cpp create mode 100755 tools/hdi-gen/codegen/c_interface_code_emitter.h create mode 100755 tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp create mode 100755 tools/hdi-gen/codegen/cpp_interface_code_emitter.h diff --git a/tools/hdi-gen/BUILD.gn b/tools/hdi-gen/BUILD.gn new file mode 100755 index 00000000..f2892d4e --- /dev/null +++ b/tools/hdi-gen/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (c) 2021 Huawei Device Co., Ltd. +# +# HDF is dual licensed: you can use it either under the terms of +# the GPL, or the BSD license, at your option. +# See the LICENSE file in the root of this repository for complete details. + +action("build_hdi_gen") { + script = "/usr/bin/env" + if (defined(ohos_lite)) { + script = "//build/lite/run_shell_cmd.py" + } + + outputs = [ "$target_out_dir/hdi-gen" ] + + args = [ + "make", + "-j8", + "-C", + rebase_path("."), + "OUT_DIR=" + rebase_path(target_out_dir), + ] +} diff --git a/tools/hdi-gen/Makefile b/tools/hdi-gen/Makefile index 47499d30..53836788 100755 --- a/tools/hdi-gen/Makefile +++ b/tools/hdi-gen/Makefile @@ -4,7 +4,8 @@ # the GPL, or the BSD license, at your option. # See the LICENSE file in the root of this repository for complete details. -export TARGET:=hdi-gen +export OUT_DIR:=. +export TARGET:=$(OUT_DIR)/hdi-gen export CXXFLAGS = -std=c++14 -O2 -w export Q := @ export MAKEFLAGS += --no-print-directory diff --git a/tools/hdi-gen/ast/ast_interface_type.cpp b/tools/hdi-gen/ast/ast_interface_type.cpp index 850f7f6c..b093998e 100755 --- a/tools/hdi-gen/ast/ast_interface_type.cpp +++ b/tools/hdi-gen/ast/ast_interface_type.cpp @@ -154,7 +154,7 @@ void ASTInterfaceType::EmitCStubReadVar(const String& parcelName, const String& sb.Append(prefix + g_tab).Append("ec = HDF_ERR_INVALID_PARAM;\n"); sb.Append(prefix + g_tab).Append("goto errors;\n"); sb.Append(prefix).Append("}\n"); - sb.Append(prefix).AppendFormat("%s = %sProxyObtain(%s);\n", + sb.Append(prefix).AppendFormat("%s = %sGet(%s);\n", name.string(), miName.string(), remoteName.string()); } diff --git a/tools/hdi-gen/build_hdi_files.py b/tools/hdi-gen/build_hdi_files.py new file mode 100755 index 00000000..d30e2797 --- /dev/null +++ b/tools/hdi-gen/build_hdi_files.py @@ -0,0 +1,292 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# +# Copyright (c) 2021, Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of Willow Garage, Inc. nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import os +import sys + +class IdlType: + INTERFACE = 1 + CALLBACK = 2 + TYPES = 3 + +def translate_file_name(file_name): + name = file_name[1:] if file_name.startswith("I") else file_name + translate_name = "" + for i in range(len(name)): + c = name[i] + if c >= 'A' and c <= 'Z': + if i > 1: + translate_name += "_" + translate_name += c.lower() + else: + translate_name += c + return translate_name + + +def get_idl_file_type(file_path): + idl_type = IdlType.TYPES + file = open(file_path, "r") + for file_line in file.readlines(): + interface_index = file_line.find("interface") + if interface_index != -1: + if file_line.find("[callback]", 0, interface_index) != -1: + idl_type = IdlType.CALLBACK + else: + idl_type = IdlType.INTERFACE + break + else: + continue + file.close() + return idl_type + +def c_interface_file_translate(idl_file, out_dir, part, outputs): + file = idl_file.split("/")[-1] + file_name = translate_file_name(file.split(".")[0]) + + iface_header_file = os.path.join(out_dir, "i" + file_name + ".h") + client_proxy_source_file = os.path.join(out_dir, file_name + "_proxy.c") + server_driver_source_file = os.path.join(out_dir, file_name + "_driver.c") + server_stub_header_file = os.path.join(out_dir, file_name + "_stub.h") + server_stub_source_file = os.path.join(out_dir, file_name + "_stub.c") + server_impl_header_file = os.path.join(out_dir, file_name + "_service.h") + server_impl_source_file = os.path.join(out_dir, file_name + "_service.c") + + if part == "client_lib_source": + outputs.append(iface_header_file) + outputs.append(client_proxy_source_file) + elif part == "server_lib_source": + outputs.append(iface_header_file) + outputs.append(server_driver_source_file) + outputs.append(server_stub_header_file) + outputs.append(server_stub_source_file) + else: + outputs.append(iface_header_file) + outputs.append(client_proxy_source_file) + outputs.append(server_driver_source_file) + outputs.append(server_stub_header_file) + outputs.append(server_stub_source_file) + outputs.append(server_impl_header_file) + outputs.append(server_impl_source_file) + +def c_callback_file_translate(idl_file, out_dir, part, outputs): + file = idl_file.split("/")[-1] + file_name = translate_file_name(file.split(".")[0]) + + iface_header_file = os.path.join(out_dir, "i" + file_name + ".h") + client_proxy_source_file = os.path.join(out_dir, file_name + "_proxy.c") + server_stub_header_file = os.path.join(out_dir, file_name + "_stub.h") + server_stub_source_file = os.path.join(out_dir, file_name + "_stub.c") + server_impl_header_file = os.path.join(out_dir, file_name + "_service.h") + server_impl_source_file = os.path.join(out_dir, file_name + "_service.c") + + if part == "client_lib_source": + outputs.append(iface_header_file) + outputs.append(server_stub_header_file) + outputs.append(server_stub_source_file) + elif part == "server_lib_source": + outputs.append(iface_header_file) + outputs.append(client_proxy_source_file) + else: + outputs.append(iface_header_file) + outputs.append(client_proxy_source_file) + outputs.append(server_stub_header_file) + outputs.append(server_stub_source_file) + outputs.append(server_impl_header_file) + outputs.append(server_impl_source_file) + +def c_types_file_translate(idl_file, out_dir, outputs): + file = idl_file.split("/")[-1] + file_name = translate_file_name(file.split(".")[0]) + + types_header_file = os.path.join(out_dir, file_name + ".h") + types_source_file = os.path.join(out_dir, file_name + ".c") + + outputs.append(types_header_file) + outputs.append(types_source_file) + +def c_idl_translate(idl_files, out_dir): + outputs = [] + for idl_file in idl_files: + idl_file_type = get_idl_file_type(idl_file) + if idl_file_type == IdlType.INTERFACE: + c_interface_file_translate(idl_file, out_dir, "all", outputs) + elif idl_file_type == IdlType.CALLBACK: + c_callback_file_translate(idl_file, out_dir, "all", outputs) + elif idl_file_type == IdlType.TYPES: + c_types_file_translate(idl_file, out_dir, outputs) + return outputs + +def cpp_interface_file_translate(idl_file, out_dir, part, outputs): + file = idl_file.split("/")[-1] + file_name = translate_file_name(file.split(".")[0]) + + iface_header_file = os.path.join(out_dir, "i" + file_name + ".h") + client_proxy_header_file = os.path.join(out_dir, file_name + "_proxy.h") + client_proxy_source_file = os.path.join(out_dir, file_name + "_proxy.cpp") + server_driver_source_file = os.path.join(out_dir, file_name + "_driver.cpp") + server_stub_header_file = os.path.join(out_dir, file_name + "_stub.h") + server_stub_source_file = os.path.join(out_dir, file_name + "_stub.cpp") + server_impl_header_file = os.path.join(out_dir, file_name + "_service.h") + server_impl_source_file = os.path.join(out_dir, file_name + "_service.cpp") + + if part == "client_lib_source": + outputs.append(iface_header_file) + outputs.append(client_proxy_header_file) + outputs.append(client_proxy_source_file) + elif part == "server_lib_source": + outputs.append(iface_header_file) + outputs.append(server_driver_source_file) + outputs.append(server_stub_header_file) + outputs.append(server_stub_source_file) + else: + outputs.append(iface_header_file) + outputs.append(client_proxy_header_file) + outputs.append(client_proxy_source_file) + outputs.append(server_driver_source_file) + outputs.append(server_stub_header_file) + outputs.append(server_stub_source_file) + outputs.append(server_impl_header_file) + outputs.append(server_impl_source_file) + +def cpp_callback_file_translate(idl_file, out_dir, part, outputs): + file = idl_file.split("/")[-1] + file_name = translate_file_name(file.split(".")[0]) + + iface_header_file = os.path.join(out_dir, "i" + file_name + ".h") + client_proxy_header_file = os.path.join(out_dir, file_name + "_proxy.h") + client_proxy_source_file = os.path.join(out_dir, file_name + "_proxy.cpp") + server_stub_header_file = os.path.join(out_dir, file_name + "_stub.h") + server_stub_source_file = os.path.join(out_dir, file_name + "_stub.cpp") + server_impl_header_file = os.path.join(out_dir, file_name + "_service.h") + server_impl_source_file = os.path.join(out_dir, file_name + "_service.cpp") + + if part == "client_lib_source": + outputs.append(iface_header_file) + outputs.append(server_stub_header_file) + outputs.append(server_stub_source_file) + elif part == "server_lib_source": + outputs.append(iface_header_file) + outputs.append(client_proxy_header_file) + outputs.append(client_proxy_source_file) + else: + outputs.append(iface_header_file) + outputs.append(client_proxy_header_file) + outputs.append(client_proxy_source_file) + outputs.append(server_stub_header_file) + outputs.append(server_stub_source_file) + outputs.append(server_impl_header_file) + outputs.append(server_impl_source_file) + +def cpp_types_file_translate(idl_file, out_dir, outputs): + file = idl_file.split("/")[-1] + file_name = translate_file_name(file.split(".")[0]) + + types_header_file = os.path.join(out_dir, file_name + ".h") + types_source_file = os.path.join(out_dir, file_name + ".cpp") + + outputs.append(types_header_file) + outputs.append(types_source_file) + +def cpp_idl_translate(idl_files, out_dir): + outputs = [] + for idl_file in idl_files: + idl_file_type = get_idl_file_type(idl_file) + if idl_file_type == IdlType.INTERFACE: + cpp_interface_file_translate(idl_file, out_dir, "all", outputs) + elif idl_file_type == IdlType.CALLBACK: + cpp_callback_file_translate(idl_file, out_dir, "all", outputs) + elif idl_file_type == IdlType.TYPES: + cpp_types_file_translate(idl_file, out_dir, outputs) + return outputs + +def idl_translate(idl_files, language, out_dir): + outputs = [] + if language == "c": + outputs = c_idl_translate(idl_files, out_dir) + elif language == "cpp": + outputs = cpp_idl_translate(idl_files, out_dir) + return outputs + +def c_get_compile_source_file(idl_files, out_dir, part): + outputs = [] + for idl_file in idl_files: + idl_file_type = get_idl_file_type(idl_file) + if idl_file_type == IdlType.INTERFACE: + c_interface_file_translate(idl_file, out_dir, part, outputs) + elif idl_file_type == IdlType.CALLBACK: + c_callback_file_translate(idl_file, out_dir, part, outputs) + elif idl_file_type == IdlType.TYPES: + c_types_file_translate(idl_file, out_dir, outputs) + return outputs + +def cpp_get_compile_source_file(idl_files, out_dir, part): + outputs = [] + for idl_file in idl_files: + idl_file_type = get_idl_file_type(idl_file) + if idl_file_type == IdlType.INTERFACE: + cpp_interface_file_translate(idl_file, out_dir, part, outputs) + elif idl_file_type == IdlType.CALLBACK: + cpp_callback_file_translate(idl_file, out_dir, part, outputs) + elif idl_file_type == IdlType.TYPES: + cpp_types_file_translate(idl_file, out_dir, outputs) + return outputs + +def get_compile_source_file(idl_files, language, out_dir, part): + outputs = [] + if language == "c": + outputs = c_get_compile_source_file(idl_files, out_dir, part) + elif language == "cpp": + outputs = cpp_get_compile_source_file(idl_files, out_dir, part) + return outputs + +def main(argv): + outputs = [] + if len(argv) < 4: + return outputs + + option = argv[1] + language = argv[2] + out_dir = argv[3] + files = argv[4:] + + if option == "-o": + outputs = idl_translate(files, language, out_dir) + elif option == "-c": + outputs = get_compile_source_file(argv[4:], language, out_dir, "client_lib_source") + elif option == "-s": + outputs = get_compile_source_file(argv[4:], language, out_dir, "server_lib_source") + + sys.stdout.write('\n'.join(outputs)) + +if __name__ == "__main__": + main(sys.argv) \ No newline at end of file diff --git a/tools/hdi-gen/codegen/c_client_proxy_code_emitter.cpp b/tools/hdi-gen/codegen/c_client_proxy_code_emitter.cpp index fd93f37b..b28d9ca2 100755 --- a/tools/hdi-gen/codegen/c_client_proxy_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_client_proxy_code_emitter.cpp @@ -14,10 +14,8 @@ namespace OHOS { namespace HDI { bool CClientProxyCodeEmitter::ResolveDirectory(const String& targetDirectory) { - if (ast_->GetASTFileType() == ASTFileType::AST_IFACE) { - directory_ = File::AdapterPath(String::Format("%s/%s/client/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); - } else if (ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { + if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || + ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), FileName(ast_->GetPackageName()).string())); } else { @@ -34,45 +32,9 @@ bool CClientProxyCodeEmitter::ResolveDirectory(const String& targetDirectory) void CClientProxyCodeEmitter::EmitCode() { - if (isCallbackInterface()) { - EmitCbProxyHeaderFile(); - } EmitProxySourceFile(); } -void CClientProxyCodeEmitter::EmitCbProxyHeaderFile() -{ - String filePath = String::Format("%s%s.h", directory_.string(), FileName(proxyName_).string()); - File file(filePath, File::WRITE); - StringBuilder sb; - - EmitLicense(sb); - EmitHeadMacro(sb, proxyFullName_); - sb.Append("\n"); - sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string()); - sb.Append("\n"); - EmitHeadExternC(sb); - sb.Append("\n"); - EmitCbProxyMethodsDcl(sb); - sb.Append("\n"); - EmitTailExternC(sb); - sb.Append("\n"); - EmitTailMacro(sb, proxyFullName_); - - String data = sb.ToString(); - file.WriteData(data.string(), data.GetLength()); - file.Flush(); - file.Close(); -} - -void CClientProxyCodeEmitter::EmitCbProxyMethodsDcl(StringBuilder& sb) -{ - sb.AppendFormat("struct %s *%sProxyObtain(struct HdfRemoteService *remote);\n", - interfaceName_.string(), infName_.string()); - sb.Append("\n"); - sb.AppendFormat("void %sProxyRelease(struct %s *callback);\n", infName_.string(), interfaceName_.string()); -} - void CClientProxyCodeEmitter::EmitProxySourceFile() { String filePath = String::Format("%s%s.c", directory_.string(), FileName(proxyName_).string()); @@ -82,7 +44,7 @@ void CClientProxyCodeEmitter::EmitProxySourceFile() EmitLicense(sb); EmitProxyInclusions(sb); sb.Append("\n"); - EmitHeadExternC(sb); + EmitProxyDefinition(sb); sb.Append("\n"); EmitProxyCallMethodImpl(sb); sb.Append("\n"); @@ -91,23 +53,24 @@ void CClientProxyCodeEmitter::EmitProxySourceFile() EmitProxyConstruction(sb); if (!isCallbackInterface()) { sb.Append("\n"); - if (isKernelCode_) { - EmitKernelProxyGetMethodImpl(sb); - } else { - EmitProxyGetMethodImpl(sb); - } + EmitProxyGetMethodImpl(sb); sb.Append("\n"); - EmitProxyReleaseMethodImpl(sb); + if (isKernelCode_) { + EmitKernelProxyGetInstanceMethodImpl(sb); + sb.Append("\n"); + EmitKernelProxyReleaseMethodImpl(sb); + } else { + EmitProxyGetInstanceMethodImpl(sb); + sb.Append("\n"); + EmitProxyReleaseMethodImpl(sb); + } } else { sb.Append("\n"); - EmitCbProxyObtainMethodImpl(sb); + EmitCbProxyGetMethodImpl(sb); sb.Append("\n"); - EmitCbProxyReleaseMethodImpl(sb); + EmitProxyReleaseMethodImpl(sb); } - sb.Append("\n"); - EmitTailExternC(sb); - String data = sb.ToString(); file.WriteData(data.string(), data.GetLength()); file.Flush(); @@ -116,18 +79,17 @@ void CClientProxyCodeEmitter::EmitProxySourceFile() void CClientProxyCodeEmitter::EmitProxyInclusions(StringBuilder& sb) { - if (!isCallbackInterface()) { - EmitProxyStdlibInclusions(sb); - sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string()); - } else { - sb.AppendFormat("#include \"%s.h\"\n", FileName(proxyName_).string()); - EmitProxyStdlibInclusions(sb); - } + EmitProxyStdlibInclusions(sb); + sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string()); } void CClientProxyCodeEmitter::EmitProxyStdlibInclusions(StringBuilder& sb) { sb.Append("#include \n"); + if (!isCallbackInterface() && !isKernelCode_) { + sb.Append("#include \n"); + } + sb.Append("#include \n"); sb.Append("#include \n"); sb.Append("#include \n"); @@ -148,6 +110,19 @@ void CClientProxyCodeEmitter::EmitProxyStdlibInclusions(StringBuilder& sb) } } +void CClientProxyCodeEmitter::EmitProxyDefinition(StringBuilder& sb) +{ + sb.AppendFormat("struct %sProxy {\n", infName_.string()); + sb.Append(g_tab).AppendFormat("struct %s instance;\n", interfaceName_.string()); + if (isKernelCode_) { + sb.Append(g_tab).Append("struct HdfIoService *serv;\n"); + } else { + sb.Append(g_tab).Append("struct HdfRemoteService *remote;\n"); + } + + sb.Append("};\n"); +} + void CClientProxyCodeEmitter::EmitProxyCallMethodImpl(StringBuilder& sb) { sb.AppendFormat("static int32_t %sProxyCall(struct %s *self, int32_t id, struct HdfSBuf *data,\n", @@ -155,19 +130,29 @@ void CClientProxyCodeEmitter::EmitProxyCallMethodImpl(StringBuilder& sb) sb.Append(g_tab).Append("struct HdfSBuf *reply)\n"); sb.Append("{\n"); + String proxyName = "self"; + if (!isCallbackInterface()) { + sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(self, struct %sProxy, instance);\n", + infName_.string(), infName_.string()); + proxyName = "proxy"; + } + String remoteName = isKernelCode_ ? "serv" : "remote"; - sb.Append(g_tab).AppendFormat("if (self->%s == NULL\n", remoteName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("|| self->%s->dispatcher == NULL\n", remoteName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("|| self->%s->dispatcher->Dispatch == NULL) {\n", remoteName.string()); + sb.Append(g_tab).AppendFormat("if (%s->%s == NULL\n", proxyName.string(), remoteName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("|| %s->%s->dispatcher == NULL\n", + proxyName.string(), remoteName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("|| %s->%s->dispatcher->Dispatch == NULL) {\n", + proxyName.string(), remoteName.string()); sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: obj is null\", __func__);\n"); sb.Append(g_tab).Append(g_tab).Append("return HDF_ERR_INVALID_OBJECT;\n"); sb.Append(g_tab).Append("}\n"); if (isKernelCode_) { - sb.Append(g_tab).Append("return self->serv->dispatcher->Dispatch"); - sb.Append("((struct HdfObject *)&(self->serv->object), id, data, reply);\n"); + sb.Append(g_tab).AppendFormat("return %s->serv->dispatcher->Dispatch", proxyName.string()); + sb.AppendFormat("((struct HdfObject *)&(%s->serv->object), id, data, reply);\n", proxyName.string()); } else { - sb.Append(g_tab).Append("return self->remote->dispatcher->Dispatch(self->remote, id, data, reply);\n"); + sb.Append(g_tab).AppendFormat("return %s->remote->dispatcher->Dispatch(%s->remote, id, data, reply);\n", + proxyName.string(), proxyName.string()); } sb.Append("}\n"); } @@ -365,16 +350,9 @@ String CClientProxyCodeEmitter::GetGotLabel(const AutoPtr& method) void CClientProxyCodeEmitter::EmitProxyConstruction(StringBuilder& sb) { - String objName; - if (!isCallbackInterface()) { - objName = "inst"; - sb.AppendFormat("static void %sConstruct(struct %s *%s)\n", - infName_.string(), interfaceName_.string(), objName.string()); - } else { - objName = "callback"; - sb.AppendFormat("static void %sProxyConstruct(struct %s *%s)\n", - infName_.string(), interfaceName_.string(), objName.string()); - } + String objName = "instance"; + sb.AppendFormat("static void %sProxyConstruct(struct %s *%s)\n", + infName_.string(), interfaceName_.string(), objName.string()); sb.Append("{\n"); for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { @@ -388,7 +366,16 @@ void CClientProxyCodeEmitter::EmitProxyConstruction(StringBuilder& sb) void CClientProxyCodeEmitter::EmitProxyGetMethodImpl(StringBuilder& sb) { - sb.AppendFormat("struct %s *Hdi%sGet()\n", interfaceName_.string(), infName_.string()); + sb.AppendFormat("struct %s *%sGet()\n", interfaceName_.string(), infName_.string()); + sb.Append("{\n"); + sb.Append(g_tab).AppendFormat("return %sGetInstance(\"%s\");\n", infName_.string(), FileName(implName_).string()); + sb.Append("}\n"); +} + +void CClientProxyCodeEmitter::EmitProxyGetInstanceMethodImpl(StringBuilder& sb) +{ + sb.AppendFormat("struct %s *%sGetInstance(const char *instanceName)\n", + interfaceName_.string(), infName_.string()); sb.Append("{\n"); sb.Append(g_tab).Append("struct HDIServiceManager *serviceMgr = HDIServiceManagerGet();\n"); sb.Append(g_tab).Append("if (serviceMgr == NULL) {\n"); @@ -398,7 +385,7 @@ void CClientProxyCodeEmitter::EmitProxyGetMethodImpl(StringBuilder& sb) sb.Append("\n"); sb.Append(g_tab).Append("struct HdfRemoteService *remote = "); - sb.AppendFormat("serviceMgr->GetService(serviceMgr, \"%sService\");\n", infName_.string()); + sb.Append("serviceMgr->GetService(serviceMgr, instanceName);\n"); sb.Append(g_tab).Append("HDIServiceManagerRelease(serviceMgr);\n"); sb.Append(g_tab).Append("if (remote == NULL) {\n"); sb.Append(g_tab).Append(g_tab).AppendFormat( @@ -407,28 +394,28 @@ void CClientProxyCodeEmitter::EmitProxyGetMethodImpl(StringBuilder& sb) sb.Append(g_tab).Append("}\n"); sb.Append("\n"); - sb.Append(g_tab).AppendFormat("struct %s *%sClient = (struct %s *)OsalMemAlloc(sizeof(struct %s));\n", - interfaceName_.string(), infName_.string(), interfaceName_.string(), interfaceName_.string()); - sb.Append(g_tab).AppendFormat("if (%sClient == NULL) {\n", infName_.string()); + sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = ", infName_.string()); + sb.AppendFormat("(struct %sProxy *)OsalMemAlloc(sizeof(struct %sProxy));\n", infName_.string(), infName_.string()); + sb.Append(g_tab).Append("if (proxy == NULL) {\n"); sb.Append(g_tab).Append(g_tab).AppendFormat( - "HDF_LOGE(\"%%{public}s: malloc %s instance failed!\", __func__);\n", interfaceName_.string()); + "HDF_LOGE(\"%%{public}s: malloc %s proxy failed!\", __func__);\n", interfaceName_.string()); sb.Append(g_tab).Append(g_tab).Append("HdfRemoteServiceRecycle(remote);\n"); sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); sb.Append(g_tab).Append("}\n"); sb.Append("\n"); - sb.Append(g_tab).AppendFormat("%sClient->remote = remote;\n", infName_.string()); - sb.Append(g_tab).AppendFormat("%sConstruct(%sClient);\n", infName_.string(), infName_.string()); - sb.Append(g_tab).AppendFormat("return %sClient;\n", infName_.string()); + sb.Append(g_tab).Append("proxy->remote = remote;\n"); + sb.Append(g_tab).AppendFormat("%sProxyConstruct(&proxy->instance);\n", infName_.string()); + sb.Append(g_tab).Append("return &proxy->instance;\n"); sb.Append("}\n"); } -void CClientProxyCodeEmitter::EmitKernelProxyGetMethodImpl(StringBuilder& sb) +void CClientProxyCodeEmitter::EmitKernelProxyGetInstanceMethodImpl(StringBuilder& sb) { - sb.AppendFormat("struct %s *Hdi%sGet()\n", interfaceName_.string(), infName_.string()); + sb.AppendFormat("struct %s *%sGetInstance(const char* serviceName)\n", interfaceName_.string(), infName_.string()); sb.Append("{\n"); sb.Append(g_tab).AppendFormat("struct HdfIoService *serv = "); - sb.AppendFormat("HdfIoServiceBind(\"%s\");\n", infName_.string()); + sb.Append("HdfIoServiceBind(serviceName);\n"); sb.Append(g_tab).Append("if (serv == NULL) {\n"); sb.Append(g_tab).Append(g_tab).AppendFormat( "HDF_LOGE(\"%%{public}s: %sService not found!\", __func__);\n", infName_.string()); @@ -436,64 +423,69 @@ void CClientProxyCodeEmitter::EmitKernelProxyGetMethodImpl(StringBuilder& sb) sb.Append(g_tab).Append("}\n"); sb.Append("\n"); - sb.Append(g_tab).AppendFormat("struct %s *%sClient = (struct %s *)OsalMemAlloc(sizeof(struct %s));\n", - interfaceName_.string(), infName_.string(), interfaceName_.string(), interfaceName_.string()); - sb.Append(g_tab).AppendFormat("if (%sClient == NULL) {\n", infName_.string()); + sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = (struct %sProxy *)OsalMemAlloc(sizeof(struct %sProxy));\n", + infName_.string(), infName_.string(), infName_.string()); + sb.Append(g_tab).Append("if (proxy == NULL) {\n"); sb.Append(g_tab).Append(g_tab).AppendFormat( - "HDF_LOGE(\"%%{public}s: malloc %s instance failed!\", __func__);\n", interfaceName_.string()); + "HDF_LOGE(\"%%{public}s: malloc %s proxy failed!\", __func__);\n", interfaceName_.string()); sb.Append(g_tab).Append(g_tab).Append("HdfIoServiceRecycle(serv);\n"); sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); sb.Append(g_tab).Append("}\n"); sb.Append("\n"); - sb.Append(g_tab).AppendFormat("%sClient->serv = serv;\n", infName_.string()); - sb.Append(g_tab).AppendFormat("%sConstruct(%sClient);\n", infName_.string(), infName_.string()); - sb.Append(g_tab).AppendFormat("return %sClient;\n", infName_.string()); + sb.Append(g_tab).Append("proxy->serv = serv;\n"); + sb.Append(g_tab).AppendFormat("%sProxyConstruct(&proxy->instance);\n", infName_.string()); + sb.Append(g_tab).Append("return &proxy->instance;\n"); + sb.Append("}\n"); +} + +void CClientProxyCodeEmitter::EmitCbProxyGetMethodImpl(StringBuilder& sb) +{ + sb.AppendFormat("struct %s *%sGet(struct HdfRemoteService *remote)\n", + interfaceName_.string(), infName_.string()); + sb.Append("{\n"); + sb.Append(g_tab).AppendFormat("struct %s *instance = (struct %s*)OsalMemAlloc(sizeof(struct %s));\n", + interfaceName_.string(), interfaceName_.string(), interfaceName_.string()); + sb.Append(g_tab).Append("if (instance == NULL) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: OsalMemAlloc failed!\", __func__);\n"); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).Append("instance->remote = remote;\n"); + sb.Append(g_tab).AppendFormat("%sProxyConstruct(instance);\n", infName_.string()); + sb.Append(g_tab).Append("return instance;\n"); sb.Append("}\n"); } void CClientProxyCodeEmitter::EmitProxyReleaseMethodImpl(StringBuilder& sb) { - sb.AppendFormat("void Hdi%sRelease(struct %s *instance)\n", infName_.string(), interfaceName_.string()); + sb.AppendFormat("void %sRelease(struct %s *instance)\n", infName_.string(), interfaceName_.string()); sb.Append("{\n"); sb.Append(g_tab).Append("if (instance == NULL) {\n"); sb.Append(g_tab).Append(g_tab).Append("return;\n"); sb.Append(g_tab).Append("}\n"); - if (isKernelCode_) { - sb.Append(g_tab).Append("HdfIoServiceRecycle(instance->serv);\n"); + if (!isCallbackInterface()) { + sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, instance);\n", + infName_.string(), infName_.string()); + sb.Append(g_tab).Append("HdfRemoteServiceRecycle(proxy->remote);\n"); + sb.Append(g_tab).Append("OsalMemFree(proxy);\n"); } else { - sb.Append(g_tab).Append("HdfRemoteServiceRecycle(instance->remote);\n"); + sb.Append(g_tab).Append("OsalMemFree(instance);\n"); } - sb.Append(g_tab).Append("OsalMemFree(instance);\n"); sb.Append("}\n"); } -void CClientProxyCodeEmitter::EmitCbProxyObtainMethodImpl(StringBuilder& sb) +void CClientProxyCodeEmitter::EmitKernelProxyReleaseMethodImpl(StringBuilder& sb) { - sb.AppendFormat("struct %s *%sProxyObtain(struct HdfRemoteService *remote)\n", - interfaceName_.string(), infName_.string()); + sb.AppendFormat("void %sRelease(struct %s *instance)\n", infName_.string(), interfaceName_.string()); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("struct %s *callback = (struct %s*)OsalMemAlloc(sizeof(struct %s));\n", - interfaceName_.string(), interfaceName_.string(), interfaceName_.string()); - sb.Append(g_tab).Append("if (callback == NULL) {\n"); - sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: OsalMemAlloc failed!\", __func__);\n"); - sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).Append("callback->remote = remote;\n"); - sb.Append(g_tab).AppendFormat("%sProxyConstruct(callback);\n", infName_.string()); - sb.Append(g_tab).Append("return callback;\n"); - sb.Append("}\n"); -} - -void CClientProxyCodeEmitter::EmitCbProxyReleaseMethodImpl(StringBuilder& sb) -{ - sb.AppendFormat("void %sProxyRelease(struct %s *callback)\n", infName_.string(), interfaceName_.string()); - sb.Append("{\n"); - sb.Append(g_tab).Append("if (callback == NULL) {\n"); + sb.Append(g_tab).Append("if (instance == NULL) {\n"); sb.Append(g_tab).Append(g_tab).Append("return;\n"); sb.Append(g_tab).Append("}\n"); - sb.Append(g_tab).Append("OsalMemFree(callback);\n"); + sb.Append(g_tab).AppendFormat("struct %sProxy *proxy = CONTAINER_OF(instance, struct %sProxy, instance);\n", + infName_.string(), infName_.string()); + sb.Append(g_tab).Append("HdfIoServiceRecycle(proxy->serv);\n"); + sb.Append(g_tab).Append("OsalMemFree(proxy);\n"); sb.Append("}\n"); } } // namespace HDI diff --git a/tools/hdi-gen/codegen/c_client_proxy_code_emitter.h b/tools/hdi-gen/codegen/c_client_proxy_code_emitter.h index 41d78d8d..83daa85a 100755 --- a/tools/hdi-gen/codegen/c_client_proxy_code_emitter.h +++ b/tools/hdi-gen/codegen/c_client_proxy_code_emitter.h @@ -23,11 +23,9 @@ private: void EmitCode() override; - void EmitCbProxyHeaderFile(); - void EmitProxySourceFile(); - void EmitCbProxyMethodsDcl(StringBuilder& sb); + void EmitProxyDefinition(StringBuilder& sb); void EmitProxyInclusions(StringBuilder& sb); @@ -54,13 +52,15 @@ private: void EmitProxyGetMethodImpl(StringBuilder& sb); - void EmitKernelProxyGetMethodImpl(StringBuilder& sb); + void EmitProxyGetInstanceMethodImpl(StringBuilder& sb); + + void EmitKernelProxyGetInstanceMethodImpl(StringBuilder& sb); + + void EmitCbProxyGetMethodImpl(StringBuilder& sb); void EmitProxyReleaseMethodImpl(StringBuilder& sb); - void EmitCbProxyObtainMethodImpl(StringBuilder& sb); - - void EmitCbProxyReleaseMethodImpl(StringBuilder& sb); + void EmitKernelProxyReleaseMethodImpl(StringBuilder& sb); std::vector freeObjStatements_; }; diff --git a/tools/hdi-gen/codegen/c_custom_types_code_emitter.cpp b/tools/hdi-gen/codegen/c_custom_types_code_emitter.cpp index 8d59af57..1ba4a9a9 100755 --- a/tools/hdi-gen/codegen/c_custom_types_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_custom_types_code_emitter.cpp @@ -37,7 +37,7 @@ void CCustomTypesCodeEmitter::EmitCode() void CCustomTypesCodeEmitter::EmitCustomTypesHeaderFile() { - String filePath = String::Format("%s%s.h", directory_.string(), FileName(infName_).string()); + String filePath = String::Format("%s/%s.h", directory_.string(), FileName(infName_).string()); File file(filePath, File::WRITE); StringBuilder sb; diff --git a/tools/hdi-gen/codegen/c_interface_code_emitter.cpp b/tools/hdi-gen/codegen/c_interface_code_emitter.cpp new file mode 100755 index 00000000..47b5f421 --- /dev/null +++ b/tools/hdi-gen/codegen/c_interface_code_emitter.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "codegen/c_interface_code_emitter.h" +#include "util/file.h" +#include "util/logger.h" + +namespace OHOS { +namespace HDI { +bool CInterfaceCodeEmitter::ResolveDirectory(const String& targetDirectory) +{ + if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || + ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { + directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), + FileName(ast_->GetPackageName()).string())); + } else { + return false; + } + + if (!File::CreateParentDir(directory_)) { + Logger::E("CInterfaceCodeEmitter", "Create '%s' failed!", directory_.string()); + return false; + } + + return true; +} + +void CInterfaceCodeEmitter::EmitCode() +{ + EmitInterfaceHeaderFile(); +} + +void CInterfaceCodeEmitter::EmitInterfaceHeaderFile() +{ + String filePath = String::Format("%s%s.h", directory_.string(), FileName(interfaceName_).string()); + File file(filePath, File::WRITE); + StringBuilder sb; + + EmitLicense(sb); + EmitHeadMacro(sb, interfaceFullName_); + sb.Append("\n"); + EmitImportInclusions(sb); + sb.Append("\n"); + EmitHeadExternC(sb); + sb.Append("\n"); + EmitInterfaceMethodCommands(sb); + sb.Append("\n"); + EmitInterfaceDefinition(sb); + sb.Append("\n"); + EmitInterfaceGetMethodDecl(sb); + sb.Append("\n"); + EmitInterfaceReleaseMethodDecl(sb); + sb.Append("\n"); + EmitTailExternC(sb); + sb.Append("\n"); + EmitTailMacro(sb, interfaceFullName_); + + String data = sb.ToString(); + file.WriteData(data.string(), data.GetLength()); + file.Flush(); + file.Close(); +} + +void CInterfaceCodeEmitter::EmitImportInclusions(StringBuilder& sb) +{ + sb.Append("#include \n"); + for (const auto& importPair : ast_->GetImports()) { + AutoPtr importAst = importPair.second; + sb.AppendFormat("#include \"%s.h\"\n", FileName(importAst->GetFullName()).string()); + } +} + +void CInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder& sb) +{ + sb.AppendFormat("struct %s {\n", interfaceName_.string()); + if (isCallbackInterface()) { + sb.Append(g_tab).Append("struct HdfRemoteService *remote;\n"); + sb.Append("\n"); + } + EmitInterfaceMethods(sb, g_tab); + sb.Append("};\n"); +} + +void CInterfaceCodeEmitter::EmitInterfaceMethods(StringBuilder& sb, const String& prefix) +{ + for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { + AutoPtr method = interface_->GetMethod(i); + EmitInterfaceMethod(method, sb, prefix); + if (i + 1 < interface_->GetMethodNumber()) { + sb.Append("\n"); + } + } +} + +void CInterfaceCodeEmitter::EmitInterfaceMethod(const AutoPtr& method, StringBuilder& sb, + const String& prefix) +{ + if (method->GetParameterNumber() == 0) { + sb.Append(prefix).AppendFormat("int32_t (*%s)(struct %s *self);\n", + method->GetName().string(), interfaceName_.string()); + } else { + StringBuilder paramStr; + paramStr.Append(prefix).AppendFormat("int32_t (*%s)(struct %s *self, ", + method->GetName().string(), interfaceName_.string()); + for (size_t i = 0; i < method->GetParameterNumber(); i++) { + AutoPtr param = method->GetParameter(i); + EmitInterfaceMethodParameter(param, paramStr, ""); + if (i + 1 < method->GetParameterNumber()) { + paramStr.Append(", "); + } + } + + paramStr.Append(");"); + sb.Append(SpecificationParam(paramStr, prefix + g_tab)); + sb.Append("\n"); + } +} + +void CInterfaceCodeEmitter::EmitInterfaceGetMethodDecl(StringBuilder& sb) +{ + String methodParamStr = isCallbackInterface() ? "struct HdfRemoteService *remote" : "void"; + sb.AppendFormat("struct %s *%sGet(%s);\n", interfaceName_.string(), infName_.string(), methodParamStr.string()); + if (!isCallbackInterface()) { + sb.Append("\n"); + sb.AppendFormat("struct %s *%sGetInstance(const char *instanceName);\n", + interfaceName_.string(), infName_.string()); + } +} + +void CInterfaceCodeEmitter::EmitInterfaceReleaseMethodDecl(StringBuilder& sb) +{ + sb.AppendFormat("void %sRelease(struct %s *instance);\n", infName_.string(), interfaceName_.string()); +} + +} // namespace HDI +} // namespace OHOS \ No newline at end of file diff --git a/tools/hdi-gen/codegen/c_interface_code_emitter.h b/tools/hdi-gen/codegen/c_interface_code_emitter.h new file mode 100755 index 00000000..a4e76b85 --- /dev/null +++ b/tools/hdi-gen/codegen/c_interface_code_emitter.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef OHOS_HDI_C_CLIENT_INTERFACE_CODE_EMITTER_H +#define OHOS_HDI_C_CLIENT_INTERFACE_CODE_EMITTER_H + +#include "codegen/c_code_emitter.h" + +namespace OHOS { +namespace HDI { +class CInterfaceCodeEmitter : public CCodeEmitter { +public: + CInterfaceCodeEmitter() : CCodeEmitter() {} + + virtual ~CInterfaceCodeEmitter() = default; +private: + bool ResolveDirectory(const String& targetDirectory) override; + + void EmitCode() override; + + void EmitInterfaceHeaderFile(); + + void EmitImportInclusions(StringBuilder& sb); + + void EmitInterfaceDefinition(StringBuilder& sb); + + void EmitInterfaceMethods(StringBuilder& sb, const String& prefix); + + void EmitInterfaceMethod(const AutoPtr& method, StringBuilder& sb, const String& prefix); + + void EmitInterfaceGetMethodDecl(StringBuilder& sb); + + void EmitInterfaceReleaseMethodDecl(StringBuilder& sb); + +}; + +} // namespace HDI +} // namespace OHOS + +#endif // OHOS_HDI_C_CLIENT_INTERFACE_CODE_EMITTER_H \ No newline at end of file diff --git a/tools/hdi-gen/codegen/c_service_driver_code_emitter.cpp b/tools/hdi-gen/codegen/c_service_driver_code_emitter.cpp index 502b3de7..d0332756 100755 --- a/tools/hdi-gen/codegen/c_service_driver_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_service_driver_code_emitter.cpp @@ -9,6 +9,7 @@ #include "codegen/c_service_driver_code_emitter.h" #include "util/file.h" #include "util/logger.h" +#include "util/options.h" namespace OHOS { namespace HDI { @@ -18,7 +19,7 @@ bool CServiceDriverCodeEmitter::ResolveDirectory(const String& targetDirectory) return false; } - directory_ = File::AdapterPath(String::Format("%s/%s/server/", targetDirectory.string(), + directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), FileName(ast_->GetPackageName()).string())); if (!File::CreateParentDir(directory_)) { Logger::E("CServiceDriverCodeEmitter", "Create '%s' failed!", directory_.string()); @@ -69,12 +70,12 @@ void CServiceDriverCodeEmitter::EmitDriverIncluions(StringBuilder& sb) sb.Append("#include \n"); sb.Append("#include \n"); sb.Append("#include \n"); - sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string()); + sb.AppendFormat("#include \"%s.h\"\n", FileName(stubName_).string()); } void CServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder& sb) { - sb.AppendFormat("struct Hdf%sService {\n", infName_.string()); + sb.AppendFormat("struct Hdf%sHost {\n", infName_.string()); sb.Append(g_tab).AppendFormat("struct IDeviceIoService ioservice;\n"); sb.Append(g_tab).Append("void *instance;\n"); sb.Append("};\n"); @@ -82,16 +83,17 @@ void CServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder& sb) void CServiceDriverCodeEmitter::EmitDriverDispatch(StringBuilder& sb) { - sb.AppendFormat("static int32_t %sServiceDispatch(struct HdfDeviceIoClient *client, int cmdId,\n", + String hostName = infName_.ToLowerCase() + "Host"; + sb.AppendFormat("static int32_t %sDriverDispatch(struct HdfDeviceIoClient *client, int cmdId,\n", infName_.string()); sb.Append(g_tab).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n"); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("struct Hdf%sService *hdf%sService = CONTAINER_OF(\n", - infName_.string(), infName_.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("client->device->service, struct Hdf%sService, ioservice);\n", + sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(\n", + infName_.string(), hostName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("client->device->service, struct Hdf%sHost, ioservice);\n", infName_.string()); - sb.Append(g_tab).AppendFormat("return %sServiceOnRemoteRequest(hdf%sService->instance, cmdId, data, reply);\n", - infName_.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("return %sServiceOnRemoteRequest(%s->instance, cmdId, data, reply);\n", + infName_.string(), hostName.string()); sb.Append("}\n"); } @@ -99,51 +101,53 @@ void CServiceDriverCodeEmitter::EmitDriverInit(StringBuilder& sb) { sb.AppendFormat("int Hdf%sDriverInit(struct HdfDeviceObject *deviceObject)\n", infName_.string()); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverInit enter, new hdi impl.\");\n", infName_.string()); + sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverInit enter.\");\n", infName_.string()); sb.Append(g_tab).Append("return HDF_SUCCESS;\n"); sb.Append("}\n"); } void CServiceDriverCodeEmitter::EmitDriverBind(StringBuilder& sb) { + String hostName = infName_.ToLowerCase() + "Host"; sb.AppendFormat("int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", infName_.string()); sb.Append("{\n"); sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverBind enter.\");\n", infName_.string()); sb.Append("\n"); - sb.Append(g_tab).AppendFormat("struct Hdf%sService *hdf%sService = (struct Hdf%sService *)OsalMemAlloc(\n", - infName_.string(), infName_.string(), infName_.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("sizeof(struct Hdf%sService));\n", infName_.string()); - sb.Append(g_tab).AppendFormat("if (hdf%sService == NULL) {\n", infName_.string()); + sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = (struct Hdf%sHost *)OsalMemAlloc(\n", + infName_.string(), hostName.string(), infName_.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("sizeof(struct Hdf%sHost));\n", infName_.string()); + sb.Append(g_tab).AppendFormat("if (%s == NULL) {\n", hostName.string()); sb.Append(g_tab).Append(g_tab).AppendFormat( - "HDF_LOGE(\"Hdf%sDriverBind OsalMemAlloc Hdf%sService failed!\");\n", infName_.string(), infName_.string()); + "HDF_LOGE(\"Hdf%sDriverBind OsalMemAlloc Hdf%sHost failed!\");\n", infName_.string(), infName_.string()); sb.Append(g_tab).Append(g_tab).Append("return HDF_FAILURE;\n"); sb.Append(g_tab).Append("}\n"); sb.Append("\n"); - sb.Append(g_tab).AppendFormat("hdf%sService->ioservice.Dispatch = %sServiceDispatch;\n", - infName_.string(), infName_.string()); - sb.Append(g_tab).AppendFormat("hdf%sService->ioservice.Open = NULL;\n", infName_.string()); - sb.Append(g_tab).AppendFormat("hdf%sService->ioservice.Release = NULL;\n", infName_.string()); - sb.Append(g_tab).AppendFormat("hdf%sService->instance = Hdi%sInstance();\n", infName_.string(), infName_.string()); - sb.Append(g_tab).AppendFormat("if (hdf%sService->instance == NULL) {\n", infName_.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("OsalMemFree(hdf%sService);\n", infName_.string()); + sb.Append(g_tab).AppendFormat("%s->ioservice.Dispatch = %sDriverDispatch;\n", + hostName.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("%s->ioservice.Open = NULL;\n", hostName.string()); + sb.Append(g_tab).AppendFormat("%s->ioservice.Release = NULL;\n", hostName.string()); + sb.Append(g_tab).AppendFormat("%s->instance = %sStubGetInstance();\n", hostName.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("if (%s->instance == NULL) {\n", hostName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("OsalMemFree(%s);\n", hostName.string()); sb.Append(g_tab).Append(g_tab).Append("return HDF_FAILURE;\n"); sb.Append(g_tab).Append("}\n"); sb.Append("\n"); - sb.Append(g_tab).AppendFormat("deviceObject->service = &hdf%sService->ioservice;\n", infName_.string()); + sb.Append(g_tab).AppendFormat("deviceObject->service = &%s->ioservice;\n", hostName.string()); sb.Append(g_tab).Append("return HDF_SUCCESS;\n"); sb.Append("}\n"); } void CServiceDriverCodeEmitter::EmitDriverRelease(StringBuilder& sb) { + String hostName = infName_.ToLowerCase() + "Host"; sb.AppendFormat("void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)\n", infName_.string()); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("struct Hdf%sService *hdf%sService = CONTAINER_OF(\n", - infName_.string(), infName_.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("deviceObject->service, struct Hdf%sService, ioservice);\n", + sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverRelease enter.\");\n", infName_.string()); + sb.Append(g_tab).AppendFormat("struct Hdf%sHost *%s = CONTAINER_OF(", infName_.string(), hostName.string()); + sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioservice);\n", infName_.string()); - sb.Append(g_tab).AppendFormat("Hdi%sRelease(hdf%sService->instance);\n", infName_.string(), infName_.string()); - sb.Append(g_tab).AppendFormat("OsalMemFree(hdf%sService);\n", infName_.string()); + sb.Append(g_tab).AppendFormat("%sStubRelease(%s->instance);\n", infName_.string(), hostName.string()); + sb.Append(g_tab).AppendFormat("OsalMemFree(%s);\n", hostName.string()); sb.Append("}\n"); } @@ -151,7 +155,8 @@ void CServiceDriverCodeEmitter::EmitDriverEntryDefinition(StringBuilder& sb) { sb.AppendFormat("struct HdfDriverEntry g_%sDriverEntry = {\n", infName_.ToLowerCase().string()); sb.Append(g_tab).Append(".moduleVersion = 1,\n"); - sb.Append(g_tab).Append(".moduleName = \"sample\", /* please change the moduleName */\n"); + sb.Append(g_tab).AppendFormat(".moduleName = \"%s\",\n", + Options::GetInstance().GetModeName().string()); sb.Append(g_tab).AppendFormat(".Bind = Hdf%sDriverBind,\n", infName_.string()); sb.Append(g_tab).AppendFormat(".Init = Hdf%sDriverInit,\n", infName_.string()); sb.Append(g_tab).AppendFormat(".Release = Hdf%sDriverRelease,\n", infName_.string()); diff --git a/tools/hdi-gen/codegen/c_service_impl_code_emitter.cpp b/tools/hdi-gen/codegen/c_service_impl_code_emitter.cpp index d6f090d8..2ea8fdf2 100755 --- a/tools/hdi-gen/codegen/c_service_impl_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_service_impl_code_emitter.cpp @@ -14,10 +14,8 @@ namespace OHOS { namespace HDI { bool CServiceImplCodeEmitter::ResolveDirectory(const String& targetDirectory) { - if (ast_->GetASTFileType() == ASTFileType::AST_IFACE) { - directory_ = File::AdapterPath(String::Format("%s/%s/server/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); - } else if (ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { + if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || + ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), FileName(ast_->GetPackageName()).string())); } else { @@ -34,9 +32,7 @@ bool CServiceImplCodeEmitter::ResolveDirectory(const String& targetDirectory) void CServiceImplCodeEmitter::EmitCode() { - if (isCallbackInterface()) { - EmitServiceImplHeaderFile(); - } + EmitServiceImplHeaderFile(); EmitServiceImplSourceFile(); } @@ -82,12 +78,6 @@ void CServiceImplCodeEmitter::EmitServiceImplSourceFile() EmitServiceImplMethodImpls(sb, ""); sb.Append("\n"); EmitServiceImplConstruct(sb); - if (!isCallbackInterface()) { - sb.Append("\n"); - EmitServiceImplInstance(sb); - sb.Append("\n"); - EmitServiceImplRelease(sb); - } String data = sb.ToString(); file.WriteData(data.string(), data.GetLength()); @@ -101,7 +91,7 @@ void CServiceImplCodeEmitter::EmitServiceImplInclusions(StringBuilder& sb) sb.Append("#include \n"); sb.Append("#include \n"); sb.Append("#include \n"); - sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string()); + sb.AppendFormat("#include \"%s.h\"\n", FileName(infName_ + "Service").string()); } void CServiceImplCodeEmitter::EmitServiceImplMethodImpls(StringBuilder& sb, const String& prefix) @@ -154,36 +144,7 @@ void CServiceImplCodeEmitter::EmitServiceImplConstruct(StringBuilder& sb) sb.Append(g_tab).AppendFormat("%s->%s = %s%s;\n", objName.string(), method->GetName().string(), infName_.string(), method->GetName().string()); } - sb.Append("}\n"); -} - -void CServiceImplCodeEmitter::EmitServiceImplInstance(StringBuilder& sb) -{ - String objName("instance"); - sb.AppendFormat("struct %s *Hdi%sInstance()\n", interfaceName_.string(), infName_.string()); - sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("struct %s *%s = (struct %s*)OsalMemAlloc(sizeof(struct %s));\n", - interfaceName_.string(), objName.string(), interfaceName_.string(), interfaceName_.string()); - sb.Append(g_tab).AppendFormat("if (%s == NULL) {\n", objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat( - "HDF_LOGE(\"%%{public}s: OsalMemAlloc struct %s %s failed!\", __func__);\n", - interfaceName_.string(), objName.string()); - sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append(g_tab).AppendFormat("%sServiceConstruct(%s);\n", infName_.string(), objName.string()); - sb.Append(g_tab).AppendFormat("return %s;\n", objName.string()); - sb.Append("}\n"); -} - -void CServiceImplCodeEmitter::EmitServiceImplRelease(StringBuilder& sb) -{ - sb.AppendFormat("void Hdi%sRelease(struct %s *instance)\n", infName_.string(), interfaceName_.string()); - sb.Append("{\n"); - sb.Append(g_tab).Append("if (instance == NULL) {\n"); - sb.Append(g_tab).Append(g_tab).Append("return;\n"); - sb.Append(g_tab).Append("}\n"); - sb.Append(g_tab).Append("OsalMemFree(instance);\n"); - sb.Append("}\n"); + sb.Append("}"); } } // namespace HDI } // namespace OHOS \ No newline at end of file diff --git a/tools/hdi-gen/codegen/c_service_stub_code_emitter.cpp b/tools/hdi-gen/codegen/c_service_stub_code_emitter.cpp index 66bc51eb..9ecd7f52 100755 --- a/tools/hdi-gen/codegen/c_service_stub_code_emitter.cpp +++ b/tools/hdi-gen/codegen/c_service_stub_code_emitter.cpp @@ -15,10 +15,8 @@ namespace OHOS { namespace HDI { bool CServiceStubCodeEmitter::ResolveDirectory(const String& targetDirectory) { - if (ast_->GetASTFileType() == ASTFileType::AST_IFACE) { - directory_ = File::AdapterPath(String::Format("%s/%s/server/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); - } else if (ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { + if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || + ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), FileName(ast_->GetPackageName()).string())); } else { @@ -35,9 +33,8 @@ bool CServiceStubCodeEmitter::ResolveDirectory(const String& targetDirectory) void CServiceStubCodeEmitter::EmitCode() { - if (isCallbackInterface()) { - EmitCbServiceStubHeaderFile(); - } + + EmitCbServiceStubHeaderFile(); EmitServiceStubSourceFile(); } @@ -68,9 +65,14 @@ void CServiceStubCodeEmitter::EmitCbServiceStubHeaderFile() void CServiceStubCodeEmitter::EmitCbServiceStubMethodsDcl(StringBuilder& sb) { - sb.AppendFormat("struct %s* %sStubObtain();\n", interfaceName_.string(), infName_.string()); + if (!isCallbackInterface()) { + sb.AppendFormat("int32_t %sServiceOnRemoteRequest(void *service, int cmdId, ", infName_.string()); + sb.Append("struct HdfSBuf *data, struct HdfSBuf *reply);\n"); + sb.Append("\n"); + } + sb.AppendFormat("struct %s* %sStubGetInstance(void);\n", interfaceName_.string(), infName_.string()); sb.Append("\n"); - sb.AppendFormat("void %sStubRelease(struct %s *callback);\n", infName_.string(), interfaceName_.string()); + sb.AppendFormat("void %sStubRelease(struct %s *instance);\n", infName_.string(), interfaceName_.string()); } void CServiceStubCodeEmitter::EmitServiceStubSourceFile() @@ -82,16 +84,33 @@ void CServiceStubCodeEmitter::EmitServiceStubSourceFile() EmitLicense(sb); EmitServiceStubInclusions(sb); sb.Append("\n"); - EmitServiceStubMethodImpls(sb, ""); - sb.Append("\n"); - EmitServiceStubOnRequestMethodImpl(sb, ""); - if (isCallbackInterface()) { + + if (!isKernelCode_) { + EmitDriverLibPath(sb); + sb.Append("\n"); + EmitServConstructTypedef(sb); sb.Append("\n"); EmitCbStubDefinitions(sb); sb.Append("\n"); - EmitCbStubObtainImpl(sb); + } + + EmitServiceStubMethodImpls(sb, ""); + sb.Append("\n"); + EmitServiceStubOnRequestMethodImpl(sb, ""); + sb.Append("\n"); + if (isKernelCode_) { + EmitKernelStubGetMethodImpl(sb); + } else { + EmitStubLinkService(sb); sb.Append("\n"); - EmitCbStubReleaseImpl(sb); + EmitStubGetMethodImpl(sb); + } + + sb.Append("\n"); + if (isKernelCode_) { + EmitKernelStubReleaseImpl(sb); + } else { + EmitStubReleaseImpl(sb); } String data = sb.ToString(); @@ -104,9 +123,20 @@ void CServiceStubCodeEmitter::EmitServiceStubInclusions(StringBuilder& sb) { if (!isCallbackInterface()) { EmitServiceStubStdlibInclusions(sb); - sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string()); + sb.AppendFormat("#include \"%s.h\"\n", FileName(stubName_).string()); + if (isKernelCode_) { + sb.AppendFormat("#include \"%s.h\"\n", FileName(implName_).string()); + } else { + for (const auto& importPair : ast_->GetImports()) { + AutoPtr importAst = importPair.second; + if (importAst->GetASTFileType() == ASTFileType::AST_ICALLBACK) { + String fileName = FileName(importAst->GetInterfaceDef()->GetFullName()); + sb.AppendFormat("#include \"%s.h\"\n", fileName.string()); + } + } + } } else { - sb.AppendFormat("#include \"%s.h\"\n", FileName(stubFullName_).string()); + sb.AppendFormat("#include \"%s.h\"\n", FileName(stubName_).string()); EmitServiceStubStdlibInclusions(sb); sb.Append("#include \n"); sb.AppendFormat("#include \"%s.h\"\n", FileName(implName_).string()); @@ -115,23 +145,56 @@ void CServiceStubCodeEmitter::EmitServiceStubInclusions(StringBuilder& sb) void CServiceStubCodeEmitter::EmitServiceStubStdlibInclusions(StringBuilder& sb) { + if (!isKernelCode_) { + sb.Append("#include \n"); + } + sb.Append("#include \n"); sb.Append("#include \n"); sb.Append("#include \n"); sb.Append("#include \n"); sb.Append("#include \n"); - const AST::TypeStringMap& types = ast_->GetTypes(); - int i = 0; - for (const auto& pair : types) { - AutoPtr type = pair.second; - if (type->GetTypeKind() == TypeKind::TYPE_UNION) { - sb.Append("#include \n"); - break; + if (isKernelCode_) { + const AST::TypeStringMap& types = ast_->GetTypes(); + for (const auto& pair : types) { + AutoPtr type = pair.second; + if (type->GetTypeKind() == TypeKind::TYPE_UNION) { + sb.Append("#include \n"); + break; + } } + } else { + sb.Append("#include \n"); } } +void CServiceStubCodeEmitter::EmitDriverLibPath(StringBuilder& sb) +{ + sb.Append("#ifdef __ARM64__\n"); + sb.Append("#define DRIVER_PATH \"system/lib64\"\n"); + sb.Append("#else\n"); + sb.Append("#define DRIVER_PATH \"system/lib\"\n"); + sb.Append("#endif\n"); +} + +void CServiceStubCodeEmitter::EmitServConstructTypedef(StringBuilder& sb) +{ + typedef void (*SERVICE_CONSTRUCT_FUNC)(struct callbacks *); + sb.AppendFormat("typedef void (*SERVICE_CONSTRUCT_FUNC)(struct %s *);\n", interfaceName_.string()); +} + +void CServiceStubCodeEmitter::EmitCbStubDefinitions(StringBuilder& sb) +{ + sb.AppendFormat("struct %sStub {\n", infName_.string()); + sb.Append(g_tab).AppendFormat("struct %s service;\n", interfaceName_.string()); + if (isCallbackInterface()) { + sb.Append(g_tab).Append("struct HdfRemoteDispatcher dispatcher;\n"); + } + sb.Append(g_tab).Append("void *dlHandler;\n"); + sb.Append("};\n"); +} + void CServiceStubCodeEmitter::EmitServiceStubMethodImpls(StringBuilder& sb, const String& prefix) { for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { @@ -316,14 +379,15 @@ void CServiceStubCodeEmitter::EmitServiceStubOnRequestMethodImpl(StringBuilder& String codeName; if (!isCallbackInterface()) { codeName = "cmdId"; - sb.Append(prefix).AppendFormat("int32_t %sServiceOnRemoteRequest(void *service, int %s,\n", + sb.Append(prefix).AppendFormat("int32_t %sServiceOnRemoteRequest(void *service, int %s, ", infName_.string(), codeName.string()); + sb.Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n"); } else { codeName = "code"; sb.Append(prefix).AppendFormat("int32_t %sServiceOnRemoteRequest(struct HdfRemoteService *service, int %s,\n", infName_.string(), codeName.string()); + sb.Append(prefix + g_tab).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n"); } - sb.Append(prefix + g_tab).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n"); sb.Append(prefix).Append("{\n"); sb.Append(prefix + g_tab).AppendFormat("struct %s *serviceImpl = (struct %s*)service;\n", interfaceName_.string(), interfaceName_.string()); @@ -345,51 +409,128 @@ void CServiceStubCodeEmitter::EmitServiceStubOnRequestMethodImpl(StringBuilder& sb.Append("}\n"); } -void CServiceStubCodeEmitter::EmitCbStubDefinitions(StringBuilder& sb) +void CServiceStubCodeEmitter::EmitStubLinkService(StringBuilder& sb) { - sb.AppendFormat("struct %sStub {\n", infName_.string()); - sb.Append(g_tab).AppendFormat("struct %s service;\n", interfaceName_.string()); - sb.Append(g_tab).Append("struct HdfRemoteDispatcher dispatcher;\n"); - sb.Append("};\n"); + sb.Append("static void *LoadServiceHandler(const char* libFileName)\n"); + sb.Append("{\n"); + sb.Append(g_tab).Append("char path[PATH_MAX + 1] = {0};\n"); + sb.Append(g_tab).Append("char libPath[PATH_MAX + 1] = {0};\n"); + sb.Append(g_tab).Append("void *handler = NULL;\n"); + sb.Append("\n"); + sb.Append(g_tab).AppendFormat("if (snprintf_s(path, sizeof(path), sizeof(path) - 1, \"%%s/%%s\", "); + sb.Append("DRIVER_PATH, libFileName) < 0) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: snprintf_s failed\", __func__);\n"); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n"); + sb.Append("\n"); + sb.Append(g_tab).Append("if (realpath(path, libPath) == NULL) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s file name invalid\", __func__);\n"); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n"); + sb.Append("\n"); + sb.Append(g_tab).Append("handler = dlopen(libPath, RTLD_LAZY);\n"); + sb.Append(g_tab).Append("if (handler == NULL) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: dlopen failed %{public}s\", "); + sb.AppendFormat("__func__, dlerror());\n"); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n"); + sb.Append("\n"); + sb.Append(g_tab).Append("return handler;\n"); + sb.Append("}\n"); } -void CServiceStubCodeEmitter::EmitCbStubObtainImpl(StringBuilder& sb) +void CServiceStubCodeEmitter::EmitStubGetMethodImpl(StringBuilder& sb) { + String libName = String::Format("lib%s.z.so", FileName(implName_).string()); String stubTypeName = String::Format("%sStub", infName_.string()); String objName = "stub"; - sb.AppendFormat("struct %s* %sStubObtain()\n", interfaceName_.string(), infName_.string()); + sb.AppendFormat("struct %s *%sStubGetInstance(void)\n", interfaceName_.string(), infName_.string()); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("struct %s* %s = (struct %s*)OsalMemAlloc(sizeof(struct %s));\n", + sb.Append(g_tab).AppendFormat("SERVICE_CONSTRUCT_FUNC serviceConstructFunc = NULL;\n", libName.string()); + sb.Append(g_tab).AppendFormat("struct %s *%s = (struct %s *)OsalMemAlloc(sizeof(struct %s));\n", stubTypeName.string(), objName.string(), stubTypeName.string(), stubTypeName.string()); - sb.Append(g_tab).AppendFormat("if (stub == NULL) {\n", objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat( - "HDF_LOGE(\"%%{public}s: OsalMemAlloc %s obj failed!\", __func__);\n", stubTypeName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("return NULL;\n"); - sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).AppendFormat("%s->dispatcher.Dispatch = %sServiceOnRemoteRequest;\n", - objName.string(), infName_.string()); - sb.Append(g_tab).AppendFormat( - "%s->service.remote = HdfRemoteServiceObtain((struct HdfObject*)%s, &(%s->dispatcher));\n", - objName.string(), objName.string(), objName.string()); - sb.Append(g_tab).AppendFormat("if (%s->service.remote == NULL) {\n", objName.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat( - "HDF_LOGE(\"%%{public}s: %s->service.remote is null\", __func__);\n", objName.string()); + sb.Append(g_tab).AppendFormat("if (%s == NULL) {\n", objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: OsalMemAlloc obj failed!\", __func__);\n", + stubTypeName.string()); sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); sb.Append(g_tab).Append("}\n\n"); - sb.Append(g_tab).AppendFormat("%sServiceConstruct(&%s->service);\n", infName_.string(), objName.string()); + if (isCallbackInterface()) { + sb.Append(g_tab).AppendFormat("%s->dispatcher.Dispatch = %sServiceOnRemoteRequest;\n", + objName.string(), infName_.string()); + sb.Append(g_tab).AppendFormat( + "%s->service.remote = HdfRemoteServiceObtain((struct HdfObject*)%s, &(%s->dispatcher));\n", + objName.string(), objName.string(), objName.string()); + sb.Append(g_tab).AppendFormat("if (%s->service.remote == NULL) {\n", objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat( + "HDF_LOGE(\"%%{public}s: %s->service.remote is null\", __func__);\n", objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("OsalMemFree(%s);\n", objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n\n"); + } + sb.Append(g_tab).AppendFormat("%s->dlHandler = LoadServiceHandler(\"lib%s.z.so\");\n", + objName.string(), FileName(implName_).string()); + sb.Append(g_tab).AppendFormat("if (%s->dlHandler == NULL) {\n", objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: %s->dlHanlder is null\", __func__);\n", + objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("OsalMemFree(%s);\n", objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("serviceConstructFunc = "); + sb.AppendFormat("(SERVICE_CONSTRUCT_FUNC)dlsym(%s->dlHandler, \"%sServiceConstruct\");\n", + objName.string(), infName_.string()); + sb.Append(g_tab).Append("if (serviceConstructFunc == NULL) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: dlsym failed %{public}s\", __func__, dlerror());\n"); + sb.Append(g_tab).Append(g_tab).AppendFormat("dlclose(%s->dlHandler);\n", objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("OsalMemFree(%s);\n", objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("serviceConstructFunc(&%s->service);\n", objName.string()); sb.Append(g_tab).AppendFormat("return &%s->service;\n", objName.string()); sb.Append("}\n"); } -void CServiceStubCodeEmitter::EmitCbStubReleaseImpl(StringBuilder& sb) +void CServiceStubCodeEmitter::EmitKernelStubGetMethodImpl(StringBuilder& sb) { - sb.AppendFormat("void %sStubRelease(struct %s *stub)\n", infName_.string(), interfaceName_.string()); + String objName("instance"); + sb.AppendFormat("struct %s *%sStubGetInstance(void)\n", interfaceName_.string(), infName_.string()); sb.Append("{\n"); - sb.Append(g_tab).Append("if (stub == NULL) {\n"); + sb.Append(g_tab).AppendFormat("struct %s *%s = (struct %s*)OsalMemAlloc(sizeof(struct %s));\n", + interfaceName_.string(), objName.string(), interfaceName_.string(), interfaceName_.string()); + sb.Append(g_tab).AppendFormat("if (%s == NULL) {\n", objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat( + "HDF_LOGE(\"%%{public}s: OsalMemAlloc struct %s %s failed!\", __func__);\n", + interfaceName_.string(), objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n"); + sb.Append(g_tab).AppendFormat("%sServiceConstruct(%s);\n", infName_.string(), objName.string()); + sb.Append(g_tab).AppendFormat("return %s;\n", objName.string()); + sb.Append("}\n"); +} + +void CServiceStubCodeEmitter::EmitStubReleaseImpl(StringBuilder& sb) +{ + sb.AppendFormat("void %sStubRelease(struct %s *instance)\n", infName_.string(), interfaceName_.string()); + sb.Append("{\n"); + sb.Append(g_tab).Append("if (instance == NULL) {\n"); sb.Append(g_tab).Append(g_tab).Append("return;\n"); sb.Append(g_tab).Append("}\n"); + sb.Append(g_tab).AppendFormat("struct %s *stub = CONTAINER_OF(instance, struct %s, service);\n", + stubName_.string(), stubName_.string()); + sb.Append(g_tab).Append("dlclose(stub->dlHandler);\n"); sb.Append(g_tab).Append("OsalMemFree(stub);\n"); sb.Append("}"); } + +void CServiceStubCodeEmitter::EmitKernelStubReleaseImpl(StringBuilder& sb) +{ + sb.AppendFormat("void %sStubRelease(struct %s *instance)\n", infName_.string(), interfaceName_.string()); + sb.Append("{\n"); + sb.Append(g_tab).Append("if (instance == NULL) {\n"); + sb.Append(g_tab).Append(g_tab).Append("return;\n"); + sb.Append(g_tab).Append("}\n"); + sb.Append(g_tab).Append("OsalMemFree(instance);\n"); + sb.Append("}"); +} + } // namespace HDI } // namespace OHOS \ No newline at end of file diff --git a/tools/hdi-gen/codegen/c_service_stub_code_emitter.h b/tools/hdi-gen/codegen/c_service_stub_code_emitter.h index fdde479f..03350ae3 100755 --- a/tools/hdi-gen/codegen/c_service_stub_code_emitter.h +++ b/tools/hdi-gen/codegen/c_service_stub_code_emitter.h @@ -33,6 +33,10 @@ private: void EmitServiceStubStdlibInclusions(StringBuilder& sb); + void EmitDriverLibPath(StringBuilder& sb); + + void EmitServConstructTypedef(StringBuilder& sb); + void EmitServiceStubMethodImpls(StringBuilder& sb, const String& prefix); void EmitServiceStubMethodImpl(const AutoPtr& method, StringBuilder& sb, const String& prefix); @@ -54,9 +58,15 @@ private: void EmitCbStubDefinitions(StringBuilder& sb); - void EmitCbStubObtainImpl(StringBuilder& sb); + void EmitStubGetMethodImpl(StringBuilder& sb); - void EmitCbStubReleaseImpl(StringBuilder& sb); + void EmitKernelStubGetMethodImpl(StringBuilder& sb); + + void EmitStubLinkService(StringBuilder& sb); + + void EmitStubReleaseImpl(StringBuilder& sb); + + void EmitKernelStubReleaseImpl(StringBuilder& sb); }; } // namespace HDI } // namespace OHOS diff --git a/tools/hdi-gen/codegen/code_generator.cpp b/tools/hdi-gen/codegen/code_generator.cpp index 00d13adc..e9c53dfd 100755 --- a/tools/hdi-gen/codegen/code_generator.cpp +++ b/tools/hdi-gen/codegen/code_generator.cpp @@ -7,32 +7,28 @@ */ #include "codegen/code_generator.h" -#include "codegen/c_client_interface_code_emitter.h" +#include "codegen/c_interface_code_emitter.h" #include "codegen/c_client_proxy_code_emitter.h" #include "codegen/c_custom_types_code_emitter.h" #include "codegen/c_service_driver_code_emitter.h" #include "codegen/c_service_impl_code_emitter.h" -#include "codegen/c_service_interface_code_emitter.h" #include "codegen/c_service_stub_code_emitter.h" -#include "codegen/cpp_client_interface_code_emitter.h" +#include "codegen/cpp_interface_code_emitter.h" #include "codegen/cpp_client_proxy_code_emitter.h" #include "codegen/cpp_custom_types_code_emitter.h" #include "codegen/cpp_service_driver_code_emitter.h" #include "codegen/cpp_service_impl_code_emitter.h" -#include "codegen/cpp_service_interface_code_emitter.h" #include "codegen/cpp_service_stub_code_emitter.h" #include "codegen/java_client_interface_code_emitter.h" #include "codegen/java_client_proxy_code_emitter.h" #include "util/options.h" - namespace OHOS { namespace HDI { CodeEmitMap CodeGenerator::cCodeEmitters_ = { {"types", new CCustomTypesCodeEmitter()}, - {"clientIface", new CClientInterfaceCodeEmitter()}, + {"interface", new CInterfaceCodeEmitter()}, {"proxy", new CClientProxyCodeEmitter()}, - {"serviceIface", new CServiceInterfaceCodeEmitter()}, {"driver", new CServiceDriverCodeEmitter()}, {"stub", new CServiceStubCodeEmitter()}, {"impl", new CServiceImplCodeEmitter()}, @@ -40,9 +36,8 @@ CodeEmitMap CodeGenerator::cCodeEmitters_ = { CodeEmitMap CodeGenerator::cppCodeEmitters_ = { {"types", new CppCustomTypesCodeEmitter()}, - {"clientIface", new CppClientInterfaceCodeEmitter()}, + {"interface", new CppInterfaceCodeEmitter()}, {"proxy", new CppClientProxyCodeEmitter()}, - {"serviceIface", new CppServiceInterfaceCodeEmitter()}, {"driver", new CppServiceDriverCodeEmitter()}, {"stub", new CppServiceStubCodeEmitter()}, {"impl", new CppServiceImplCodeEmitter()}, @@ -56,7 +51,6 @@ CodeEmitMap CodeGenerator::javaCodeEmitters_ = { bool CodeGenerator::Generate() { const Options& options = Options::GetInstance(); - String dir = options.GetGenerationDirectory(); String language = options.GetTargetLanguage(); bool isModeKernel = options.DoGenerateKernelCode(); @@ -85,19 +79,18 @@ void CodeGenerator::GenerateCCode(const AutoPtr& ast, const String& outDir, } case ASTFileType::AST_IFACE: { if (codePart.Equals("client")) { - cCodeEmitters_["clientIface"]->OutPut(ast, outDir, isKernel); + cCodeEmitters_["interface"]->OutPut(ast, outDir, isKernel); cCodeEmitters_["proxy"]->OutPut(ast, outDir, isKernel); break; } else if (codePart.Equals("server")) { - cCodeEmitters_["serviceIface"]->OutPut(ast, outDir, isKernel); + cCodeEmitters_["interface"]->OutPut(ast, outDir, isKernel); cCodeEmitters_["driver"]->OutPut(ast, outDir, isKernel); cCodeEmitters_["stub"]->OutPut(ast, outDir, isKernel); cCodeEmitters_["impl"]->OutPut(ast, outDir, isKernel); break; } else { - cCodeEmitters_["clientIface"]->OutPut(ast, outDir, isKernel); + cCodeEmitters_["interface"]->OutPut(ast, outDir, isKernel); cCodeEmitters_["proxy"]->OutPut(ast, outDir, isKernel); - cCodeEmitters_["serviceIface"]->OutPut(ast, outDir, isKernel); cCodeEmitters_["driver"]->OutPut(ast, outDir, isKernel); cCodeEmitters_["stub"]->OutPut(ast, outDir, isKernel); cCodeEmitters_["impl"]->OutPut(ast, outDir, isKernel); @@ -106,9 +99,8 @@ void CodeGenerator::GenerateCCode(const AutoPtr& ast, const String& outDir, } case ASTFileType::AST_ICALLBACK: // khdf doesn't support callback - cCodeEmitters_["clientIface"]->OutPut(ast, outDir); + cCodeEmitters_["interface"]->OutPut(ast, outDir); cCodeEmitters_["proxy"]->OutPut(ast, outDir); - cCodeEmitters_["serviceIface"]->OutPut(ast, outDir); cCodeEmitters_["driver"]->OutPut(ast, outDir); cCodeEmitters_["stub"]->OutPut(ast, outDir); cCodeEmitters_["impl"]->OutPut(ast, outDir); @@ -126,17 +118,16 @@ void CodeGenerator::GenerateCppCode(const AutoPtr& ast, const String& outDi break; case ASTFileType::AST_IFACE: { if (codePart.Equals("client")) { - cppCodeEmitters_["clientIface"]->OutPut(ast, outDir); + cppCodeEmitters_["interface"]->OutPut(ast, outDir); cppCodeEmitters_["proxy"]->OutPut(ast, outDir); } else if (codePart.Equals("server")) { - cppCodeEmitters_["serviceIface"]->OutPut(ast, outDir); + cppCodeEmitters_["interface"]->OutPut(ast, outDir); cppCodeEmitters_["driver"]->OutPut(ast, outDir); cppCodeEmitters_["stub"]->OutPut(ast, outDir); cppCodeEmitters_["impl"]->OutPut(ast, outDir); } else { - cppCodeEmitters_["clientIface"]->OutPut(ast, outDir); + cppCodeEmitters_["interface"]->OutPut(ast, outDir); cppCodeEmitters_["proxy"]->OutPut(ast, outDir); - cppCodeEmitters_["serviceIface"]->OutPut(ast, outDir); cppCodeEmitters_["driver"]->OutPut(ast, outDir); cppCodeEmitters_["stub"]->OutPut(ast, outDir); cppCodeEmitters_["impl"]->OutPut(ast, outDir); @@ -144,9 +135,8 @@ void CodeGenerator::GenerateCppCode(const AutoPtr& ast, const String& outDi break; } case ASTFileType::AST_ICALLBACK: - cppCodeEmitters_["clientIface"]->OutPut(ast, outDir); + cppCodeEmitters_["interface"]->OutPut(ast, outDir); cppCodeEmitters_["proxy"]->OutPut(ast, outDir); - cppCodeEmitters_["serviceIface"]->OutPut(ast, outDir); cppCodeEmitters_["driver"]->OutPut(ast, outDir); cppCodeEmitters_["stub"]->OutPut(ast, outDir); cppCodeEmitters_["impl"]->OutPut(ast, outDir); diff --git a/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp index 2ef74107..e73a21ea 100755 --- a/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.cpp @@ -15,10 +15,8 @@ namespace OHOS { namespace HDI { bool CppClientProxyCodeEmitter::ResolveDirectory(const String& targetDirectory) { - if (ast_->GetASTFileType() == ASTFileType::AST_IFACE) { - directory_ = File::AdapterPath(String::Format("%s/%s/client/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); - } else if (ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { + if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || + ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), FileName(ast_->GetPackageName()).string())); } else { @@ -86,11 +84,8 @@ void CppClientProxyCodeEmitter::EmitProxyDecl(StringBuilder& sb, const String& p void CppClientProxyCodeEmitter::EmitProxyConstructor(StringBuilder& sb, const String& prefix) { - sb.Append(prefix).AppendFormat("explicit %s(\n", proxyName_.string()); - sb.Append(prefix + g_tab).Append("const sptr& remote)\n"); - sb.Append(prefix + g_tab).AppendFormat(": IRemoteProxy<%s>(remote)\n", interfaceName_.string()); - sb.Append(prefix).Append("{}\n"); - sb.Append("\n"); + sb.Append(prefix).AppendFormat("explicit %s(const sptr& remote)", proxyName_.string()); + sb.AppendFormat(" : IRemoteProxy<%s>(remote) {}\n\n", interfaceName_.string()); sb.Append(prefix).AppendFormat("virtual ~%s() {}\n", proxyName_.string()); } @@ -154,6 +149,8 @@ void CppClientProxyCodeEmitter::EmitProxySourceFile() if (!isCallbackInterface()) { EmitGetMethodImpl(sb, ""); sb.Append("\n"); + EmitGetInstanceMethodImpl(sb, ""); + sb.Append("\n"); } EmitProxyMethodImpls(sb, ""); sb.Append("\n"); @@ -192,6 +189,16 @@ void CppClientProxyCodeEmitter::EmitGetMethodImpl(StringBuilder& sb, const Strin sb.Append(prefix).AppendFormat("sptr<%s> %s::Get()\n", interface_->GetName().string(), interface_->GetName().string()); sb.Append(prefix).Append("{\n"); + sb.Append(prefix + g_tab).AppendFormat("return %s::GetInstance(\"%s\");\n", + interfaceName_.string(), FileName(implName_).string()); + sb.Append(prefix).Append("}\n"); +} + +void CppClientProxyCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder& sb, const String& prefix) +{ + sb.Append(prefix).AppendFormat("sptr<%s> %s::GetInstance(const std::string& serviceName)\n", + interface_->GetName().string(), interface_->GetName().string()); + sb.Append(prefix).Append("{\n"); sb.Append(prefix + g_tab).Append("do {\n"); sb.Append(prefix + g_tab + g_tab).Append("using namespace OHOS::HDI::ServiceManager::V1_0;\n"); sb.Append(prefix + g_tab + g_tab).Append("auto servMgr = IServiceManager::Get();\n"); @@ -200,15 +207,14 @@ void CppClientProxyCodeEmitter::EmitGetMethodImpl(StringBuilder& sb, const Strin "HDF_LOGE(\"%{public}s:get IServiceManager failed!\", __func__);\n"); sb.Append(prefix + g_tab + g_tab + g_tab).Append("break;\n"); sb.Append(prefix + g_tab + g_tab).Append("}\n\n"); - sb.Append(prefix + g_tab + g_tab).AppendFormat( - "sptr remote = servMgr->GetService(\"%sService\");\n", infName_.string()); + sb.Append(prefix + g_tab + g_tab).Append("sptr remote = servMgr->GetService(serviceName.c_str());\n"); sb.Append(prefix + g_tab + g_tab).Append("if (remote != nullptr) {\n"); sb.Append(prefix + g_tab + g_tab + g_tab).AppendFormat("return iface_cast<%s>(remote);\n", interface_->GetName().string()); sb.Append(prefix + g_tab + g_tab).Append("}\n"); sb.Append(prefix + g_tab).Append("} while(false);\n"); sb.Append(prefix + g_tab).AppendFormat( - "HDF_LOGE(\"%%{public}s: get %sService failed!\", __func__);\n", infName_.string()); + "HDF_LOGE(\"%%{public}s: get %s failed!\", __func__);\n", FileName(implName_).string()); sb.Append(prefix + g_tab).Append("return nullptr;\n"); sb.Append(prefix).Append("}\n"); } @@ -272,7 +278,7 @@ void CppClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr& me ConstantName(method->GetName()).string()); sb.Append(prefix + g_tab).Append("if (ec != HDF_SUCCESS) {\n"); sb.Append(prefix + g_tab + g_tab).AppendFormat( - "HDF_LOGE(\"%%{public}s failed, error code is %%d\", ec);\n", method->GetName().string()); + "HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, ec);\n", method->GetName().string()); sb.Append(prefix + g_tab + g_tab).Append("return ec;\n"); sb.Append(prefix + g_tab).Append("}\n"); diff --git a/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.h b/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.h index 2ab597f3..868f113f 100755 --- a/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.h +++ b/tools/hdi-gen/codegen/cpp_client_proxy_code_emitter.h @@ -47,6 +47,8 @@ private: void EmitGetMethodImpl(StringBuilder& sb, const String& prefix); + void EmitGetInstanceMethodImpl(StringBuilder& sb, const String& prefix); + void EmitProxyMethodImpls(StringBuilder& sb, const String& prefix); void EmitProxyMethodImpl(const AutoPtr& method, StringBuilder& sb, const String& prefix); diff --git a/tools/hdi-gen/codegen/cpp_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_code_emitter.cpp index 74b14832..83b857d0 100755 --- a/tools/hdi-gen/codegen/cpp_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_code_emitter.cpp @@ -77,6 +77,20 @@ void CppCodeEmitter::EmitTailMacro(StringBuilder& sb, const String& fullName) sb.Append("#endif // ").Append(macroName).Append("\n\n"); } +void CppCodeEmitter::EmitHeadExternC(StringBuilder& sb) +{ + sb.Append("#ifdef __cplusplus\n"); + sb.Append("extern \"C\" {\n"); + sb.Append("#endif /* __cplusplus */\n"); +} + +void CppCodeEmitter::EmitTailExternC(StringBuilder& sb) +{ + sb.Append("#ifdef __cplusplus\n"); + sb.Append("}\n"); + sb.Append("#endif /* __cplusplus */\n"); +} + void CppCodeEmitter::EmitBeginNamespace(StringBuilder& sb) { String nspace = interface_->GetNamespace()->ToString(); diff --git a/tools/hdi-gen/codegen/cpp_code_emitter.h b/tools/hdi-gen/codegen/cpp_code_emitter.h index c46a6ff0..a7c30f1e 100755 --- a/tools/hdi-gen/codegen/cpp_code_emitter.h +++ b/tools/hdi-gen/codegen/cpp_code_emitter.h @@ -35,6 +35,10 @@ protected: void EmitTailMacro(StringBuilder& sb, const String& fullName); + void EmitHeadExternC(StringBuilder& sb); + + void EmitTailExternC(StringBuilder& sb); + virtual void EmitBeginNamespace(StringBuilder& sb); virtual void EmitEndNamespace(StringBuilder& sb); diff --git a/tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp new file mode 100755 index 00000000..0e0a7c76 --- /dev/null +++ b/tools/hdi-gen/codegen/cpp_interface_code_emitter.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "codegen/cpp_interface_code_emitter.h" +#include "util/file.h" +#include "util/logger.h" + +namespace OHOS { +namespace HDI { +bool CppInterfaceCodeEmitter::ResolveDirectory(const String& targetDirectory) +{ + if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || + ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { + directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), + FileName(ast_->GetPackageName()).string())); + } else { + return false; + } + + if (!File::CreateParentDir(directory_)) { + Logger::E("CppInterfaceCodeEmitter", "Create '%s' failed!", directory_.string()); + return false; + } + + return true; +} + +void CppInterfaceCodeEmitter::EmitCode() +{ + EmitInterfaceHeaderFile(); +} + +void CppInterfaceCodeEmitter::EmitInterfaceHeaderFile() +{ + String filePath = String::Format("%s/%s.h", directory_.string(), FileName(interfaceName_).string()); + File file(filePath, File::WRITE); + StringBuilder sb; + + EmitLicense(sb); + EmitHeadMacro(sb, interfaceFullName_); + sb.Append("\n"); + EmitInterfaceInclusions(sb); + sb.Append("\n"); + EmitBeginNamespace(sb); + sb.Append("\n"); + EmitUsingNamespace(sb); + sb.Append("\n"); + EmitInterfaceMethodCommands(sb, ""); + sb.Append("\n"); + EmitInterfaceDefinition(sb); + sb.Append("\n"); + EmitEndNamespace(sb); + sb.Append("\n"); + EmitTailMacro(sb, interfaceFullName_); + + String data = sb.ToString(); + file.WriteData(data.string(), data.GetLength()); + file.Flush(); + file.Close(); +} + +void CppInterfaceCodeEmitter::EmitInterfaceInclusions(StringBuilder& sb) +{ + EmitInterfaceStdlibInclusions(sb); + EmitInterfaceDBinderInclusions(sb); + EmitInterfaceSelfDefinedTypeInclusions(sb); +} + +void CppInterfaceCodeEmitter::EmitInterfaceStdlibInclusions(StringBuilder& sb) +{ + bool includeString = false; + bool includeList = false; + bool includeMap = false; + + const AST::TypeStringMap& types = ast_->GetTypes(); + for (const auto& pair : types) { + AutoPtr type = pair.second; + switch (type->GetTypeKind()) { + case TypeKind::TYPE_STRING: { + if (!includeString) { + sb.Append("#include \n"); + includeString = true; + } + break; + } + case TypeKind::TYPE_ARRAY: + case TypeKind::TYPE_LIST: { + if (!includeList) { + sb.Append("#include \n"); + includeList = true; + } + break; + } + case TypeKind::TYPE_MAP: { + if (!includeMap) { + sb.Append("#include \n"); + includeMap = true; + } + break; + } + default: + break; + } + } +} + +void CppInterfaceCodeEmitter::EmitInterfaceDBinderInclusions(StringBuilder& sb) +{ + sb.Append("#include \n"); + sb.Append("#include \n"); + sb.Append("#include \n"); +} + +void CppInterfaceCodeEmitter::EmitInterfaceSelfDefinedTypeInclusions(StringBuilder& sb) +{ + for (const auto& importPair : ast_->GetImports()) { + AutoPtr importAst = importPair.second; + sb.Append("#include ").AppendFormat("\"%s.h\"\n", FileName(importAst->GetFullName()).string()); + } +} + +void CppInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder& sb) +{ + if (!isCallbackInterface()) { + sb.Append("#ifndef __HDI_SERVER__\n"); + sb.AppendFormat("class %s : public IRemoteBroker {\n", interfaceName_.string()); + sb.Append("public:\n"); + EmitInterfaceDescriptor(sb, g_tab); + sb.Append("\n"); + EmitGetMethodDecl(sb, g_tab); + sb.Append("\n"); + EmitGetInstanceMethodDecl(sb, g_tab); + sb.Append("#else\n"); + sb.AppendFormat("class %s {\n", interfaceName_.string()); + sb.Append("public:\n"); + sb.Append("#endif\n"); + + + EmitInterfaceDestruction(sb, g_tab); + sb.Append("\n"); + EmitInterfaceMethodsDecl(sb, g_tab); + sb.Append("};\n\n"); + } else { + sb.AppendFormat("class %s : public IRemoteBroker {\n", interfaceName_.string()); + sb.Append("public:\n"); + EmitInterfaceDescriptor(sb, g_tab); + sb.Append("\n"); + EmitInterfaceDestruction(sb, g_tab); + sb.Append("\n"); + EmitInterfaceMethodsDecl(sb, g_tab); + sb.Append("};\n\n"); + } +} + +void CppInterfaceCodeEmitter::EmitInterfaceDescriptor(StringBuilder& sb, const String& prefix) +{ + sb.Append(g_tab).AppendFormat("DECLARE_INTERFACE_DESCRIPTOR(u\"%s\");\n", interfaceFullName_.string()); +} + +void CppInterfaceCodeEmitter::EmitGetMethodDecl(StringBuilder& sb, const String& prefix) +{ + sb.Append(prefix).AppendFormat("static sptr<%s> Get();\n", interface_->GetName().string()); +} + +void CppInterfaceCodeEmitter::EmitGetInstanceMethodDecl(StringBuilder& sb, const String& prefix) +{ + sb.Append(prefix).AppendFormat("static sptr<%s> GetInstance(const std::string& serviceName);\n", + interface_->GetName().string()); +} + +void CppInterfaceCodeEmitter::EmitInterfaceDestruction(StringBuilder& sb, const String& prefix) +{ + sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", interface_->GetName().string()); +} + +void CppInterfaceCodeEmitter::EmitInterfaceMethodsDecl(StringBuilder& sb, const String& prefix) +{ + for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { + AutoPtr method = interface_->GetMethod(i); + EmitInterfaceMethodDecl(method, sb, prefix); + if (i + 1 < interface_->GetMethodNumber()) { + sb.Append("\n"); + } + } +} + +void CppInterfaceCodeEmitter::EmitInterfaceMethodDecl(const AutoPtr& method, StringBuilder& sb, + const String& prefix) +{ + if (method->GetParameterNumber() == 0) { + sb.Append(prefix).AppendFormat("virtual int32_t %s() = 0;\n", method->GetName().string()); + } else { + StringBuilder paramStr; + paramStr.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().string()); + for (size_t i = 0; i < method->GetParameterNumber(); i++) { + AutoPtr param = method->GetParameter(i); + EmitInterfaceMethodParameter(param, paramStr, ""); + if (i + 1 < method->GetParameterNumber()) { + paramStr.Append(", "); + } + } + + paramStr.Append(") = 0;"); + sb.Append(SpecificationParam(paramStr, prefix + g_tab)); + sb.Append("\n"); + } +} + +void CppInterfaceCodeEmitter::EmitInterfaceMethodParameter(const AutoPtr& param, StringBuilder& sb, + const String& prefix) +{ + sb.Append(prefix).Append(param->EmitCppParameter()); +} +} // namespace HDI +} // namespace OHOS \ No newline at end of file diff --git a/tools/hdi-gen/codegen/cpp_interface_code_emitter.h b/tools/hdi-gen/codegen/cpp_interface_code_emitter.h new file mode 100755 index 00000000..2481aac5 --- /dev/null +++ b/tools/hdi-gen/codegen/cpp_interface_code_emitter.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef OHOS_HDI_CPP_INTERFACE_CODE_EMITTER_H +#define OHOS_HDI_CPP_INTERFACE_CODE_EMITTER_H + +#include "codegen/cpp_code_emitter.h" + +namespace OHOS { +namespace HDI { + +class CppInterfaceCodeEmitter : public CppCodeEmitter { +public: + CppInterfaceCodeEmitter() : CppCodeEmitter() {} + + virtual ~CppInterfaceCodeEmitter() = default; +private: + bool ResolveDirectory(const String& targetDirectory) override; + + void EmitCode() override; + + void EmitInterfaceHeaderFile(); + + void EmitInterfaceInclusions(StringBuilder& sb); + + void EmitInterfaceStdlibInclusions(StringBuilder& sb); + + void EmitInterfaceDBinderInclusions(StringBuilder& sb); + + void EmitInterfaceSelfDefinedTypeInclusions(StringBuilder& sb); + + void EmitInterfaceDefinition(StringBuilder& sb); + + void EmitInterfaceDescriptor(StringBuilder& sb, const String& prefix); + + void EmitGetMethodDecl(StringBuilder& sb, const String& prefix); + + void EmitGetInstanceMethodDecl(StringBuilder& sb, const String& prefix); + + void EmitInterfaceDestruction(StringBuilder& sb, const String& prefix); + + void EmitInterfaceMethodsDecl(StringBuilder& sb, const String& prefix); + + void EmitInterfaceMethodDecl(const AutoPtr& method, StringBuilder& sb, const String& prefix); + + void EmitInterfaceMethodParameter(const AutoPtr& param, StringBuilder& sb, const String& prefix); +}; + +} // namespace HDI +} // namespace OHOS + +#endif // OHOS_HDI_CPP_INTERFACE_CODE_EMITTER_H \ No newline at end of file diff --git a/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp index 21a84322..9a08369b 100755 --- a/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_service_driver_code_emitter.cpp @@ -9,6 +9,7 @@ #include "codegen/cpp_service_driver_code_emitter.h" #include "util/file.h" #include "util/logger.h" +#include "util/options.h" namespace OHOS { namespace HDI { @@ -18,7 +19,7 @@ bool CppServiceDriverCodeEmitter::ResolveDirectory(const String& targetDirectory return false; } - directory_ = File::AdapterPath(String::Format("%s/%s/server/", targetDirectory.string(), + directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), FileName(ast_->GetPackageName()).string())); if (!File::CreateParentDir(directory_)) { Logger::E("CppServiceDriverCodeEmitter", "Create '%s' failed!", directory_.string()); @@ -88,7 +89,7 @@ void CppServiceDriverCodeEmitter::EmitDriverUsings(StringBuilder& sb) void CppServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder& sb) { - sb.AppendFormat("struct Hdf%s%s {\n", infName_.string(), "Service"); + sb.AppendFormat("struct Hdf%sHost {\n", infName_.string()); sb.Append(g_tab).Append("struct IDeviceIoService ioservice;\n"); sb.Append(g_tab).Append("void *instance;\n"); sb.Append("};\n"); @@ -96,15 +97,15 @@ void CppServiceDriverCodeEmitter::EmitDriverServiceDecl(StringBuilder& sb) void CppServiceDriverCodeEmitter::EmitDriverDispatch(StringBuilder& sb) { - sb.AppendFormat("static int32_t %sServiceDispatch(struct HdfDeviceIoClient *client, int cmdId,\n", + sb.AppendFormat("static int32_t %sDriverDispatch(struct HdfDeviceIoClient *client, int cmdId,\n", infName_.string()); sb.Append(g_tab).Append("struct HdfSBuf *data, struct HdfSBuf *reply)\n"); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("struct Hdf%sService *hdf%sService = CONTAINER_OF(\n", + sb.Append(g_tab).AppendFormat("struct Hdf%sHost *hdf%sHost = CONTAINER_OF(\n", infName_.string(), infName_.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("client->device->service, struct Hdf%sService, ioservice);\n", + sb.Append(g_tab).Append(g_tab).AppendFormat("client->device->service, struct Hdf%sHost, ioservice);\n", infName_.string()); - sb.Append(g_tab).AppendFormat("return %sServiceOnRemoteRequest(hdf%sService->instance, cmdId, data, reply);\n", + sb.Append(g_tab).AppendFormat("return %sServiceOnRemoteRequest(hdf%sHost->instance, cmdId, data, reply);\n", infName_.string(), infName_.string()); sb.Append("}\n"); } @@ -113,7 +114,7 @@ void CppServiceDriverCodeEmitter::EmitDriverInit(StringBuilder& sb) { sb.AppendFormat("int Hdf%sDriverInit(struct HdfDeviceObject *deviceObject)\n", infName_.string()); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverInit enter, new hdi impl.\");\n", infName_.string()); + sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverInit enter\");\n", infName_.string()); sb.Append(g_tab).Append("return HDF_SUCCESS;\n"); sb.Append("}\n"); } @@ -122,24 +123,24 @@ void CppServiceDriverCodeEmitter::EmitDriverBind(StringBuilder& sb) { sb.AppendFormat("int Hdf%sDriverBind(struct HdfDeviceObject *deviceObject)\n", infName_.string()); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverBind enter.\");\n", infName_.string()); + sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverBind enter\");\n", infName_.string()); sb.Append("\n"); - sb.Append(g_tab).AppendFormat("struct Hdf%sService *hdf%sService = (struct Hdf%sService *)OsalMemAlloc(\n", + sb.Append(g_tab).AppendFormat("struct Hdf%sHost *hdf%sHost = (struct Hdf%sHost *)OsalMemAlloc(\n", infName_.string(), infName_.string(), infName_.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("sizeof(struct Hdf%sService));\n", infName_.string()); - sb.Append(g_tab).AppendFormat("if (hdf%sService == nullptr) {\n", infName_.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"Hdf%sDriverBind OsalMemAlloc Hdf%sService failed!\");\n", + sb.Append(g_tab).Append(g_tab).AppendFormat("sizeof(struct Hdf%sHost));\n", infName_.string()); + sb.Append(g_tab).AppendFormat("if (hdf%sHost == nullptr) {\n", infName_.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"Hdf%sDriverBind OsalMemAlloc Hdf%sHost failed!\");\n", infName_.string(), infName_.string()); sb.Append(g_tab).Append(g_tab).Append("return HDF_FAILURE;\n"); sb.Append(g_tab).Append("}\n"); sb.Append("\n"); - sb.Append(g_tab).AppendFormat("hdf%sService->ioservice.Dispatch = %sServiceDispatch;\n", + sb.Append(g_tab).AppendFormat("hdf%sHost->ioservice.Dispatch = %sDriverDispatch;\n", infName_.string(), infName_.string()); - sb.Append(g_tab).AppendFormat("hdf%sService->ioservice.Open = NULL;\n", infName_.string()); - sb.Append(g_tab).AppendFormat("hdf%sService->ioservice.Release = NULL;\n", infName_.string()); - sb.Append(g_tab).AppendFormat("hdf%sService->instance = %sStubInstance();\n", infName_.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("hdf%sHost->ioservice.Open = NULL;\n", infName_.string()); + sb.Append(g_tab).AppendFormat("hdf%sHost->ioservice.Release = NULL;\n", infName_.string()); + sb.Append(g_tab).AppendFormat("hdf%sHost->instance = %sStubInstance();\n", infName_.string(), infName_.string()); sb.Append("\n"); - sb.Append(g_tab).AppendFormat("deviceObject->service = &hdf%sService->ioservice;\n", infName_.string()); + sb.Append(g_tab).AppendFormat("deviceObject->service = &hdf%sHost->ioservice;\n", infName_.string()); sb.Append(g_tab).Append("return HDF_SUCCESS;\n"); sb.Append("}\n"); } @@ -148,13 +149,11 @@ void CppServiceDriverCodeEmitter::EmitDriverRelease(StringBuilder& sb) { sb.AppendFormat("void Hdf%sDriverRelease(struct HdfDeviceObject *deviceObject)", infName_.string()); sb.Append("{\n"); - sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverRelease enter.\");\n\n", interfaceName_.string()); - sb.Append(g_tab).AppendFormat("struct Hdf%sService *hdf%sService = CONTAINER_OF(\n", - infName_.string(), infName_.string()); - sb.Append(g_tab).Append(g_tab).AppendFormat("deviceObject->service, struct Hdf%sService, ioservice);\n", - infName_.string()); - sb.Append(g_tab).AppendFormat("%sStubRelease(hdf%sService->instance);\n", infName_.string(), infName_.string()); - sb.Append(g_tab).AppendFormat("OsalMemFree(hdf%sService);\n", infName_.string()); + sb.Append(g_tab).AppendFormat("HDF_LOGI(\"Hdf%sDriverRelease enter\");\n\n", infName_.string()); + sb.Append(g_tab).AppendFormat("struct Hdf%sHost *hdf%sHost = CONTAINER_OF(", infName_.string(), infName_.string()); + sb.AppendFormat("deviceObject->service, struct Hdf%sHost, ioservice);\n", infName_.string()); + sb.Append(g_tab).AppendFormat("%sStubRelease(hdf%sHost->instance);\n", infName_.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("OsalMemFree(hdf%sHost);\n", infName_.string()); sb.Append("}\n"); } @@ -162,7 +161,8 @@ void CppServiceDriverCodeEmitter::EmitDriverEntryDefinition(StringBuilder& sb) { sb.AppendFormat("struct HdfDriverEntry g_%sDriverEntry = {\n", infName_.ToLowerCase().string()); sb.Append(g_tab).Append(".moduleVersion = 1,\n"); - sb.Append(g_tab).AppendFormat(".moduleName = \"%s\",\n", infName_.ToLowerCase().string()); + sb.Append(g_tab).AppendFormat(".moduleName = \"%s\",\n", + Options::GetInstance().GetModeName().string()); sb.Append(g_tab).AppendFormat(".Bind = Hdf%sDriverBind,\n", infName_.string()); sb.Append(g_tab).AppendFormat(".Init = Hdf%sDriverInit,\n", infName_.string()); sb.Append(g_tab).AppendFormat(".Release = Hdf%sDriverRelease,\n", infName_.string()); diff --git a/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp index 1d0d0e7d..263f68bd 100755 --- a/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_service_impl_code_emitter.cpp @@ -14,10 +14,8 @@ namespace OHOS { namespace HDI { bool CppServiceImplCodeEmitter::ResolveDirectory(const String& targetDirectory) { - if (ast_->GetASTFileType() == ASTFileType::AST_IFACE) { - directory_ = File::AdapterPath(String::Format("%s/%s/server/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); - } else if (ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { + if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || + ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), FileName(ast_->GetPackageName()).string())); } else { @@ -50,6 +48,18 @@ void CppServiceImplCodeEmitter::EmitImplHeaderFile() EmitServiceImplInclusions(sb); sb.Append("\n"); EmitServiceImplDecl(sb); + + if (!isCallbackInterface()) { + sb.Append("\n"); + EmitHeadExternC(sb); + sb.Append("\n"); + EmitExternalGetMethodDecl(sb); + sb.Append("\n"); + EmitExternalReleaseMethodDecl(sb); + sb.Append("\n"); + EmitTailExternC(sb); + } + sb.Append("\n"); EmitTailMacro(sb, implFullName_); @@ -132,6 +142,16 @@ void CppServiceImplCodeEmitter::EmitServiceImplMethodDecl(const AutoPtr& method, StringBuilder& sb, const String& prefix); + void EmitExternalGetMethodDecl(StringBuilder& sb); + + void EmitExternalReleaseMethodDecl(StringBuilder& sb); + void EmitImplSourceFile(); void EmitServiceImplMethodImpls(StringBuilder& sb, const String& prefix); void EmitServiceImplMethodImpl(const AutoPtr& method, StringBuilder& sb, const String& prefix); + + void EmitExternalGetMethodImpl(StringBuilder& sb); + + void EmitExternalReleaseMethodImpl(StringBuilder& sb); }; } // namespace HDI } // namespace OHOS diff --git a/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp b/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp index 6a2c2652..26a22985 100755 --- a/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp +++ b/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.cpp @@ -14,10 +14,8 @@ namespace OHOS { namespace HDI { bool CppServiceStubCodeEmitter::ResolveDirectory(const String& targetDirectory) { - if (ast_->GetASTFileType() == ASTFileType::AST_IFACE) { - directory_ = File::AdapterPath(String::Format("%s/%s/server/", targetDirectory.string(), - FileName(ast_->GetPackageName()).string())); - } else if (ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { + if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || + ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) { directory_ = File::AdapterPath(String::Format("%s/%s/", targetDirectory.string(), FileName(ast_->GetPackageName()).string())); } else { @@ -69,12 +67,10 @@ void CppServiceStubCodeEmitter::EmitStubHeaderInclusions(StringBuilder& sb) sb.Append("#include \n"); sb.Append("#include \n"); sb.Append("#include \n"); - if (!isCallbackInterface()) { - sb.AppendFormat("#include \"%s_service.h\"\n", FileName(infName_).string()); - } else { + if (isCallbackInterface()) { sb.Append("#include \n"); - sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string()); } + sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string()); } void CppServiceStubCodeEmitter::EmitStubDecl(StringBuilder& sb) @@ -178,8 +174,8 @@ void CppServiceStubCodeEmitter::EmitStubOnRequestMethodDecl(StringBuilder& sb, c void CppServiceStubCodeEmitter::EmitStubMembers(StringBuilder& sb, const String& prefix) { - sb.Append("private:\n"); - sb.Append(prefix).AppendFormat("%sService service;\n", infName_.string()); + sb.Append(prefix).Append("void *dlHandler;\n"); + sb.Append(prefix).AppendFormat("%s *service;\n", interfaceName_.string()); } void CppServiceStubCodeEmitter::EmitStubExternalsMethodsDel(StringBuilder& sb) @@ -201,6 +197,18 @@ void CppServiceStubCodeEmitter::EmitStubSourceFile() EmitLicense(sb); EmitStubSourceInclusions(sb); + + if (!isCallbackInterface()) { + sb.Append("\n"); + EmitDriverLibPath(sb); + sb.Append("\n"); + EmitHeadExternC(sb); + sb.Append("\n"); + EmitLibFuncTypeDef(sb); + sb.Append("\n"); + EmitTailExternC(sb); + } + sb.Append("\n"); EmitBeginNamespace(sb); sb.Append("\n"); @@ -233,20 +241,43 @@ void CppServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder& sb) void CppServiceStubCodeEmitter::EmitStubSourceStdlibInclusions(StringBuilder& sb) { + if (!isCallbackInterface()) { + sb.Append("#include \n"); + } sb.Append("#include \n"); sb.Append("#include \n"); sb.Append("#include \n"); const AST::TypeStringMap& types = ast_->GetTypes(); - for (const auto& pair : types) { - AutoPtr type = pair.second; - if (type->GetTypeKind() == TypeKind::TYPE_UNION) { - sb.Append("#include \n"); - break; + if (isCallbackInterface()) { + for (const auto& pair : types) { + AutoPtr type = pair.second; + if (type->GetTypeKind() == TypeKind::TYPE_UNION) { + sb.Append("#include \n"); + break; + } } + } else { + sb.Append("#include \n"); } } +void CppServiceStubCodeEmitter::EmitDriverLibPath(StringBuilder& sb) +{ + sb.Append("#ifdef __ARM64__\n"); + sb.Append("#define DRIVER_PATH \"system/lib64\"\n"); + sb.Append("#else\n"); + sb.Append("#define DRIVER_PATH \"system/lib\"\n"); + sb.Append("#endif\n"); +} + +void CppServiceStubCodeEmitter::EmitLibFuncTypeDef(StringBuilder& sb) +{ + sb.AppendFormat("typedef %s* (*SERVICE_CONSTRUCT_FUNC)();\n", CppFullName(interface_->GetFullName()).string()); + sb.AppendFormat("typedef void (*SERVICE_RELEASE_FUNC)(%s *obj);\n", + CppFullName(interface_->GetFullName()).string()); +} + void CppServiceStubCodeEmitter::EmitStubMethodImpls(StringBuilder& sb, const String& prefix) { for (size_t i = 0; i < interface_->GetMethodNumber(); i++) { @@ -298,7 +329,7 @@ void CppServiceStubCodeEmitter::EmitStubCallMethod(const AutoPtr& met const String& prefix) { if (!isCallbackInterface()) { - sb.Append(prefix).AppendFormat("int32_t ec = service.%s(", method->GetName().string()); + sb.Append(prefix).AppendFormat("int32_t ec = service->%s(", method->GetName().string()); } else { sb.Append(prefix).AppendFormat("int32_t ec = %s(", method->GetName().string()); } @@ -369,58 +400,141 @@ void CppServiceStubCodeEmitter::EmitCbStubOnRequestMethodImpl(StringBuilder& sb, void CppServiceStubCodeEmitter::EmitStubExternalsMethodsImpl(StringBuilder& sb, const String& prefix) { - EmitStubInstanceMethodImpl(sb, prefix); + EmitStubLinkService(sb); sb.Append("\n"); - EmitStubReleaseMethodImpl(sb, prefix); + EmitStubInstanceMethodImpl(sb); sb.Append("\n"); - EmitServiceOnRemoteRequest(sb, prefix); + EmitStubReleaseMethodImpl(sb); + sb.Append("\n"); + EmitServiceOnRemoteRequest(sb); } -void CppServiceStubCodeEmitter::EmitStubInstanceMethodImpl(StringBuilder& sb, const String& prefix) +void CppServiceStubCodeEmitter::EmitStubLinkService(StringBuilder& sb) { - sb.Append(prefix).AppendFormat("void *%sInstance()\n", stubName_.string()); - sb.Append(prefix).Append("{\n"); - sb.Append(prefix + g_tab).AppendFormat("using namespace %s;\n", - EmitStubServiceUsings(interface_->GetNamespace()->ToString()).string()); - sb.Append(prefix + g_tab).AppendFormat("return reinterpret_cast(new %s());\n", stubName_.string()); - sb.Append(prefix).Append("}\n"); + sb.Append("static void *LoadServiceHandler(const char* libFileName)\n"); + sb.Append("{\n"); + sb.Append(g_tab).Append("char path[PATH_MAX + 1] = {0};\n"); + sb.Append(g_tab).Append("char libPath[PATH_MAX + 1] = {0};\n"); + sb.Append(g_tab).Append("void *handler = NULL;\n"); + sb.Append("\n"); + sb.Append(g_tab).AppendFormat("if (snprintf_s(path, sizeof(path), sizeof(path) - 1, \"%%s/%%s\", "); + sb.Append("DRIVER_PATH, libFileName) < 0) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: snprintf_s failed\", __func__);\n"); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n"); + sb.Append("\n"); + sb.Append(g_tab).Append("if (realpath(path, libPath) == NULL) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s file name invalid\", __func__);\n"); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n"); + sb.Append("\n"); + sb.Append(g_tab).Append("handler = dlopen(libPath, RTLD_LAZY);\n"); + sb.Append(g_tab).Append("if (handler == NULL) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: dlopen failed %{public}s\", "); + sb.AppendFormat("__func__, dlerror());\n"); + sb.Append(g_tab).Append(g_tab).Append("return NULL;\n"); + sb.Append(g_tab).Append("}\n"); + sb.Append("\n"); + sb.Append(g_tab).Append("return handler;\n"); + sb.Append("}\n"); } -void CppServiceStubCodeEmitter::EmitStubReleaseMethodImpl(StringBuilder& sb, const String& prefix) +void CppServiceStubCodeEmitter::EmitStubInstanceMethodImpl(StringBuilder& sb) { - sb.Append(prefix).AppendFormat("void %sRelease(void *obj)\n", stubName_.string()); - sb.Append(prefix).Append("{\n"); - sb.Append(prefix + g_tab).AppendFormat("using namespace %s;\n", + String objName = "stub"; + String libName = String::Format("lib%s.z.so", FileName(implName_).string()); + sb.AppendFormat("void *%sInstance()\n", stubName_.string()); + sb.Append("{\n"); + sb.Append(g_tab).AppendFormat("using namespace %s;\n", EmitStubServiceUsings(interface_->GetNamespace()->ToString()).string()); - sb.Append(prefix + g_tab).AppendFormat("delete reinterpret_cast<%s *>(obj);\n", stubName_.string()); - sb.Append(prefix).Append("}\n"); + sb.Append(g_tab).Append("SERVICE_CONSTRUCT_FUNC serviceConstructFunc = nullptr;\n"); + sb.Append(g_tab).AppendFormat("%sStub *%s = new %sStub();\n", infName_.string(), objName.string(), + infName_.string()); + sb.Append(g_tab).AppendFormat("if (%s == nullptr) {\n", objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: OsalMemAlloc %s failed!\", __func__);\n", + objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return nullptr;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("%s->dlHandler = LoadServiceHandler(\"%s\");\n", objName.string(), libName.string()); + sb.Append(g_tab).AppendFormat("if (%s->dlHandler == nullptr) {\n", objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("HDF_LOGE(\"%%{public}s: %s->dlHanlder is null\", __func__);\n", + objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("delete %s;\n", objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return nullptr;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("serviceConstructFunc = "); + sb.AppendFormat("(SERVICE_CONSTRUCT_FUNC)dlsym(%s->dlHandler, \"%sServiceConstruct\");\n", + objName.string(), infName_.string()); + sb.Append(g_tab).Append("if (serviceConstructFunc == nullptr) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: dlsym failed %{public}s\", __func__, dlerror());\n"); + sb.Append(g_tab).Append(g_tab).AppendFormat("dlclose(%s->dlHandler);\n", objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("delete %s;\n", objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return nullptr;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("%s->service = serviceConstructFunc();\n", objName.string()); + sb.Append(g_tab).AppendFormat("if (%s->service == nullptr) {\n", objName.string()); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: get service failed %{public}s\", "); + sb.Append("__func__, dlerror());\n"); + sb.Append(g_tab).Append(g_tab).AppendFormat("dlclose(%s->dlHandler);\n", objName.string()); + sb.Append(g_tab).Append(g_tab).AppendFormat("delete %s;\n", objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return nullptr;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).Append("return reinterpret_cast(stub);\n"); + sb.Append("}\n"); } -void CppServiceStubCodeEmitter::EmitServiceOnRemoteRequest(StringBuilder& sb, const String& prefix) +void CppServiceStubCodeEmitter::EmitStubReleaseMethodImpl(StringBuilder& sb) +{ + String objName = "stub"; + sb.AppendFormat("void %sRelease(void *obj)\n", stubName_.string()); + sb.Append("{\n"); + sb.Append(g_tab).AppendFormat("using namespace %s;\n", + EmitStubServiceUsings(interface_->GetNamespace()->ToString()).string()); + sb.Append(g_tab).Append("if (obj == nullptr) {\n"); + sb.Append(g_tab).Append(g_tab).Append("return;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("%sStub *%s = reinterpret_cast<%sStub *>(obj);\n", infName_.string(), + objName.string(), infName_.string()); + sb.Append(g_tab).AppendFormat("if (%s == nullptr) {\n", objName.string()); + sb.Append(g_tab).Append(g_tab).Append("return;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).Append("SERVICE_RELEASE_FUNC serviceReleaseFunc = "); + sb.AppendFormat("(SERVICE_RELEASE_FUNC)dlsym(%s->dlHandler, \"SampleServiceRelease\");\n", objName.string()); + sb.Append(g_tab).Append("if (serviceReleaseFunc == nullptr) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s: dlsym failed %{public}s\", __func__, dlerror());\n"); + sb.Append(g_tab).Append("} else {\n"); + sb.Append(g_tab).Append(g_tab).AppendFormat("serviceReleaseFunc(%s->service);\n", objName.string()); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).AppendFormat("dlclose(%s->dlHandler);\n", objName.string()); + sb.Append(g_tab).AppendFormat("delete %s;\n", objName.string()); + sb.Append("}\n"); +} + +void CppServiceStubCodeEmitter::EmitServiceOnRemoteRequest(StringBuilder& sb) { String stubObjName = String::Format("%sStub", infName_.ToLowerCase().string()); - sb.Append(prefix).AppendFormat( + sb.AppendFormat( "int32_t %sServiceOnRemoteRequest(void *stub, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply)\n", infName_.string()); - sb.Append(prefix).Append("{\n"); - sb.Append(prefix + g_tab).AppendFormat("using namespace %s;\n", + sb.Append("{\n"); + sb.Append(g_tab).AppendFormat("using namespace %s;\n", EmitStubServiceUsings(interface_->GetNamespace()->ToString()).string()); - sb.Append(prefix + g_tab).AppendFormat("%s *%s = reinterpret_cast<%s *>(stub);\n", + sb.Append(g_tab).AppendFormat("%s *%s = reinterpret_cast<%s *>(stub);\n", stubName_.string(), stubObjName.string(), stubName_.string()); - sb.Append(prefix + g_tab).Append("OHOS::MessageParcel *dataParcel = nullptr;\n"); - sb.Append(prefix + g_tab).Append("OHOS::MessageParcel *replyParcel = nullptr;\n"); + sb.Append(g_tab).Append("OHOS::MessageParcel *dataParcel = nullptr;\n"); + sb.Append(g_tab).Append("OHOS::MessageParcel *replyParcel = nullptr;\n"); sb.Append("\n"); - sb.Append(prefix + g_tab).Append("(void)SbufToParcel(reply, &replyParcel);\n"); - sb.Append(prefix + g_tab).Append("if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {\n"); - sb.Append(prefix + g_tab + g_tab).Append( - "HDF_LOGE(\"%{public}s:invalid data sbuf object to dispatch\", __func__);\n"); - sb.Append(prefix + g_tab + g_tab).Append("return HDF_ERR_INVALID_PARAM;\n"); - sb.Append(prefix + g_tab).Append("}\n\n"); - sb.Append(prefix + g_tab).Append("OHOS::MessageOption option;\n"); - sb.Append(prefix + g_tab).AppendFormat("return %s->%sOnRemoteRequest(cmdId, *dataParcel, *replyParcel, option);\n", + sb.Append(g_tab).Append("(void)SbufToParcel(reply, &replyParcel);\n"); + sb.Append(g_tab).Append("if (SbufToParcel(data, &dataParcel) != HDF_SUCCESS) {\n"); + sb.Append(g_tab).Append(g_tab).Append("HDF_LOGE(\"%{public}s:invalid data sbuf object to dispatch\","); + sb.Append(" __func__);\n"); + sb.Append(g_tab).Append(g_tab).Append("return HDF_ERR_INVALID_PARAM;\n"); + sb.Append(g_tab).Append("}\n\n"); + sb.Append(g_tab).Append("OHOS::MessageOption option;\n"); + sb.Append(g_tab).AppendFormat("return %s->%sOnRemoteRequest(cmdId, *dataParcel, *replyParcel, option);\n", stubObjName.string(), stubName_.string()); - sb.Append(prefix).Append("}\n"); + sb.Append("}\n"); } String CppServiceStubCodeEmitter::EmitStubServiceUsings(String nameSpace) diff --git a/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h b/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h index a403a30b..9d8bd615 100755 --- a/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h +++ b/tools/hdi-gen/codegen/cpp_service_stub_code_emitter.h @@ -59,6 +59,10 @@ private: void EmitStubSourceStdlibInclusions(StringBuilder& sb); + void EmitDriverLibPath(StringBuilder& sb); + + void EmitLibFuncTypeDef(StringBuilder& sb); + void EmitStubMethodImpls(StringBuilder& sb, const String& prefix); void EmitStubMethodImpl(const AutoPtr& method, StringBuilder& sb, const String& prefix); @@ -71,11 +75,13 @@ private: void EmitStubExternalsMethodsImpl(StringBuilder& sb, const String& prefix); - void EmitStubInstanceMethodImpl(StringBuilder& sb, const String& prefix); + void EmitStubLinkService(StringBuilder& sb); - void EmitStubReleaseMethodImpl(StringBuilder& sb, const String& prefix); + void EmitStubInstanceMethodImpl(StringBuilder& sb); - void EmitServiceOnRemoteRequest(StringBuilder& sb, const String& prefix); + void EmitStubReleaseMethodImpl(StringBuilder& sb); + + void EmitServiceOnRemoteRequest(StringBuilder& sb); String EmitStubServiceUsings(String nameSpace); }; diff --git a/tools/hdi-gen/main.cpp b/tools/hdi-gen/main.cpp index 00c6e853..5974ef04 100755 --- a/tools/hdi-gen/main.cpp +++ b/tools/hdi-gen/main.cpp @@ -37,12 +37,14 @@ int main(int argc, char** argv) } if (options.DoGetHashKey()) { - std::unique_ptr idlFile = std::make_unique(options.GetSourceFile(), int(File::READ)); - if (!idlFile->IsValid()) { - Logger::E("hdi-gen", "open idl file failed!"); - return -1; + for (const auto& sourceFile : options.GetSourceFiles()) { + std::unique_ptr idlFile = std::make_unique(sourceFile, int(File::READ)); + if (!idlFile->IsValid()) { + Logger::E("hdi-gen", "open idl file failed!"); + return -1; + } + printf("%s:%lu\n", idlFile->GetPath().string(), idlFile->GetHashKey()); } - printf("%s:%lu\n", idlFile->GetPath().string(), idlFile->GetHashKey()); return 0; } diff --git a/tools/hdi-gen/parser/module_parser.cpp b/tools/hdi-gen/parser/module_parser.cpp index 222f89f7..d8ff0b53 100755 --- a/tools/hdi-gen/parser/module_parser.cpp +++ b/tools/hdi-gen/parser/module_parser.cpp @@ -13,6 +13,8 @@ namespace OHOS { namespace HDI { +const char* ModuleParser::TAG = "ModuleParser"; + AutoPtr ModuleParser::Parse() { if (!ParserDependencies()) { @@ -28,13 +30,20 @@ AutoPtr ModuleParser::Parse() bool ModuleParser::ParserDependencies() { - if (!ParserAllImports(option_.GetSourceFile())) { - Logger::E(g_tab, "Parsing all idl file failed."); - return false; + if (option_.GetSourceFiles().size() == 1) { + if (!ParserAllImports(option_.GetSourceFiles()[0])) { + Logger::E(TAG, "Parsing all idl file failed."); + return false; + } + } else { + if (!ParserAllidlFile(option_.GetSourceFiles())) { + Logger::E(TAG, "Parsing all given idl file failed."); + return false; + } } if (!CheckCircularReference()) { - Logger::E(g_tab, "has circle reference."); + Logger::E(TAG, "has circle reference."); return false; } @@ -47,7 +56,7 @@ bool ModuleParser::CompileFiles() for (const auto& filePath : compileFiles_) { if (!parserPtr->Parse(filePath)) { - Logger::E(g_tab, "parse %s failed", filePath.string()); + Logger::E(TAG, "parse %s failed", filePath.string()); return false; } } @@ -84,19 +93,19 @@ bool ModuleParser::ParserAllImportsRecursion(const std::shared_ptr& std::unique_ptr parserPtr = std::make_unique(option_); std::shared_ptr file = nullptr; if (!parserPtr->Parse(filePath, file)) { - Logger::E(g_tab, "Parsing %s failed.", filePath.string()); + Logger::E(TAG, "Parsing %s failed.", filePath.string()); return false; } if (file == nullptr) { - Logger::E(g_tab, "Parsing %s failed, generator filedetail is nullptr.", filePath.string()); + Logger::E(TAG, "Parsing %s failed, generator filedetail is nullptr.", filePath.string()); return false; } sourceFiles_[file->GetFullName()] = file; if (!ParserAllImportsRecursion(file)) { - Logger::E(g_tab, "Parsing %s file's import failed.", file->GetFilePath().string()); + Logger::E(TAG, "Parsing %s file's import failed.", file->GetFilePath().string()); return false; } } @@ -104,6 +113,26 @@ bool ModuleParser::ParserAllImportsRecursion(const std::shared_ptr& return true; } +bool ModuleParser::ParserAllidlFile(const std::vector& idlSourceFile) +{ + std::unique_ptr parserPtr = std::make_unique(option_); + + for (const auto& idlSourceFile : idlSourceFile) { + std::shared_ptr fileInfo = nullptr; + if (!parserPtr->Parse(idlSourceFile, fileInfo)) { + return false; + } + + if (fileInfo == nullptr) { + return false; + } + + sourceFiles_[fileInfo->GetFullName()] = fileInfo; + } + + return true; +} + bool ModuleParser::CheckCircularReference() { std::queue> fileQueue; diff --git a/tools/hdi-gen/parser/module_parser.h b/tools/hdi-gen/parser/module_parser.h index 934ef45e..e7f0537e 100755 --- a/tools/hdi-gen/parser/module_parser.h +++ b/tools/hdi-gen/parser/module_parser.h @@ -43,9 +43,13 @@ private: bool ParserAllImportsRecursion(const std::shared_ptr& fileInfo); + bool ParserAllidlFile(const std::vector& idlSourceFile); + // check circular reference and reverse topology sorting of all idl file bool CheckCircularReference(); + static const char* TAG; + const Options& option_; FileDetailMap sourceFiles_; diff --git a/tools/hdi-gen/util/options.cpp b/tools/hdi-gen/util/options.cpp index a20a7450..5960d6ae 100755 --- a/tools/hdi-gen/util/options.cpp +++ b/tools/hdi-gen/util/options.cpp @@ -20,14 +20,13 @@ const char* Options::optSupportArgs = "c:d:"; static struct option g_longOpts[] = { {"help", no_argument, nullptr, 'h'}, {"version", no_argument, nullptr, 'v'}, - {"mode-k", no_argument, nullptr, 'k'}, - {"mode-u", no_argument, nullptr, 'u'}, {"gen-c", no_argument, nullptr, 'C'}, {"gen-cpp", no_argument, nullptr, 'P'}, {"gen-java", no_argument, nullptr, 'J'}, - {"client", no_argument, nullptr, 'a'}, - {"server", no_argument, nullptr, 'b'}, - {"hash", no_argument, nullptr, 'H'}, + {"gen-hash", no_argument, nullptr, 'H'}, + {"build-target", required_argument, nullptr, 'p'}, + {"mode-name", required_argument, nullptr, 'N'}, + {"kernel", no_argument, nullptr, 'K'}, {"dump-ast", no_argument, nullptr, 'D'}, {nullptr, 0, nullptr, 0} }; @@ -57,7 +56,7 @@ void Options::SetOptionData(char op) switch (op) { case 'c': doCompile_ = true; - sourceFilePath_ = optarg; + sourceFiles_.push_back(optarg); break; case 'd': doOutDir_ = true; @@ -69,11 +68,12 @@ void Options::SetOptionData(char op) case 'v': doShowVersion_ = true; break; - case 'k': + case 'K': doModeKernel_ = true; break; - case 'u': - doModeKernel_ = false; + case 'N': + doSetModeName_ = true; + modeName_ = optarg; break; case 'C': SetLanguage("c"); @@ -84,11 +84,8 @@ void Options::SetOptionData(char op) case 'J': SetLanguage("java"); break; - case 'a': - SetCodePart("client"); - break; - case 'b': - SetCodePart("server"); + case 'p': + SetCodePart(optarg); break; case 'H': doGetHashKey_ = true; @@ -103,14 +100,15 @@ void Options::SetOptionData(char op) } } -void Options::SetLanguage(String language) +void Options::SetLanguage(const String& language) { doGenerateCode_ = true; targetLanguage_ = language; } -void Options::SetCodePart(String part) +void Options::SetCodePart(const String& part) { + // The default parameter is 'all', and the optional parameters is 'client' or 'server' doGeneratePart_ = true; codePart_ = part; } @@ -136,6 +134,13 @@ void Options::CheckOptions() errors_.push_back(String::Format("%s: no out directory.", program_.string())); return; } + + if (doGeneratePart_ && !codePart_.Equals("all") && !codePart_.Equals("client") && + !codePart_.Equals("server")) { + errors_.push_back( + String::Format("%s: The '--build-target' option parameter must be 'client' 'server' or 'all'.", + program_.string())); + } } else { if (doGetHashKey_ || doDumpAST_ || doGenerateCode_ || doOutDir_) { errors_.push_back(String::Format("%s: no '-c' option.", program_.string())); @@ -164,19 +169,18 @@ void Options::ShowUsage() const printf("Compile a .idl file and generate C/C++ and Java codes.\n" "Usage: idl [options] file\n" "Options:\n" - " --help Display command line options\n" - " --version Display toolchain version information\n" - " --hash Display hash key of the idl file\n" - " --dump-ast Display the AST of the compiled file\n" - " -c Compile the .idl file\n" - " --mode-k Generate kernel-mode ioservice stub code\n" - " --mode-u Generate user-mode ioservice stub code\n" - " --gen-c Generate C codes\n" - " --gen-cpp Generate C++ codes\n" - " --gen-java Generate Java codes\n" - " --client Generate client codes\n" - " --server Generate server codes\n" - " -d Place generated codes into \n"); + " --help Display command line options\n" + " --version Display toolchain version information\n" + " --dump-ast Display the AST of the compiled file\n" + " -c <*.idl> Compile the .idl file\n" + " --gen-hash Generate hash key of the idl file\n" + " --gen-c Generate C code\n" + " --gen-cpp Generate C++ code\n" + " --gen-java Generate Java code\n" + " --kernel Generate kernel-mode ioservice stub code, default user-mode ioservice stub code\n" + " --mode-name Set driver module name\n" + " --build-target Generate client code, server code or all code\n" + " -d Place generated codes into \n"); } } // namespace HDI } // namespace OHOS \ No newline at end of file diff --git a/tools/hdi-gen/util/options.h b/tools/hdi-gen/util/options.h index f5e410d4..e9423120 100755 --- a/tools/hdi-gen/util/options.h +++ b/tools/hdi-gen/util/options.h @@ -65,9 +65,9 @@ public: return !errors_.empty(); } - inline String GetSourceFile() const + inline std::vector GetSourceFiles() const { - return sourceFilePath_; + return sourceFiles_; } inline String GetTargetLanguage() const @@ -80,6 +80,11 @@ public: return codePart_; } + inline String GetModeName() const + { + return doSetModeName_ ? modeName_ : "sample"; + } + inline String GetGenerationDirectory() const { return generationDirectory_; @@ -93,7 +98,7 @@ public: private: Options() : program_(), - sourceFilePath_(), + sourceFiles_(0), targetLanguage_(), codePart_("all"), generationDirectory_(), @@ -105,13 +110,16 @@ private: doDumpAST_(false), doGetHashKey_(false), doGenerateCode_(false), + doModeKernel_(false), + doGeneratePart_(false), + doSetModeName_(false), doOutDir_(false) {} void SetOptionData(char op); - void SetLanguage(String language); + void SetLanguage(const String& language); - void SetCodePart(String part); + void SetCodePart(const String& part); void CheckOptions(); @@ -122,22 +130,24 @@ private: static constexpr int VERSION_MINOR = 1; String program_; - String sourceFilePath_; + std::vector sourceFiles_; String targetLanguage_; String codePart_; + String modeName_; String generationDirectory_; String illegalOptions_; std::vector errors_; - bool doShowUsage_ = false; - bool doShowVersion_ = false; - bool doCompile_ = false; - bool doDumpAST_ = false; - bool doGetHashKey_ = false; - bool doGenerateCode_ = false; - bool doModeKernel_ = false; - bool doGeneratePart_ = false; - bool doOutDir_ = false; + bool doShowUsage_; + bool doShowVersion_; + bool doCompile_; + bool doDumpAST_; + bool doGetHashKey_; + bool doGenerateCode_; + bool doModeKernel_; + bool doGeneratePart_; + bool doSetModeName_; + bool doOutDir_; }; } // namespace HDI } // namespace OHOS