Loading system/gd/packet/parser/main.cc +66 −42 Original line number Diff line number Diff line Loading @@ -14,8 +14,8 @@ * limitations under the License. */ #include <errno.h> #include <unistd.h> #include <cerrno> #include <cstdio> #include <filesystem> #include <fstream> Loading @@ -37,21 +37,21 @@ void yyset_in(FILE*, void*); namespace { void parse_namespace(std::string root_namespace, std::filesystem::path input_file_relative_path, std::vector<std::string>& token) { void parse_namespace(const std::string& root_namespace, const std::filesystem::path& input_file_relative_path, std::vector<std::string>* token) { std::filesystem::path gen_namespace = root_namespace / input_file_relative_path; std::string gen_namespace_str = gen_namespace; std::regex path_tokenizer("/"); auto it = std::sregex_token_iterator(gen_namespace_str.cbegin(), gen_namespace_str.cend(), path_tokenizer, -1); std::sregex_token_iterator it_end; std::sregex_token_iterator it_end = {}; for (; it != it_end; ++it) { token.push_back(it->str()); token->push_back(it->str()); } } void generate_namespace_open(const std::vector<std::string>& token, std::ostream& output) { for (auto it = token.begin(); it != token.end(); ++it) { output << "namespace " << *it << " {" << std::endl; for (const auto& ns : token) { output << "namespace " << ns << " {" << std::endl; } } Loading @@ -61,17 +61,7 @@ void generate_namespace_close(const std::vector<std::string>& token, std::ostrea } } bool parse_one_file(std::filesystem::path input_file, std::filesystem::path include_dir, std::filesystem::path out_dir, std::string root_namespace) { auto gen_relative_path = input_file.lexically_relative(include_dir).parent_path(); auto input_filename = input_file.filename().string().substr(0, input_file.filename().string().find(".pdl")); auto gen_path = out_dir / gen_relative_path; std::filesystem::create_directories(gen_path); auto gen_file = gen_path / (input_filename + ".h"); bool parse_declarations_one_file(const std::filesystem::path& input_file, Declarations* declarations) { void* scanner; yylex_init(&scanner); Loading @@ -83,20 +73,47 @@ bool parse_one_file(std::filesystem::path input_file, std::filesystem::path incl yyset_in(in_file, scanner); std::ofstream out_file; out_file.open(gen_file); if (!out_file.is_open()) { std::cerr << "can't open " << gen_file << std::endl; int ret = yy::parser(scanner, declarations).parse(); if (ret != 0) { std::cerr << "yylex parsing failed: returned " << ret << std::endl; return false; } Declarations decls; int ret = yy::parser(scanner, &decls).parse(); yylex_destroy(scanner); if (ret != 0) { std::cerr << "yylex parsing failed: returned " << ret << std::endl; fclose(in_file); // Set endianess before returning for (auto& s : declarations->type_defs_queue_) { if (s.second->GetDefinitionType() == TypeDef::Type::STRUCT) { auto* struct_def = dynamic_cast<StructDef*>(s.second); struct_def->SetEndianness(declarations->is_little_endian); } } for (auto& packet_def : declarations->packet_defs_queue_) { packet_def.second.SetEndianness(declarations->is_little_endian); } return true; } bool generate_cpp_headers_one_file(const Declarations& decls, const std::filesystem::path& input_file, const std::filesystem::path& include_dir, const std::filesystem::path& out_dir, const std::string& root_namespace) { auto gen_relative_path = input_file.lexically_relative(include_dir).parent_path(); auto input_filename = input_file.filename().string().substr(0, input_file.filename().string().find(".pdl")); auto gen_path = out_dir / gen_relative_path; std::filesystem::create_directories(gen_path); auto gen_file = gen_path / (input_filename + ".h"); std::ofstream out_file; out_file.open(gen_file); if (!out_file.is_open()) { std::cerr << "can't open " << gen_file << std::endl; return false; } Loading Loading @@ -127,7 +144,7 @@ bool parse_one_file(std::filesystem::path input_file, std::filesystem::path incl out_file << "\n\n"; std::vector<std::string> namespace_list; parse_namespace(root_namespace, gen_relative_path, namespace_list); parse_namespace(root_namespace, gen_relative_path, &namespace_list); generate_namespace_open(namespace_list, out_file); out_file << "\n\n"; Loading @@ -152,36 +169,40 @@ bool parse_one_file(std::filesystem::path input_file, std::filesystem::path incl for (const auto& e : decls.type_defs_queue_) { if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) { EnumGen gen(*(EnumDef*)e.second); const auto* enum_def = dynamic_cast<const EnumDef*>(e.second); EnumGen gen(*enum_def); gen.GenDefinition(out_file); out_file << "\n\n"; } } for (const auto& e : decls.type_defs_queue_) { if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) { EnumGen gen(*(EnumDef*)e.second); const auto* enum_def = dynamic_cast<const EnumDef*>(e.second); EnumGen gen(*enum_def); gen.GenLogging(out_file); out_file << "\n\n"; } } for (const auto& ch : decls.type_defs_queue_) { if (ch.second->GetDefinitionType() == TypeDef::Type::CHECKSUM) { ((ChecksumDef*)ch.second)->GenChecksumCheck(out_file); const auto* checksum_def = dynamic_cast<const ChecksumDef*>(ch.second); checksum_def->GenChecksumCheck(out_file); } } out_file << "\n/* Done ChecksumChecks */\n"; for (const auto& c : decls.type_defs_queue_) { if (c.second->GetDefinitionType() == TypeDef::Type::CUSTOM && c.second->size_ == -1 /* Variable Size */) { ((CustomFieldDef*)c.second)->GenCustomFieldCheck(out_file, decls.is_little_endian); const auto* custom_field_def = dynamic_cast<const CustomFieldDef*>(c.second); custom_field_def->GenCustomFieldCheck(out_file, decls.is_little_endian); } } out_file << "\n"; for (auto& s : decls.type_defs_queue_) { if (s.second->GetDefinitionType() == TypeDef::Type::STRUCT) { ((StructDef*)s.second)->SetEndianness(decls.is_little_endian); ((StructDef*)s.second)->GenDefinition(out_file); const auto* struct_def = dynamic_cast<const StructDef*>(s.second); struct_def->GenDefinition(out_file); out_file << "\n"; } } Loading @@ -192,21 +213,19 @@ bool parse_one_file(std::filesystem::path input_file, std::filesystem::path incl out_file << "\n\n"; } for (size_t i = 0; i < decls.packet_defs_queue_.size(); i++) { decls.packet_defs_queue_[i].second.SetEndianness(decls.is_little_endian); decls.packet_defs_queue_[i].second.GenParserDefinition(out_file); for (const auto& packet_def : decls.packet_defs_queue_) { packet_def.second.GenParserDefinition(out_file); out_file << "\n\n"; } for (const auto p : decls.packet_defs_queue_) { p.second.GenBuilderDefinition(out_file); for (const auto& packet_def : decls.packet_defs_queue_) { packet_def.second.GenBuilderDefinition(out_file); out_file << "\n\n"; } generate_namespace_close(namespace_list, out_file); out_file.close(); fclose(in_file); return true; } Loading Loading @@ -245,10 +264,15 @@ int main(int argc, const char** argv) { } while (!input_files.empty()) { if (!parse_one_file(input_files.front(), include_dir, out_dir, root_namespace)) { std::cerr << "Didn't parse " << input_files.front() << " correctly" << std::endl; Declarations declarations; if (!parse_declarations_one_file(input_files.front(), &declarations)) { std::cerr << "Cannot parse " << input_files.front() << " correctly" << std::endl; return 2; } if (!generate_cpp_headers_one_file(declarations, input_files.front(), include_dir, out_dir, root_namespace)) { std::cerr << "Didn't generate cpp headers for " << input_files.front() << std::endl; return 3; } input_files.pop(); } Loading system/gd/packet/parser/struct_parser_generator.cc +32 −30 Original line number Diff line number Diff line Loading @@ -16,11 +16,12 @@ #include "struct_parser_generator.h" StructParserGenerator::StructParserGenerator(Declarations& decls) { StructParserGenerator::StructParserGenerator(const Declarations& decls) { is_little_endian = decls.is_little_endian; for (auto& s : decls.type_defs_queue_) { for (const auto& s : decls.type_defs_queue_) { if (s.second->GetDefinitionType() == TypeDef::Type::STRUCT) { variable_struct_fields_.push_back((StructDef*)s.second); const auto* struct_def = dynamic_cast<const StructDef*>(s.second); variable_struct_fields_.emplace_back(struct_def); } } for (const auto& node : variable_struct_fields_) { Loading @@ -36,10 +37,10 @@ StructParserGenerator::StructParserGenerator(Declarations& decls) { void StructParserGenerator::explore_children(const TreeNode& node, std::ostream& s) const { auto field = node.packet_field_; if (node.children_.size() > 0) { if (!node.children_.empty()) { s << "bool " << field->GetName() << "_child_found = false; /* Greedy match */"; } for (const auto child : node.children_) { for (const auto& child : node.children_) { s << "if (!" << field->GetName() << "_child_found && "; s << child->struct_def_->name_ << "::IsInstance(*" << field->GetName() << "_value.get())) {"; s << field->GetName() << "_child_found = true;"; Loading @@ -65,7 +66,9 @@ void StructParserGenerator::explore_children(const TreeNode& node, std::ostream& void StructParserGenerator::Generate(std::ostream& s) const { for (const auto& node : variable_struct_fields_) { if (node.children_.size() > 0) { if (node.children_.empty()) { continue; } auto field = node.packet_field_; s << "inline std::unique_ptr<" << node.struct_def_->name_ << "> Parse" << node.struct_def_->name_; if (is_little_endian) { Loading Loading @@ -93,4 +96,3 @@ void StructParserGenerator::Generate(std::ostream& s) const { s << "return " << field->GetName() << "_value; }"; } } } system/gd/packet/parser/struct_parser_generator.h +2 −2 Original line number Diff line number Diff line Loading @@ -24,14 +24,14 @@ class StructParserGenerator { public: StructParserGenerator(Declarations& declarations); explicit StructParserGenerator(const Declarations& declarations); void Generate(std::ostream& s) const; private: class TreeNode { public: TreeNode(const StructDef* s) explicit TreeNode(const StructDef* s) : struct_def_(s), packet_field_(s->GetNewField(s->name_ + "_parse", ParseLocation())) {} const StructDef* struct_def_; const PacketField* packet_field_; Loading Loading
system/gd/packet/parser/main.cc +66 −42 Original line number Diff line number Diff line Loading @@ -14,8 +14,8 @@ * limitations under the License. */ #include <errno.h> #include <unistd.h> #include <cerrno> #include <cstdio> #include <filesystem> #include <fstream> Loading @@ -37,21 +37,21 @@ void yyset_in(FILE*, void*); namespace { void parse_namespace(std::string root_namespace, std::filesystem::path input_file_relative_path, std::vector<std::string>& token) { void parse_namespace(const std::string& root_namespace, const std::filesystem::path& input_file_relative_path, std::vector<std::string>* token) { std::filesystem::path gen_namespace = root_namespace / input_file_relative_path; std::string gen_namespace_str = gen_namespace; std::regex path_tokenizer("/"); auto it = std::sregex_token_iterator(gen_namespace_str.cbegin(), gen_namespace_str.cend(), path_tokenizer, -1); std::sregex_token_iterator it_end; std::sregex_token_iterator it_end = {}; for (; it != it_end; ++it) { token.push_back(it->str()); token->push_back(it->str()); } } void generate_namespace_open(const std::vector<std::string>& token, std::ostream& output) { for (auto it = token.begin(); it != token.end(); ++it) { output << "namespace " << *it << " {" << std::endl; for (const auto& ns : token) { output << "namespace " << ns << " {" << std::endl; } } Loading @@ -61,17 +61,7 @@ void generate_namespace_close(const std::vector<std::string>& token, std::ostrea } } bool parse_one_file(std::filesystem::path input_file, std::filesystem::path include_dir, std::filesystem::path out_dir, std::string root_namespace) { auto gen_relative_path = input_file.lexically_relative(include_dir).parent_path(); auto input_filename = input_file.filename().string().substr(0, input_file.filename().string().find(".pdl")); auto gen_path = out_dir / gen_relative_path; std::filesystem::create_directories(gen_path); auto gen_file = gen_path / (input_filename + ".h"); bool parse_declarations_one_file(const std::filesystem::path& input_file, Declarations* declarations) { void* scanner; yylex_init(&scanner); Loading @@ -83,20 +73,47 @@ bool parse_one_file(std::filesystem::path input_file, std::filesystem::path incl yyset_in(in_file, scanner); std::ofstream out_file; out_file.open(gen_file); if (!out_file.is_open()) { std::cerr << "can't open " << gen_file << std::endl; int ret = yy::parser(scanner, declarations).parse(); if (ret != 0) { std::cerr << "yylex parsing failed: returned " << ret << std::endl; return false; } Declarations decls; int ret = yy::parser(scanner, &decls).parse(); yylex_destroy(scanner); if (ret != 0) { std::cerr << "yylex parsing failed: returned " << ret << std::endl; fclose(in_file); // Set endianess before returning for (auto& s : declarations->type_defs_queue_) { if (s.second->GetDefinitionType() == TypeDef::Type::STRUCT) { auto* struct_def = dynamic_cast<StructDef*>(s.second); struct_def->SetEndianness(declarations->is_little_endian); } } for (auto& packet_def : declarations->packet_defs_queue_) { packet_def.second.SetEndianness(declarations->is_little_endian); } return true; } bool generate_cpp_headers_one_file(const Declarations& decls, const std::filesystem::path& input_file, const std::filesystem::path& include_dir, const std::filesystem::path& out_dir, const std::string& root_namespace) { auto gen_relative_path = input_file.lexically_relative(include_dir).parent_path(); auto input_filename = input_file.filename().string().substr(0, input_file.filename().string().find(".pdl")); auto gen_path = out_dir / gen_relative_path; std::filesystem::create_directories(gen_path); auto gen_file = gen_path / (input_filename + ".h"); std::ofstream out_file; out_file.open(gen_file); if (!out_file.is_open()) { std::cerr << "can't open " << gen_file << std::endl; return false; } Loading Loading @@ -127,7 +144,7 @@ bool parse_one_file(std::filesystem::path input_file, std::filesystem::path incl out_file << "\n\n"; std::vector<std::string> namespace_list; parse_namespace(root_namespace, gen_relative_path, namespace_list); parse_namespace(root_namespace, gen_relative_path, &namespace_list); generate_namespace_open(namespace_list, out_file); out_file << "\n\n"; Loading @@ -152,36 +169,40 @@ bool parse_one_file(std::filesystem::path input_file, std::filesystem::path incl for (const auto& e : decls.type_defs_queue_) { if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) { EnumGen gen(*(EnumDef*)e.second); const auto* enum_def = dynamic_cast<const EnumDef*>(e.second); EnumGen gen(*enum_def); gen.GenDefinition(out_file); out_file << "\n\n"; } } for (const auto& e : decls.type_defs_queue_) { if (e.second->GetDefinitionType() == TypeDef::Type::ENUM) { EnumGen gen(*(EnumDef*)e.second); const auto* enum_def = dynamic_cast<const EnumDef*>(e.second); EnumGen gen(*enum_def); gen.GenLogging(out_file); out_file << "\n\n"; } } for (const auto& ch : decls.type_defs_queue_) { if (ch.second->GetDefinitionType() == TypeDef::Type::CHECKSUM) { ((ChecksumDef*)ch.second)->GenChecksumCheck(out_file); const auto* checksum_def = dynamic_cast<const ChecksumDef*>(ch.second); checksum_def->GenChecksumCheck(out_file); } } out_file << "\n/* Done ChecksumChecks */\n"; for (const auto& c : decls.type_defs_queue_) { if (c.second->GetDefinitionType() == TypeDef::Type::CUSTOM && c.second->size_ == -1 /* Variable Size */) { ((CustomFieldDef*)c.second)->GenCustomFieldCheck(out_file, decls.is_little_endian); const auto* custom_field_def = dynamic_cast<const CustomFieldDef*>(c.second); custom_field_def->GenCustomFieldCheck(out_file, decls.is_little_endian); } } out_file << "\n"; for (auto& s : decls.type_defs_queue_) { if (s.second->GetDefinitionType() == TypeDef::Type::STRUCT) { ((StructDef*)s.second)->SetEndianness(decls.is_little_endian); ((StructDef*)s.second)->GenDefinition(out_file); const auto* struct_def = dynamic_cast<const StructDef*>(s.second); struct_def->GenDefinition(out_file); out_file << "\n"; } } Loading @@ -192,21 +213,19 @@ bool parse_one_file(std::filesystem::path input_file, std::filesystem::path incl out_file << "\n\n"; } for (size_t i = 0; i < decls.packet_defs_queue_.size(); i++) { decls.packet_defs_queue_[i].second.SetEndianness(decls.is_little_endian); decls.packet_defs_queue_[i].second.GenParserDefinition(out_file); for (const auto& packet_def : decls.packet_defs_queue_) { packet_def.second.GenParserDefinition(out_file); out_file << "\n\n"; } for (const auto p : decls.packet_defs_queue_) { p.second.GenBuilderDefinition(out_file); for (const auto& packet_def : decls.packet_defs_queue_) { packet_def.second.GenBuilderDefinition(out_file); out_file << "\n\n"; } generate_namespace_close(namespace_list, out_file); out_file.close(); fclose(in_file); return true; } Loading Loading @@ -245,10 +264,15 @@ int main(int argc, const char** argv) { } while (!input_files.empty()) { if (!parse_one_file(input_files.front(), include_dir, out_dir, root_namespace)) { std::cerr << "Didn't parse " << input_files.front() << " correctly" << std::endl; Declarations declarations; if (!parse_declarations_one_file(input_files.front(), &declarations)) { std::cerr << "Cannot parse " << input_files.front() << " correctly" << std::endl; return 2; } if (!generate_cpp_headers_one_file(declarations, input_files.front(), include_dir, out_dir, root_namespace)) { std::cerr << "Didn't generate cpp headers for " << input_files.front() << std::endl; return 3; } input_files.pop(); } Loading
system/gd/packet/parser/struct_parser_generator.cc +32 −30 Original line number Diff line number Diff line Loading @@ -16,11 +16,12 @@ #include "struct_parser_generator.h" StructParserGenerator::StructParserGenerator(Declarations& decls) { StructParserGenerator::StructParserGenerator(const Declarations& decls) { is_little_endian = decls.is_little_endian; for (auto& s : decls.type_defs_queue_) { for (const auto& s : decls.type_defs_queue_) { if (s.second->GetDefinitionType() == TypeDef::Type::STRUCT) { variable_struct_fields_.push_back((StructDef*)s.second); const auto* struct_def = dynamic_cast<const StructDef*>(s.second); variable_struct_fields_.emplace_back(struct_def); } } for (const auto& node : variable_struct_fields_) { Loading @@ -36,10 +37,10 @@ StructParserGenerator::StructParserGenerator(Declarations& decls) { void StructParserGenerator::explore_children(const TreeNode& node, std::ostream& s) const { auto field = node.packet_field_; if (node.children_.size() > 0) { if (!node.children_.empty()) { s << "bool " << field->GetName() << "_child_found = false; /* Greedy match */"; } for (const auto child : node.children_) { for (const auto& child : node.children_) { s << "if (!" << field->GetName() << "_child_found && "; s << child->struct_def_->name_ << "::IsInstance(*" << field->GetName() << "_value.get())) {"; s << field->GetName() << "_child_found = true;"; Loading @@ -65,7 +66,9 @@ void StructParserGenerator::explore_children(const TreeNode& node, std::ostream& void StructParserGenerator::Generate(std::ostream& s) const { for (const auto& node : variable_struct_fields_) { if (node.children_.size() > 0) { if (node.children_.empty()) { continue; } auto field = node.packet_field_; s << "inline std::unique_ptr<" << node.struct_def_->name_ << "> Parse" << node.struct_def_->name_; if (is_little_endian) { Loading Loading @@ -93,4 +96,3 @@ void StructParserGenerator::Generate(std::ostream& s) const { s << "return " << field->GetName() << "_value; }"; } } }
system/gd/packet/parser/struct_parser_generator.h +2 −2 Original line number Diff line number Diff line Loading @@ -24,14 +24,14 @@ class StructParserGenerator { public: StructParserGenerator(Declarations& declarations); explicit StructParserGenerator(const Declarations& declarations); void Generate(std::ostream& s) const; private: class TreeNode { public: TreeNode(const StructDef* s) explicit TreeNode(const StructDef* s) : struct_def_(s), packet_field_(s->GetNewField(s->name_ + "_parse", ParseLocation())) {} const StructDef* struct_def_; const PacketField* packet_field_; Loading