feat: generate code

This commit is contained in:
anjingyu 2025-07-14 21:47:13 +08:00
parent 602abeddc1
commit 07a4e3acad
9 changed files with 548 additions and 67 deletions

View File

@ -8,6 +8,8 @@ set (ADMAKE_DISABLE_ADDRESS_SANITIZER ON)
include (CMakeListsPub)
set (TARGET_NAME ${CMAKE_PROJECT_NAME})
append_3rd_modules (rapidjson)
if (DEFINED ADMAKE_BUILD_TEST)
append_modules (dbcc)
file (GLOB_RECURSE TEST_SRC

View File

@ -0,0 +1,51 @@
#pragma once
#include <cstdint>
#include <string> /**< std::string */
#include <vector> /**< std::vector */
#include <memory> /**< std::unique_ptr */
#include "dbcc/signal.h"
#include "dbcc/message.h"
namespace ad {
namespace dbcc {
namespace helper {
typedef std::pair<std::string, ad::dbcc::Signal> NameSignalPair;
typedef std::vector<NameSignalPair> NameSignalVector;
class GenHelper final
{
public:
GenHelper(const std::string &dbc, const std::string &dbc_json);
~GenHelper();
std::string GenAll();
std::string GenMessageDef(const std::string &msg, int indent_level);
std::string GenMessageUnpackDecl(const std::string &msg, int indent_level);
std::string GenMessageUnpackDef(const std::string &msg, int indent_level);
std::string GenMessagePackDecl(const std::string &msg, int indent_level);
std::string GenMessagePackDef(const std::string &msg, int indent_level);
static std::string GenMessageDef(const ad::dbcc::Message &msg, const ad::dbcc::helper::NameSignalVector &sigs,
int indent_level);
static std::string GenMessageUnpackDecl(const ad::dbcc::Message &msg, int indent_level);
static std::string GenMessageUnpackDef(const ad::dbcc::Message &msg, const ad::dbcc::helper::NameSignalVector &sigs,
int indent_level);
static std::string GenMessagePackDecl(const ad::dbcc::Message &msg, int indent_level);
static std::string GenMessagePackDef(const ad::dbcc::Message &msg, const ad::dbcc::helper::NameSignalVector &sigs,
int indent_level);
private:
class Generator;
std::unique_ptr<Generator> impl_;
};
} // namespace helper
} // namespace dbcc
} // namespace ad

View File

@ -0,0 +1,416 @@
#include "dbcc/helper/gen_helper.h"
#include <sstream>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include "dbcc/dbc_iterator.h"
#include "dbcc/message.h" /**< ad::dbcc::Message */
#include "dbcc/helper/signal_helper.h"
#include "rapidjson/document.h" /**< rapidjson::Document */
#include "rapidjson/istreamwrapper.h" /**< rapidjson::IStreamWrapper */
namespace ad {
namespace dbcc {
namespace helper {
const std::string kDefaultIndentSpaces = " ";
const std::string kCPackAndUnpackMacros = std::string(
"#define PACK_LEFT_SHIFT(value,shift,mask) (uint8_t)((uint8_t)(value << "
"shift) & mask)\n"
"#define UNPACK_LEFT_SHIFT(_type,value,shift,mask) (_type)((_type)(value & "
"mask) << shift)\n"
"\n"
"#define PACK_RIGHT_SHIFT(value,shift,mask) (uint8_t)((uint8_t)(value >> "
"shift) & mask)\n"
"#define UNPACK_RIGHT_SHIFT(_type,value,shift,mask) (_type)((_type)(value "
"& mask) >> shift)\n");
inline const std::string GenerateIndent(int indent_level)
{
std::stringstream ss;
for (int i = 0; i < indent_level; i++) {
ss << kDefaultIndentSpaces;
}
return ss.str();
}
class GenHelper::Generator
{
public:
Generator(const std::string &dbc, const std::string &dbc_json) : iter_(dbc)
{
const std::vector<std::string> kRequiredKeys{"control", "feedback"};
std::ifstream ifs(dbc_json.c_str());
if (!ifs.good())
{
// Maybe the fail is not readable, not existent etc.
throw std::runtime_error("Failed to load the configuration file: " + dbc_json);
}
rapidjson::IStreamWrapper isw(ifs);
config_.ParseStream(isw);
// Check the required keys
for (auto &s : kRequiredKeys)
{
if (!config_.HasMember(s.c_str()))
{
throw std::runtime_error("Required key <" + s + "> is not existent!");
}
}
}
~Generator() = default;
inline std::string GenAll()
{
ad::dbcc::helper::NameSignalVector sigs;
std::stringstream ss;
ss << kCPackAndUnpackMacros << std::endl;
for (auto &msg : config_["feedback"].GetObject())
{
sigs.clear();
ad::dbcc::Message msgp = FindMessageByName(msg.name.GetString());
for (auto &m : msg.value.GetObject())
{
size_t idx = msgp[m.name.GetString()];
if (idx != ad::dbcc::kInvalidIndex)
{
sigs.push_back(std::make_pair(m.name.GetString(), msgp[idx]));
} else {
throw std::runtime_error("The signal " + std::string(m.name.GetString()) + " is NOT existent!");
}
}
ss << GenHelper::GenMessageDef(msgp, sigs, 0) << std::endl;
ss << GenHelper::GenMessageUnpackDecl(msgp, 0) << std::endl;
ss << GenHelper::GenMessageUnpackDef(msgp, sigs, 0) << std::endl;
}
for (auto &msg : config_["control"].GetObject())
{
sigs.clear();
ad::dbcc::Message msgp = FindMessageByName(msg.name.GetString());
for (auto &m : msg.value.GetObject())
{
size_t idx = msgp[m.name.GetString()];
if (idx != ad::dbcc::kInvalidIndex)
{
sigs.push_back(std::make_pair(m.name.GetString(), msgp[idx]));
} else {
throw std::runtime_error("The signal " + std::string(m.name.GetString()) + " is NOT existent!");
}
}
ss << GenHelper::GenMessageDef(msgp, sigs, 0) << std::endl;
ss << GenHelper::GenMessagePackDecl(msgp, 0) << std::endl;
ss << GenHelper::GenMessagePackDef(msgp, sigs, 0) << std::endl;
}
return ss.str();
}
inline ad::dbcc::Message &FindMessageByName(const std::string &msg)
{
for (auto &m : iter_)
{
if (m.Name() == msg)
{
return m;
}
}
throw std::runtime_error("Message is NOT existent: " + msg);
}
inline ad::dbcc::helper::NameSignalVector GenSignalsFromMessage(const std::string &msg)
{
ad::dbcc::helper::NameSignalVector sigs;
if (config_["feedback"].HasMember(msg.c_str()))
{
if (config_["feedback"][msg.c_str()].IsObject())
{
ad::dbcc::Message msgp = FindMessageByName(msg);
for (auto &m : config_["feedback"][msg.c_str()].GetObject())
{
size_t idx = msgp[m.name.GetString()];
if (idx != ad::dbcc::kInvalidIndex)
{
sigs.push_back(std::make_pair(m.name.GetString(), msgp[idx]));
} else {
throw std::runtime_error("The signal " + std::string(m.name.GetString()) + " is NOT existent!");
}
}
} else {
throw std::runtime_error("The value of a message can ONLY be an object");
}
}
else if (config_["control"].HasMember(msg.c_str()))
{
if (config_["control"][msg.c_str()].IsObject())
{
ad::dbcc::Message msgp = FindMessageByName(msg);
for (auto &m : config_["control"][msg.c_str()].GetObject())
{
size_t idx = msgp[m.name.GetString()];
if (idx != ad::dbcc::kInvalidIndex)
{
sigs.push_back(std::make_pair(m.name.GetString(), msgp[idx]));
} else {
throw std::runtime_error("The signal " + std::string(m.name.GetString()) + " is NOT existent!");
}
}
} else {
throw std::runtime_error("The value of a message can ONLY be an object");
}
}
else
{
throw std::runtime_error("The message is not existent: " + msg);
}
return sigs;
}
inline std::string GenMessageDef(const std::string &msg, int indent_level)
{
ad::dbcc::helper::NameSignalVector sigs = GenSignalsFromMessage(msg);
ad::dbcc::Message msgp = FindMessageByName(msg);
return GenHelper::GenMessageDef(msgp, sigs, indent_level);
}
inline std::string GenMessageUnpackDecl(const std::string &msg, int indent_level)
{
ad::dbcc::Message msgp = FindMessageByName(msg);
return GenHelper::GenMessageUnpackDecl(msgp, indent_level);
}
inline std::string GenMessageUnpackDef(const std::string &msg, int indent_level)
{
ad::dbcc::helper::NameSignalVector sigs = GenSignalsFromMessage(msg);
ad::dbcc::Message msgp = FindMessageByName(msg);
return GenHelper::GenMessageUnpackDef(msgp, sigs, indent_level);
}
inline std::string GenMessagePackDecl(const std::string &msg, int indent_level)
{
ad::dbcc::Message msgp = FindMessageByName(msg);
return GenHelper::GenMessagePackDecl(msgp, indent_level);
}
inline std::string GenMessagePackDef(const std::string &msg, int indent_level)
{
ad::dbcc::helper::NameSignalVector sigs = GenSignalsFromMessage(msg);
ad::dbcc::Message msgp = FindMessageByName(msg);
return GenHelper::GenMessagePackDef(msgp, sigs, indent_level);
}
private:
ad::dbcc::DbcIterator iter_;
rapidjson::Document config_;
};
GenHelper::GenHelper(const std::string &dbc, const std::string &dbc_json)
{
impl_ = std::unique_ptr<GenHelper::Generator>(new GenHelper::Generator(dbc, dbc_json));
}
GenHelper::~GenHelper() {}
std::string GenHelper::GenAll()
{
return impl_->GenAll();
}
std::string GenHelper::GenMessageDef(const std::string &msg, int indent_level)
{
return impl_->GenMessageDef(msg, indent_level);
}
std::string GenHelper::GenMessageUnpackDecl(const std::string &msg, int indent_level)
{
return impl_->GenMessageUnpackDecl(msg, indent_level);
}
std::string GenHelper::GenMessageUnpackDef(const std::string &msg, int indent_level)
{
return impl_->GenMessageUnpackDef(msg, indent_level);
}
std::string GenHelper::GenMessagePackDecl(const std::string &msg, int indent_level)
{
return impl_->GenMessagePackDecl(msg, indent_level);
}
std::string GenHelper::GenMessagePackDef(const std::string &msg, int indent_level)
{
return impl_->GenMessagePackDef(msg, indent_level);
}
/*
struct <msg.Name()>_<msg.Id()>
{
<type1> <sig1.Name()>;
<type2> <sig2.Name()>;
<type3> <sig3.Name()>;
...
};
*/
std::string GenHelper::GenMessageDef(const ad::dbcc::Message &msg, const ad::dbcc::helper::NameSignalVector &sigs,
int indent_level)
{
std::stringstream ss;
const std::string indent = GenerateIndent(indent_level);
const std::string indent2 = GenerateIndent(indent_level + 1);
ss << indent << "/* " << msg.Name() << "(0x" << std::hex << msg.Id() << std::dec << "), len: " << msg.Dlc() << " bytes */"
<< std::endl;
ss << indent << "typedef struct _" << msg.Name() << "_0x" << std::hex << msg.Id() << std::dec
<< std::endl;
ss << indent << "{" << std::endl;
for (const auto &sig : sigs) {
ad::dbcc::helper::SignalHelper sig_helper(sig.second);
std::string signal_member_name = sig.first.empty() ? sig.second.Name() : sig.first;
ss << indent2 << sig_helper.TypeName() << " "
<< signal_member_name << ";" << std::endl;
}
ss << indent << "} " << msg.Name() << "_0x" << std::hex << msg.Id() << std::dec << ";" << std::endl;
return ss.str();
}
std::string GenHelper::GenMessageUnpackDecl(const ad::dbcc::Message &msg, int indent_level)
{
std::stringstream ss;
const std::string indent = GenerateIndent(indent_level);
ss << indent << "/* Unpack message " << msg.Name() << "(0x" << std::hex << msg.Id() << std::dec << ") from a CAN data frame */"
<< std::endl;
ss << indent << "void Unpack_" << msg.Name() << "_0x" << std::hex << msg.Id() << std::dec
<< "(" << msg.Name() << "_0x" << std::hex << msg.Id() << std::dec << " *msg, const uint8_t *data, size_t len);" << std::endl;
return ss.str();
}
std::string GenHelper::GenMessageUnpackDef(const ad::dbcc::Message &msg, const ad::dbcc::helper::NameSignalVector &sigs,
int indent_level)
{
std::stringstream ss;
ss << msg.Name() << "_0x" << std::hex << msg.Id() << std::dec;
const std::string msg_name = ss.str();
const std::string indent = GenerateIndent(indent_level);
const std::string indent2 = GenerateIndent(indent_level + 1);
ss.str("");
ss.clear();
ss << indent << "/* Unpack message " << msg.Name() << "(0x" << std::hex << msg.Id() << std::dec << ") from a CAN data frame */"
<< std::endl;
ss << indent << "void Unpack_" << msg_name
<< "(" << msg_name << " *msg, const uint8_t *data, size_t len)" << std::endl;
ss << indent << "{" << std::endl;
bool need_new_line = false;
for (const auto &sig : sigs)
{
if (need_new_line)
{
ss << std::endl << std::endl;
}
ad::dbcc::helper::SignalHelper sig_helper(sig.second);
std::string signal_member_name = sig.first.empty() ? sig.second.Name() : sig.first;
ss << indent2 << "/* " << sig.second.Name() << ": "
<< sig.second.StartBit() << ", " << sig.second.Length() << " */"
<< std::endl;
ss << sig_helper.Unpack2Code(signal_member_name, "msg->", indent_level + 1) << std::endl;
need_new_line = true;
}
ss << indent << "}" << std::endl;
return ss.str();
}
std::string GenHelper::GenMessagePackDecl(const ad::dbcc::Message &msg, int indent_level)
{
std::stringstream ss;
const std::string indent = GenerateIndent(indent_level);
ss << indent << "/* Pack message " << msg.Name() << "(0x" << std::hex << msg.Id() << std::dec << ") as a CAN data frame */"
<< std::endl;
ss << indent << "void Pack_" << msg.Name() << "_0x" << std::hex << msg.Id() << std::dec
<< "(const " << msg.Name() << "_0x" << std::hex << msg.Id() << std::dec << " *msg, uint8_t *data, size_t len);" << std::endl;
return ss.str();
}
std::string GenHelper::GenMessagePackDef(const ad::dbcc::Message &msg, const ad::dbcc::helper::NameSignalVector &sigs,
int indent_level)
{
std::stringstream ss;
ss << msg.Name() << "_0x" << std::hex << msg.Id() << std::dec;
const std::string msg_name = ss.str();
const std::string indent = GenerateIndent(indent_level);
const std::string indent2 = GenerateIndent(indent_level + 1);
ss.str("");
ss.clear();
ss << indent << "/* Pack message " << msg.Name() << "(0x" << std::hex << msg.Id() << std::dec << ") as a CAN data frame */"
<< std::endl;
ss << indent << "void Pack_" << msg_name
<< "(const " << msg_name << " *msg, uint8_t *data, size_t len)" << std::endl;
ss << indent << "{" << std::endl;
bool need_new_line = false;
for (const auto &sig : sigs)
{
if (need_new_line)
{
ss << std::endl << std::endl;
}
ad::dbcc::helper::SignalHelper sig_helper(sig.second);
std::string signal_member_name = sig.first.empty() ? sig.second.Name() : sig.first;
ss << indent2 << "/* " << sig.second.Name() << ": "
<< sig.second.StartBit() << ", " << sig.second.Length() << " */"
<< std::endl;
ss << sig_helper.Pack2Code(signal_member_name, "msg->", indent_level + 1) << std::endl;
need_new_line = true;
}
ss << indent << "}" << std::endl;
return ss.str();
}
} // namespace helper
} // namespace dbcc
} // namespace ad

View File

@ -11,21 +11,7 @@ namespace ad {
namespace dbcc {
namespace helper {
typedef std::pair<std::string, ad::dbcc::Signal> NameSignalPair;
typedef std::vector<NameSignalPair> NameSignalVector;
const std::string DefaultIndentSpaces = " ";
const std::string CPackAndUnpackMacros = std::string(
"#define PACK_LEFT_SHIFT(value,shift,mask) (uint8_t)((uint8_t)(value << "
"shift) & mask)\n"
"#define UNPACK_LEFT_SHIFT(_type,value,shift,mask) (_type)((_type)(value & "
"mask) << shift)\n"
"\n"
"#define PACK_RIGHT_SHIFT(value,shift,mask) (uint8_t)((uint8_t)(value >> "
"shift) & mask)\n"
"#define UNPACK_RIGHT_SHIFT(_type,value,shift,mask) (_type)((_type)(value "
"& mask) >> shift)\n");
const std::string kDefaultIndentSpaces = " ";
inline void LeftTrim(std::string& s)
{
@ -55,7 +41,7 @@ inline const std::string GenerateIndent(int indent_level)
std::stringstream ss;
for (int i = 0; i < indent_level; i++) {
ss << DefaultIndentSpaces;
ss << kDefaultIndentSpaces;
}
return ss.str();
@ -202,19 +188,19 @@ std::string SignalHelper::Unpack2Code(const std::string& name, const std::string
// Unpack the type information of this signal
std::string signal_member_type = TypeName();
ss << indent << OperationTypeName() << " " << name << "Temp = 0;" << std::endl;
ss << indent << OperationTypeName() << " " << name << "_temp = 0;" << std::endl;
for (auto seg : Segments(true)) {
ss << indent;
if (seg.direction == ad::dbcc::helper::SignalHelper::ShiftDirection::kLeft) {
ss << name << "Temp |= UNPACK_LEFT_SHIFT(";
ss << name << "_temp |= UNPACK_LEFT_SHIFT(";
} else {
ss << name << "Temp |= UNPACK_RIGHT_SHIFT(";
ss << name << "_temp |= UNPACK_RIGHT_SHIFT(";
}
ss << OperationTypeName() << ", "
<< "frame.data[" << seg.index << "], " << seg.shift << "u, " << std::setw(2)
<< "data[" << seg.index << "], " << seg.shift << "u, " << std::setw(2)
<< std::setfill('0') << "0x" << std::hex << seg.mask << std::dec << "u);" << std::setw(0)
<< std::setfill(' ') << std::endl;
}
@ -228,18 +214,25 @@ std::string SignalHelper::Unpack2Code(const std::string& name, const std::string
mask <<= signal_.Length();
ss << indent << "if ((" << name << "Temp & (1" << cts << " << "
ss << indent << "if ((" << name << "_temp & (1" << cts << " << "
<< (signal_.Length() - 1) << ")) != 0" << cts << ")" << std::endl
<< indent << "{" << std::endl
<< indent2 << name << "Temp |= 0x" << std::hex << mask << std::dec << cts << ";"
<< indent2 << name << "_temp |= 0x" << std::hex << mask << std::dec << cts << ";"
<< std::endl
<< indent << "}" << std::endl;
}
}
ss << indent << prefix << name << " = (" << signal_member_type << ")(" << name << "Temp * "
<< signal_.Factor() << " + (" << signal_.Offset() << ")"
<< ");";
ss << indent << prefix << name << " = (" << signal_member_type << ")(" << name << "_temp";
if (signal_.Factor() != 1) {
ss << " * " << signal_.Factor();
}
if (signal_.Offset() != 0) {
ss << " + (" << signal_.Offset() << ")";
}
ss << ");";
return ss.str();
}
@ -250,9 +243,23 @@ std::string SignalHelper::Pack2Code(const std::string& name, const std::string&
std::stringstream ss;
bool need_new_line = false;
const std::string indent = GenerateIndent(indent_level);
ss << indent << OperationTypeName() << " " << name << "Temp = (" << OperationTypeName() << ")(("
<< prefix << name << " - (" << signal_.Offset() << ")) / " << signal_.Factor() << ");"
<< std::endl;
ss << indent << OperationTypeName() << " " << name << "_temp = (" << OperationTypeName() << ")(";
if (signal_.Factor() != 1) {
ss << "(";
}
ss << prefix << name;
if (signal_.Offset() != 0)
{
ss << " - (" << signal_.Offset() << ")";
}
if (signal_.Factor() != 1) {
ss << ") / " << signal_.Factor();
}
ss << ");" << std::endl;
for (auto seg : Segments()) {
if (need_new_line) {
@ -262,14 +269,14 @@ std::string SignalHelper::Pack2Code(const std::string& name, const std::string&
ss << indent;
if (seg.direction == ad::dbcc::helper::SignalHelper::ShiftDirection::kLeft) {
ss << "frame.data[" << seg.index << "]"
ss << "data[" << seg.index << "]"
<< " |= PACK_LEFT_SHIFT(";
} else {
ss << "frame.data[" << seg.index << "]"
ss << "data[" << seg.index << "]"
<< " |= PACK_RIGHT_SHIFT(";
}
ss << name << "Temp, " << seg.shift << "u, " << std::setw(2) << std::setfill('0') << "0x"
ss << name << "_temp, " << seg.shift << "u, " << std::setw(2) << std::setfill('0') << "0x"
<< std::hex << seg.mask << std::dec << "u);" << std::setw(0) << std::setfill(' ');
need_new_line = true;
}

View File

@ -92,7 +92,7 @@ static std::string SignalPack2Code(NameSignalPair &sig, int indent_level)
bool need_new_line = false;
const std::string indent = ad::dbcc::GenerateIndent(indent_level);
ss << indent << sig_helper.OperationTypeName() << " " << sig.first
<< "Temp = (" << sig_helper.OperationTypeName() << ")((controller->"
<< "Temp = (" << sig_helper.OperationTypeName() << ")((control->"
<< sig.first << " - (" << sig.second.Offset() << ")) / "
<< sig.second.Factor() << ");" << std::endl;
@ -264,7 +264,7 @@ static std::string GenerateUnpack(DbcIterator &iter,
return ss.str();
}
// Pack for controller
// Pack for control
static std::string GeneratePack(DbcIterator &iter,
const rapidjson::Document &doc,
int indent_level = 0)
@ -276,7 +276,7 @@ static std::string GeneratePack(DbcIterator &iter,
const std::string indent1 = ad::dbcc::GenerateIndent(indent_level + 1);
ss << indent
<< "int CanDataOperation::pack(const ControlCommand "
"*controller, CanFrame *frame)"
"*control, CanFrame *frame)"
<< std::endl
<< indent << "{" << std::endl
<< indent1 << "switch (frame->id)" << std::endl
@ -288,15 +288,15 @@ static std::string GeneratePack(DbcIterator &iter,
for (auto sig : msg)
{
if (!doc["controller"].HasMember(sig.Name().c_str()))
if (!doc["control"].HasMember(sig.Name().c_str()))
{
continue;
}
else
{
std::string controller_signal_name = std::string(
doc["controller"][sig.Name().c_str()].GetString());
sigs.push_back(std::make_pair(controller_signal_name, sig));
std::string control_signal_name = std::string(
doc["control"][sig.Name().c_str()].GetString());
sigs.push_back(std::make_pair(control_signal_name, sig));
}
}
@ -441,17 +441,17 @@ static std::string GenerateHDecl(DbcIterator &iter,
for (auto &sig : msg)
{
if (!doc["controller"].HasMember(sig.Name().c_str()))
if (!doc["control"].HasMember(sig.Name().c_str()))
{
continue;
}
else
{
std::string controller_signal_name = std::string(
doc["controller"][sig.Name().c_str()].GetString());
std::string control_signal_name = std::string(
doc["control"][sig.Name().c_str()].GetString());
ad::dbcc::helper::SignalHelper sig_helper(sig);
ss << kDefaultIndentSpaces << sig_helper.TypeName() << " "
<< controller_signal_name << ";" << std::endl;
<< control_signal_name << ";" << std::endl;
}
}
}
@ -462,7 +462,7 @@ static std::string GenerateHDecl(DbcIterator &iter,
"\n"
"int CanDataOperation_Unpack(const CanFrame *frame, Feedback "
"*feedback);\n"
"int CanDataOperation_Pack(const ControlCommand *controller, "
"int CanDataOperation_Pack(const ControlCommand *control, "
"CanFrame *frame);\n"
"\n");

View File

@ -30,7 +30,7 @@ static std::string SignalUnpack2Code(NameSignalPair &sig, int indent_level)
}
ss << indent << sig_helper.OperationTypeName() << " " << signal_member_name
<< "Temp = 0;" << std::endl;
<< "_temp = 0;" << std::endl;
for (auto seg : sig_helper.Segments(true))
{
@ -39,11 +39,11 @@ static std::string SignalUnpack2Code(NameSignalPair &sig, int indent_level)
if (seg.direction ==
ad::dbcc::helper::SignalHelper::ShiftDirection::kLeft)
{
ss << signal_member_name << "Temp |= UNPACK_LEFT_SHIFT(";
ss << signal_member_name << "_temp |= UNPACK_LEFT_SHIFT(";
}
else
{
ss << signal_member_name << "Temp |= UNPACK_RIGHT_SHIFT(";
ss << signal_member_name << "_temp |= UNPACK_RIGHT_SHIFT(";
}
ss << sig_helper.OperationTypeName() << ", "
@ -67,18 +67,18 @@ static std::string SignalUnpack2Code(NameSignalPair &sig, int indent_level)
mask <<= sig.second.Length();
ss << indent << "if ((" << signal_member_name << "Temp & (1"
ss << indent << "if ((" << signal_member_name << "_temp & (1"
<< conversion_type_suffix << " << " << (sig.second.Length() - 1)
<< ")) != 0" << conversion_type_suffix << ")" << std::endl
<< indent << "{" << std::endl
<< indent2 << signal_member_name << "Temp |= 0x" << std::hex
<< indent2 << signal_member_name << "_temp |= 0x" << std::hex
<< mask << std::dec << conversion_type_suffix << ";" << std::endl
<< indent << "}" << std::endl;
}
}
ss << indent << "feedback." << signal_member_name << " = ("
<< signal_member_type << ")(" << signal_member_name << "Temp * "
<< signal_member_type << ")(" << signal_member_name << "_temp * "
<< sig.second.Factor() << " + (" << sig.second.Offset() << ")"
<< ");";
return ss.str();
@ -91,7 +91,7 @@ static std::string SignalPack2Code(NameSignalPair &sig, int indent_level)
bool need_new_line = false;
const std::string indent = ad::dbcc::GenerateIndent(indent_level);
ss << indent << sig_helper.OperationTypeName() << " " << sig.first
<< "Temp = (" << sig_helper.OperationTypeName() << ")((controller."
<< "_temp = (" << sig_helper.OperationTypeName() << ")((control."
<< sig.first << " - (" << sig.second.Offset() << ")) / "
<< sig.second.Factor() << ");" << std::endl;
@ -116,7 +116,7 @@ static std::string SignalPack2Code(NameSignalPair &sig, int indent_level)
<< " |= PACK_RIGHT_SHIFT(";
}
ss << sig.first << "Temp, " << seg.shift << "u, " << std::setw(2)
ss << sig.first << "_temp, " << seg.shift << "u, " << std::setw(2)
<< std::setfill('0') << "0x" << std::hex << seg.mask << std::dec
<< "u);" << std::setw(0) << std::setfill(' ');
need_new_line = true;
@ -263,7 +263,7 @@ static std::string GenerateUnpack(DbcIterator &iter,
return ss.str();
}
// Pack for controller
// Pack for control
static std::string GeneratePack(DbcIterator &iter,
const rapidjson::Document &doc,
int indent_level = 0)
@ -275,7 +275,7 @@ static std::string GeneratePack(DbcIterator &iter,
const std::string indent1 = ad::dbcc::GenerateIndent(indent_level + 1);
ss << indent
<< "bool CanDataOperation::pack(const ad::canbus::ControlCommand "
"&controller, ad::canbus::CanFrame &frame)"
"&control, ad::canbus::CanFrame &frame)"
<< std::endl
<< indent << "{" << std::endl
<< indent1 << "switch (frame.id)" << std::endl
@ -287,15 +287,15 @@ static std::string GeneratePack(DbcIterator &iter,
for (auto sig : msg)
{
if (!doc["controller"].HasMember(sig.Name().c_str()))
if (!doc["control"].HasMember(sig.Name().c_str()))
{
continue;
}
else
{
std::string controller_signal_name = std::string(
doc["controller"][sig.Name().c_str()].GetString());
sigs.push_back(std::make_pair(controller_signal_name, sig));
std::string control_signal_name = std::string(
doc["control"][sig.Name().c_str()].GetString());
sigs.push_back(std::make_pair(control_signal_name, sig));
}
}
@ -440,17 +440,17 @@ static std::string GenerateHDecl(DbcIterator &iter,
for (auto &sig : msg)
{
if (!doc["controller"].HasMember(sig.Name().c_str()))
if (!doc["control"].HasMember(sig.Name().c_str()))
{
continue;
}
else
{
std::string controller_signal_name = std::string(
doc["controller"][sig.Name().c_str()].GetString());
std::string control_signal_name = std::string(
doc["control"][sig.Name().c_str()].GetString());
ad::dbcc::helper::SignalHelper sig_helper(sig);
ss << kDefaultIndentSpaces << sig_helper.TypeName() << " "
<< controller_signal_name << ";" << std::endl;
<< control_signal_name << ";" << std::endl;
}
}
}
@ -462,7 +462,7 @@ static std::string GenerateHDecl(DbcIterator &iter,
"{\n"
" static bool Unpack(const ad::canbus::CanFrame &frame, "
"ad::canbus::Feedback &feedback);\n"
" static bool Pack(const ad::canbus::ControlCommand &controller, "
" static bool Pack(const ad::canbus::ControlCommand &control, "
"ad::canbus::CanFrame &frame);\n"
"};\n");

View File

@ -28,7 +28,7 @@ bool Generator::Generate(const std::string &path, Language lang)
bool need_filter = false;
rapidjson::Document doc;
// Load json configuration if existent.
const std::vector<std::string> kRequiredKeys{"controller", "feedback"};
const std::vector<std::string> kRequiredKeys{"control", "feedback"};
if (!config_file_.empty())
{

View File

@ -1,6 +1,8 @@
cmake_minimum_required (VERSION 3.15)
project (parser)
set (ADMAKE_DISABLE_ADDRESS_SANITIZER ON)
include (CMakeListsPub)
set (TARGET_NAME ${CMAKE_PROJECT_NAME})

View File

@ -2,19 +2,22 @@
#include <string> /**< std::string */
#include "dbcc/dbc_iterator.h"
#include "dbcc/helper/gen_helper.h"
const std::string usage = "This parser is meant to be used via CLi at the moment\n"
"\t./parser <FILE>\n";
"\t./parser <FILE> <CONFIG FILE>\n";
int main(int argc, char *argv[])
{
if (argc < 2)
if (argc < 3)
{
std::cout << usage << std::endl;
return 0;
}
ad::dbcc::DbcIterator iter(argv[1]);
std::cout << iter << std::endl;
ad::dbcc::helper::GenHelper gen(argv[1], argv[2]);
std::cout << gen.GenAll() << std::endl;
return 0;
}