Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ea44149 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Packet: Refactor packet generation executable"

parents 8ddc001e 77ddc7e8
Loading
Loading
Loading
Loading
+66 −42
Original line number Diff line number Diff line
@@ -14,8 +14,8 @@
 * limitations under the License.
 */

#include <errno.h>
#include <unistd.h>
#include <cerrno>
#include <cstdio>
#include <filesystem>
#include <fstream>
@@ -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;
  }
}

@@ -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);

@@ -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;
  }

@@ -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";

@@ -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";
    }
  }
@@ -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;
}
@@ -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();
  }

+32 −30
Original line number Diff line number Diff line
@@ -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_) {
@@ -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;";
@@ -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) {
@@ -93,4 +96,3 @@ void StructParserGenerator::Generate(std::ostream& s) const {
    s << "return " << field->GetName() << "_value; }";
  }
}
}
+2 −2
Original line number Diff line number Diff line
@@ -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_;