diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d02809..9864a10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ add_executable(crpc src/rpc.cpp src/service.cpp src/plugins/c/c_message_plugin.cpp + src/plugins/c/generators/c_item.cpp ) target_link_libraries(crpc PRIVATE antlr4_static) target_include_directories(crpc PRIVATE /opt/dev/vcpkg/installed/arm64-osx/include/antlr4-runtime) diff --git a/main.cpp b/main.cpp index a6bb460..16b23c9 100644 --- a/main.cpp +++ b/main.cpp @@ -10,6 +10,7 @@ #include "plugins/c/c_message_plugin.h" #include #include +#include class Listener : public ProtoParserBaseListener { public: @@ -73,6 +74,15 @@ public: int main(int argc, char *argv[]) { + // show current working directory + char cwd[1024]; + if (getcwd(cwd, sizeof(cwd)) != NULL) { + std::cout << "Current working dir: " << cwd << std::endl; + } else { + perror("getcwd() error"); + return 1; + } + std::ifstream ifs; ifs.open(argv[1]); @@ -94,7 +104,7 @@ main(int argc, char *argv[]) std::cout << service->ToString() << std::endl; } - tqcq::CMessagePlugin message_plugin("/tmp/gen"); + tqcq::CMessagePlugin message_plugin("./gen/"); message_plugin.Generate(listener.message_map); return 0; diff --git a/src/item.h b/src/item.h index 5681b73..9c9d754 100644 --- a/src/item.h +++ b/src/item.h @@ -13,6 +13,7 @@ namespace tqcq { class Item { public: enum class Type { + kMessage, kInt32, kString }; diff --git a/src/plugins/c/c_message_plugin.cpp b/src/plugins/c/c_message_plugin.cpp index 2f2d559..545c4c3 100644 --- a/src/plugins/c/c_message_plugin.cpp +++ b/src/plugins/c/c_message_plugin.cpp @@ -6,24 +6,28 @@ #include #include #include +#include "generators/c_item.h" namespace tqcq { -static std::string GenerateGuardMacro(std::string id, std::string prefix) +static std::string +GenerateGuardMacro(std::string id, std::string prefix) { std::stringstream ss; ss << prefix << "_" << id << "_H_"; return ss.str(); } -static std::string GenerateHeaderFileName(std::string id) +std::string +CMessagePlugin::GenerateHeaderFileName(std::string id) { std::stringstream ss; ss << id << ".h"; return ss.str(); } -std::string GenerateSourceFileName(std::string id) +std::string +GenerateSourceFileName(std::string id) { std::stringstream ss; ss << id << ".c"; @@ -77,6 +81,11 @@ CMessagePlugin::GenerateIncludeGuardStart(Message::Ptr message) ss << "#ifndef " << guard_macro << std::endl; ss << "#define " << guard_macro << std::endl; ss << std::endl; + + ss << "#ifdef __cplusplus" << std::endl; + ss << "extern \"C\" {" << std::endl; + ss << "#endif" << std::endl; + ss << std::endl; return ss.str(); } @@ -84,6 +93,9 @@ std::string CMessagePlugin::GenerateIncludeGuardEnd(Message::Ptr message) { std::stringstream ss; + ss << "#ifdef __cplusplus" << std::endl; + ss << "}" << std::endl; + ss << "#endif" << std::endl; ss << "#endif //" << GenerateGuardMacro(message->id(), generate_prefix()) << std::endl; return ss.str(); } @@ -101,7 +113,8 @@ std::string CMessagePlugin::GenerateStructStart(Message::Ptr message) { std::stringstream ss; - ss << "typedef struct " << " {" << std::endl; + ss << "typedef struct " + << " {" << std::endl; return ss.str(); } @@ -110,8 +123,7 @@ CMessagePlugin::GenerateStructItem(Message::Ptr message) { std::stringstream ss; for (auto &item : message->items()) { - auto type_name = TranslateTypeToCType(item->type()); - ss << " " << type_name << " " << item->id() << ";" << std::endl; + ss << CItem::Create(item)->GenerateStructDeclareCodeBlock(message->id()) << std::endl; } return ss.str(); } @@ -128,13 +140,48 @@ CMessagePlugin::GenerateStructEnd(Message::Ptr message) std::string CMessagePlugin::GenerateFunctionDeclaration(Message::Ptr message) { - return std::string(); + std::stringstream ss; + ss << "void " << message->id() << "_Init(" << message->id() << "* message);" << std::endl; + ss << "void " << message->id() << "_Destroy(" << message->id() << "* message);" << std::endl; + ss << std::endl; + + ss << "int32_t " << message->id() << "_Serialize(" << message->id() + << "* message, char* buffer, int32_t buffer_size);" << std::endl; + ss << "int32_t " << message->id() << "_Deserialize(" << message->id() + << "* message, char* buffer, int32_t buffer_size);" << std::endl; + ss << std::endl; + + for (auto &item : message->items()) { + auto c_item = CItem::Create(item); + ss << c_item->GenerateSetterDeclaration(message->id()) << std::endl; + ss << c_item->GenerateGetterDeclaration(message->id()) << std::endl; + } + ss << std::endl; + + return ss.str(); } std::string CMessagePlugin::GenerateFunctionDefinition(Message::Ptr message) { - return std::string(); + std::stringstream ss; + ss << GenerateFunctionDefinitionInit(message); + ss << GenerateFunctionDefinitionDestroy(message); + ss << std::endl; + + ss << GenerateFunctionDefinitionSerialize(message); + ss << GenerateFunctionDefinitionDeserialize(message); + ss << std::endl; + + for (auto &item : message->items()) { + auto c_item = CItem::Create(item); + ss << c_item->GenerateSetterDefinition(message->id()) << std::endl; + ss << c_item->GenerateGetterDefinition(message->id()) << std::endl; + } + ss << std::endl; + + + return ss.str(); } std::string @@ -142,29 +189,70 @@ CMessagePlugin::GenerateSourceIncludeFile(Message::Ptr message) { std::stringstream ss; ss << "#include \"" << GenerateHeaderFileName(message->id()) << "\"" << std::endl; + ss << "#include " << std::endl; + ss << "#include " << std::endl; + ss << std::endl; + return ss.str(); +} +std::string +CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message) +{ + std::stringstream ss; + ss << "int32_t " << message->id() << "_Serialize(" << message->id() + << "* message, char* buffer, int32_t buffer_size) {" << std::endl; + ss << " int32_t offset = 0;" << std::endl; + for (auto &item : message->items()) { + auto c_item = CItem::Create(item); + ss << c_item->GenerateSerializeCodeBlock(message->id()) << std::endl; + } + ss << " return offset;" << std::endl; + ss << "}" << std::endl; ss << std::endl; return ss.str(); } std::string -CMessagePlugin::TranslateTypeToCType(Item::Type type) +CMessagePlugin::GenerateFunctionDefinitionDeserialize(Message::Ptr message) { - switch(type) { - case Item::Type::kInt32: - return "int32_t"; - case Item::Type::kString: - return "char*"; + std::stringstream ss; + ss << "int32_t " << message->id() << "_Deserialize(" << message->id() + << "* message, char* buffer, int32_t buffer_size) {" << std::endl; + ss << " int32_t offset = 0;" << std::endl; + for (auto &item : message->items()) { + auto c_item = CItem::Create(item); + ss << c_item->GenerateDeserializeCodeBlock(message->id()) << std::endl; } + ss << " return offset;" << std::endl; + ss << "}" << std::endl; + ss << std::endl; + return ss.str(); } std::string -CMessagePlugin::TranslateTypeToRealType(Item::Type type) +CMessagePlugin::GenerateFunctionDefinitionInit(Message::Ptr message) { - switch(type) { - case Item::Type::kInt32: - return "int32_t"; - case Item::Type::kString: - return "char*"; + std::stringstream ss; + ss << "void " << message->id() << "_Init(" << message->id() << "* message) {" << std::endl; + for (auto &item : message->items()) { + auto c_item = CItem::Create(item); + ss << c_item->GenerateInitCodeBlock(message->id()) << std::endl; } + ss << "}" << std::endl; + ss << std::endl; + return ss.str(); +} + +std::string +CMessagePlugin::GenerateFunctionDefinitionDestroy(Message::Ptr message) +{ + std::stringstream ss; + ss << "void " << message->id() << "_Destroy(" << message->id() << "* message) {" << std::endl; + for (auto &item : message->items()) { + auto c_item = CItem::Create(item); + ss << c_item->GenerateDestroyCodeBlock(message->id()) << std::endl; + } + ss << "}" << std::endl; + ss << std::endl; + return ss.str(); } }// namespace tqcq diff --git a/src/plugins/c/c_message_plugin.h b/src/plugins/c/c_message_plugin.h index bd23f4e..9a2e14c 100644 --- a/src/plugins/c/c_message_plugin.h +++ b/src/plugins/c/c_message_plugin.h @@ -11,6 +11,7 @@ namespace tqcq { class CMessagePlugin : public MessagePlugin { public: + static std::string GenerateHeaderFileName(std::string message_id); CMessagePlugin(std::string generate_path, std::string generate_prefix="CRPC"); ~CMessagePlugin() override = default; void GenerateHeader(std::map message_map) override; @@ -28,10 +29,18 @@ private: std::string GenerateFunctionDeclaration(Message::Ptr message); std::string GenerateFunctionDefinition(Message::Ptr message); + std::string GenerateFunctionDefinitionGetter(Message::Ptr message, Item::Ptr item); + std::string GenerateFunctionDefinitionSetter(Message::Ptr message, Item::Ptr item); + std::string GenerateFunctionDefinitionSerialize(Message::Ptr message); + std::string GenerateFunctionDefinitionDeserialize(Message::Ptr message); + std::string GenerateFunctionDefinitionInit(Message::Ptr message); + std::string GenerateFunctionDefinitionDestroy(Message::Ptr message); + + std::string GenerateSourceIncludeFile(Message::Ptr message); - std::string TranslateTypeToCType(Item::Type type); - std::string TranslateTypeToRealType(Item::Type type); + std::string TranslateTypeToCType(Message::Ptr message, Item::Type type); + std::string TranslateTypeToRealType(Message::Ptr message, Item::Type type); }; }// namespace tqcq diff --git a/src/plugins/message_plugin.cpp b/src/plugins/message_plugin.cpp index a129768..3afe4ea 100644 --- a/src/plugins/message_plugin.cpp +++ b/src/plugins/message_plugin.cpp @@ -3,11 +3,35 @@ // #include "message_plugin.h" +#include +#include +#include namespace tqcq { + +static void EnsureDirectoryExist(std::string path) +{ + std::string::size_type pos = 0; + while (true) { + pos = path.find('/', pos); + if (pos == std::string::npos) { + break; + } + std::string dir = path.substr(0, pos); + int status = mkdir(dir.c_str(), 0755); + if (status != 0 && errno != EEXIST) { + perror("mkdir"); + exit(1); + } + pos++; + } +} + MessagePlugin::MessagePlugin(std::string generate_path, std::string generate_prefix) : generate_path_(std::move(generate_path)), generate_prefix_(std::move(generate_prefix)) -{} +{ + EnsureDirectoryExist(generate_path_); +} void MessagePlugin::Generate(std::map message_map)