/* * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "idlc/parser.h" #include "idlc/cs_gen/cs_proxy_gen.h" #include "idlc/cs_gen/cs_stub_gen.h" #include "idlc/cs_gen/cs_lib_gen.h" #include "idlc/c_gen/c_proxy_header_gen.h" #include "idlc/c_gen/c_proxy_body_gen.h" #include "idlc/c_gen/c_stub_header_gen.h" #include "idlc/c_gen/c_stub_body_gen.h" #include "idlc/cpp_gen/cpp_proxy_header_gen.h" #include "idlc/cpp_gen/cpp_proxy_body_gen.h" #include "idlc/cpp_gen/cpp_stub_header_gen.h" #include "idlc/cpp_gen/cpp_stub_body_gen.h" namespace { class Options { public: Options(); ~Options() = default; static std::unique_ptr Parse(int argc, char** argv); bool IsProxy() const { return isProxy_; } std::string GetLanguage() const { return language_; } std::string GetInput() const { return input_; } std::string GetOutput() const { return output_; } bool HasNamespace() const { return hasNamespace_; } bool HasRpcPortLib() const { return hasRpcPortLib_; } private: enum Cmd { CMD_PROXY, CMD_STUB, CMD_VERSION, CMD_HELP, CMD_MAX }; enum Opt { OPT_LANGUAGE, OPT_INPUT, OPT_OUTPUT, OPT_NAMESPACE, OPT_RPCLIB, OPT_MAX }; void PrintUsage(); void PrintVersion(); private: bool isProxy_; std::string language_; std::string input_; std::string output_; std::string help_; bool hasNamespace_ = false; bool hasRpcPortLib_ = false; }; Options::Options() { help_ = R"__option_cb( Usage: tidlc [OPTION...] Help Options: -h, --help Show help options Additional Options: -l, --language=LANGUAGE Select generating language (C, C++, C#). -i, --input=INPUT A tidl interface file. -o, --output=OUTPUT The generated interface file. -n, --namespace Add the prefix in the funtion name as output file name (C language only). -r, --rpclib Generate C# library for rpc-port (C# language only). Application Options: -p, --proxy Generate proxy code -s, --stub Generate stub code -v, --version Show version information )__option_cb"; } void Options::PrintUsage() { std::cerr << help_ << std::endl; } void Options::PrintVersion() { std::cerr << "tidlc " << FULLVER << std::endl; } std::unique_ptr Options::Parse(int argc, char** argv) { int cmd[CMD_MAX] = { 0, }; int opt[OPT_MAX] = { 0, }; auto options = std::unique_ptr(new Options()); int option_index = 0; struct option long_options[] = { {"proxy", no_argument, NULL, 'p'}, {"stub", no_argument, NULL, 's'}, {"version", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, {"language", required_argument, NULL, 'l'}, {"input", required_argument, NULL, 'i'}, {"output", required_argument, NULL, 'o'}, {"namespace", no_argument, NULL, 'n'}, {"rpclib", no_argument, NULL, 'r'}, {0, 0, 0, 0} }; while (true) { int c = getopt_long(argc, argv, "psvhl:i:o:nr", long_options, &option_index); if (c == -1) break; switch (c) { case 0: break; case 'p': cmd[CMD_PROXY] = 1; break; case 's': cmd[CMD_STUB] = 1; break; case 'v': cmd[CMD_VERSION] = 1; break; case 'h': cmd[CMD_HELP] = 1; break; case 'n': opt[OPT_NAMESPACE] = 1; break; case 'r': opt[OPT_RPCLIB] = 1; break; case 'l': opt[OPT_LANGUAGE] = 1; options->language_ = optarg; break; case 'i': opt[OPT_INPUT] = 1; options->input_ = optarg; break; case 'o': opt[OPT_OUTPUT] = 1; options->output_ = optarg; break; default: cmd[CMD_HELP] = 1; } } if (cmd[CMD_VERSION]) { options->PrintVersion(); return std::unique_ptr(nullptr); } if (cmd[CMD_HELP] || (!cmd[CMD_PROXY] && !cmd[CMD_STUB]) || !opt[OPT_LANGUAGE] || !opt[OPT_INPUT] || !opt[OPT_OUTPUT]) { options->PrintUsage(); return std::unique_ptr(nullptr); } options->isProxy_ = cmd[CMD_PROXY] ? true : false; options->hasNamespace_ = opt[OPT_NAMESPACE] ? true : false; options->hasRpcPortLib_ = opt[OPT_RPCLIB] ? true : false; return options; } } // namespace int main(int argc, char** argv) { std::unique_ptr<::Options> options = ::Options::Parse(argc, argv); if (!options) exit(1); tidl::Parser ps; std::string path(options->GetInput()); if (!ps.ParseFromFile(path)) exit(1); if (options->IsProxy()) { if (options->GetLanguage() == "C#") { tidl::CsProxyGen proxy(ps.GetDoc()); proxy.Run(options->GetOutput() + ".cs"); if (options->HasRpcPortLib()) { tidl::CsLibGen lib(ps.GetDoc()); lib.Run("rpc-port.cs"); } } else if (options->GetLanguage() == "C++") { tidl::CppProxyHeaderGen proxy_header(ps.GetDoc()); proxy_header.Run(options->GetOutput() + ".h"); tidl::CppProxyBodyGen proxy_body(ps.GetDoc()); proxy_body.Run(options->GetOutput() + ".cc"); } else if (options->GetLanguage() == "C") { tidl::CProxyHeaderGen proxy_header(ps.GetDoc()); proxy_header.EnableNamespace(options->HasNamespace()); proxy_header.Run(options->GetOutput() + ".h"); tidl::CProxyBodyGen proxy_body(ps.GetDoc()); proxy_body.EnableNamespace(options->HasNamespace()); proxy_body.Run(options->GetOutput() + ".c"); } } else { if (options->GetLanguage() == "C#") { tidl::CsStubGen stub(ps.GetDoc()); stub.Run(options->GetOutput() + ".cs"); if (options->HasRpcPortLib()) { tidl::CsLibGen lib(ps.GetDoc()); lib.Run("rpc-port.cs"); } } else if (options->GetLanguage() == "C++") { tidl::CppStubHeaderGen stub_header(ps.GetDoc()); stub_header.Run(options->GetOutput() + ".h"); tidl::CppStubBodyGen stub_body(ps.GetDoc()); stub_body.Run(options->GetOutput() + ".cc"); } else if (options->GetLanguage() == "C") { tidl::CStubHeaderGen stub_header(ps.GetDoc()); stub_header.EnableNamespace(options->HasNamespace()); stub_header.Run(options->GetOutput() + ".h"); tidl::CStubBodyGen stub_body(ps.GetDoc()); stub_body.EnableNamespace(options->HasNamespace()); stub_body.Run(options->GetOutput() + ".c"); } } return 0; }