mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-04-18 10:38:16 +00:00
40
sdv_executables/sdv_vss_util/CMakeLists.txt
Normal file
40
sdv_executables/sdv_vss_util/CMakeLists.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
# Define project
|
||||
project (sdv_vss_util VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Add include directories
|
||||
include_directories(../export)
|
||||
|
||||
# Define the executable
|
||||
add_executable(sdv_vss_util
|
||||
main.cpp
|
||||
csv_file_reader.h
|
||||
csv_file_reader.cpp
|
||||
vss_vd_generator.h
|
||||
vss_vd_generator.cpp
|
||||
vss_bs_generator.h
|
||||
vss_bs_generator.cpp
|
||||
vss_helper.cpp
|
||||
vss_helper.h
|
||||
vss_coding.cpp
|
||||
vss_coding.h
|
||||
vss_vd_codingrx.cpp
|
||||
vss_vd_codingrx.h
|
||||
vss_bs_codingrx.cpp
|
||||
vss_bs_codingrx.h
|
||||
vss_vd_codingtx.cpp
|
||||
vss_vd_codingtx.h
|
||||
vss_bs_codingtx.cpp
|
||||
vss_bs_codingtx.h
|
||||
codegen_base.cpp)
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(sdv_vss_util ${CMAKE_DL_LIBS} Rpcrt4.lib)
|
||||
else()
|
||||
target_link_libraries(sdv_vss_util ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
# Build dependencies
|
||||
add_dependencies(sdv_vss_util CompileCoreIDL)
|
||||
|
||||
# Appending the executable to the service list
|
||||
set(SDV_Executable_List ${SDV_Executable_List} sdv_vss_util PARENT_SCOPE)
|
||||
38
sdv_executables/sdv_vss_util/codegen_base.cpp
Normal file
38
sdv_executables/sdv_vss_util/codegen_base.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "codegen_base.h"
|
||||
#include <sstream>
|
||||
|
||||
std::string CCodeGeneratorBase::ReplaceKeywords(const std::string& rssStr, const CKeywordMap& rmapKeywords, char cMarker /*= '%'*/)
|
||||
{
|
||||
std::stringstream sstream;
|
||||
size_t nPos = 0;
|
||||
while (nPos < rssStr.size())
|
||||
{
|
||||
// Find the initial separator
|
||||
size_t nSeparator = rssStr.find(cMarker, nPos);
|
||||
sstream << rssStr.substr(nPos, nSeparator == std::string::npos ? nSeparator : nSeparator - nPos);
|
||||
nPos = nSeparator;
|
||||
if (nSeparator == std::string::npos) continue;
|
||||
nPos++;
|
||||
|
||||
// Find the next separator.
|
||||
nSeparator = rssStr.find(cMarker, nPos);
|
||||
if (nSeparator == std::string::npos)
|
||||
{
|
||||
// Internal error: missing second separator during code building.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the keyword in the keyword map (between the separator and the position).
|
||||
CKeywordMap::const_iterator itKeyword = rmapKeywords.find(rssStr.substr(nPos, nSeparator - nPos));
|
||||
if (itKeyword == rmapKeywords.end())
|
||||
{
|
||||
// Internal error: invalid keyword during building code.
|
||||
nPos = nSeparator + 1;
|
||||
continue;
|
||||
}
|
||||
sstream << itKeyword->second;
|
||||
nPos = nSeparator + 1;
|
||||
}
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
71
sdv_executables/sdv_vss_util/codegen_base.h
Normal file
71
sdv_executables/sdv_vss_util/codegen_base.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#ifndef CODEGEN_BASE_H
|
||||
#define CODEGEN_BASE_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cmath>
|
||||
|
||||
/**
|
||||
* @brief Code generator base class.
|
||||
*/
|
||||
class CCodeGeneratorBase
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* @brief Keyword map for keyword replacement in a string.
|
||||
*/
|
||||
typedef std::map<std::string, std::string> CKeywordMap;
|
||||
|
||||
/**
|
||||
* @brief Replace keywords in a string.
|
||||
* @param[in] rssStr Reference to the string containing the keywords.
|
||||
* @param[in] rmapKeywords Map with keywords to replace.
|
||||
* @param[in] cMarker Character to identify the keyword with (placed before and after the keyword; e.g. %keyword%).
|
||||
* @return Returns the string with replacements.
|
||||
*/
|
||||
static std::string ReplaceKeywords(const std::string& rssStr, const CKeywordMap& rmapKeywords, char cMarker = '%');
|
||||
|
||||
/**
|
||||
* @brief Generator specific string generator. The std::to_string doesn't handle floating points very well.
|
||||
* @tparam T Type of the variable to stringetize.
|
||||
* @param[in] rtVar Reference to the variable.
|
||||
* @return The generated string object.
|
||||
*/
|
||||
template <typename T>
|
||||
static std::string to_string(const T& rtVar)
|
||||
{
|
||||
std::ostringstream sstream;
|
||||
sstream << rtVar;
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Overloading for double.
|
||||
* @param[in] rdVar Reference to the double variable.
|
||||
* @return The generated string object.
|
||||
*/
|
||||
static std::string to_string(const double& rdVar)
|
||||
{
|
||||
std::ostringstream sstream;
|
||||
sstream << rdVar;
|
||||
if (std::round(rdVar) == rdVar) sstream << ".0";
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Overloading for float.
|
||||
* @param[in] rfVar Reference to the float variable.
|
||||
* @return The generated string object.
|
||||
*/
|
||||
static std::string to_string(const float& rfVar)
|
||||
{
|
||||
std::ostringstream sstream;
|
||||
sstream << rfVar;
|
||||
if (std::round(rfVar) == rfVar) sstream << ".0";
|
||||
sstream << "f";
|
||||
return sstream.str();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined CODEGEN_BASE_H
|
||||
275
sdv_executables/sdv_vss_util/csv_file_reader.cpp
Normal file
275
sdv_executables/sdv_vss_util/csv_file_reader.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
#include "csv_file_reader.h"
|
||||
|
||||
CCSVFileReader::CCSVFileReader(const std::string& ssFileName, const bool bSilent, const bool bVerbose)
|
||||
{
|
||||
m_silent = bSilent;
|
||||
m_verbose = bVerbose;
|
||||
m_vdSignals.clear();
|
||||
m_bsSignals.clear();
|
||||
if (ssFileName.empty())
|
||||
{
|
||||
Help();
|
||||
return;
|
||||
}
|
||||
else if (!ReadCSVVSSFile(ssFileName))
|
||||
{
|
||||
std::cout << "\nError: '" << ssFileName.c_str() << "' file could not be oppened or has no vss definitions." << std::endl;
|
||||
Help();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CCSVFileReader::Help()
|
||||
{
|
||||
std::cout << std::endl;
|
||||
std::cout << "-----------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
std::cout << "Required: An excel text file in csv format, the separator should be ';'" << std::endl;
|
||||
std::cout << " [required] Cells must not contain spaces." << std::endl;
|
||||
std::cout << " [required] Column 'Device Type' must be either 'VD' or 'BS'." << std::endl;
|
||||
std::cout << " [required] Column 'vss' must contain a character '.' or can be empty." << std::endl;
|
||||
std::cout << " [required] Column signal direction, either 'RX' or 'TX' or empty." << std::endl;
|
||||
std::cout << " [required] Column signal value type must not be empty." << std::endl;
|
||||
std::cout << " [required] Column 'CAN name' must contain a character '.' (for vehicle device signal)." << std::endl;
|
||||
std::cout << " [required] Last column: in case of vehicle device it is 'CAN name'." << std::endl;
|
||||
std::cout << " [required] Last column: in case of basic service it is avss from vehicle device." << std::endl;
|
||||
std::cout << " [recommended] Cells may be empty. In that case either a default string is created or previous entry is used." << std::endl;
|
||||
std::cout << " [recommended] Column Class name should start with uppercase character." << std::endl;
|
||||
std::cout << " [recommended] Column Function name should start with uppercase character." << std::endl;
|
||||
std::cout << " [recommended] Column Signal name should start with lowercase character." << std::endl;
|
||||
std::cout << "Summary can be found in file 'summary.txt'." << std::endl;
|
||||
std::cout << "Columns:" << std::endl;
|
||||
std::cout << "Device Type ';' Class name ';' Function name ';' Signal name ';' Interface (vss) ';' Direction ';' Signal value type ';' 'CAN name' or Interface(vss)" << std::endl;
|
||||
std::cout << std::endl;
|
||||
std::cout << "e.g." << std::endl;
|
||||
std::cout << "VD ';' FrontWheel ';' SetAverageAngle ';' averageAngle ';' Vehicle.Chassis.Axle.Row.Wheel.AverageAngle ';' RX ';' float ';' CANMsg.Angle" << std::endl;
|
||||
std::cout << "BS ';' VehicleChassisAxle ';' SetAngleStatus ';' angleStatus ';' Vehicle.Chassis.Axle.Row.Wheel ';' TX ';' uint8_t ';' Vehicle.Chassis.Axle.Row.Wheel" << std::endl;
|
||||
std::cout << "-----------------------------------------------------------------------------------------------------------" << std::endl;
|
||||
}
|
||||
|
||||
bool CCSVFileReader::ReadCSVVSSFile(const std::string& ssFileName)
|
||||
{
|
||||
std::ifstream file(ssFileName);
|
||||
if (!file.is_open())
|
||||
{
|
||||
std::cerr << "'" << ssFileName << "' could not be opened." << std::endl;
|
||||
return false;
|
||||
}
|
||||
std::string line;
|
||||
uint32_t index = 1;
|
||||
while (std::getline(file, line))
|
||||
{
|
||||
line.erase(std::remove(line.begin(), line.end(), '\r'), line.end());
|
||||
ReadLine(line, index++, vssVDColumns::column_end);
|
||||
}
|
||||
file.close();
|
||||
|
||||
if ((m_vdSignals.size() == 0) && (m_bsSignals.size() == 0))
|
||||
{
|
||||
if (!m_silent)
|
||||
{
|
||||
std::cout << "No valid signal definitions found." << std::endl;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCSVFileReader::ReadLine(const std::string& ssLine, const uint32_t index, size_t endColumn)
|
||||
{
|
||||
std::stringstream ss(ssLine);
|
||||
std::string item;
|
||||
std::vector<std::string> parts;
|
||||
while (std::getline(ss, item, ';'))
|
||||
{
|
||||
item = Trim(item);
|
||||
auto cType = GetCTypeFromIDLType(item); // maybe its a IDL type
|
||||
if (MustNotContainSpaces(item) || (cType.size() != 0))
|
||||
{
|
||||
parts.push_back(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((m_vdSignals.size() != 0) && (m_bsSignals.size() && !m_silent))
|
||||
{
|
||||
std::cout << "Invalid, contains spaces: '" << item << "'" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parts.size() >= endColumn)
|
||||
{
|
||||
ParseColumns(parts, index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCSVFileReader::ParseColumns(const std::vector<std::string>& parts, const uint32_t index)
|
||||
{
|
||||
static std::string vss = "";
|
||||
static sdv::core::ESignalDirection signalDirection = sdv::core::ESignalDirection::sigdir_rx;
|
||||
|
||||
if (parts.size() >= vssVDColumns::column_end)
|
||||
{
|
||||
if (parts[vssVDColumns::column_vssDefinition].size() != 0) // if vss is empty use previous one
|
||||
{
|
||||
vss = parts[vssVDColumns::column_vssDefinition];
|
||||
}
|
||||
if (!MustContainDotOrIsEmpty(vss, false)) // vss can be empty
|
||||
{
|
||||
if ((m_vdSignals.size() != 0) && (m_bsSignals.size() && !m_silent))
|
||||
{
|
||||
std::cout << "Invalid, contains no charatcer '.': '" << vss << "', line number " << std::to_string(index)<< std::endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
vss = ValidateVSSFormatNumbers(vss);
|
||||
|
||||
if (!parts[vssVDColumns::column_direction].compare("RX"))
|
||||
signalDirection = sdv::core::ESignalDirection::sigdir_rx;
|
||||
if (!parts[vssVDColumns::column_direction].compare("TX"))
|
||||
signalDirection = sdv::core::ESignalDirection::sigdir_tx;
|
||||
|
||||
if (!parts[vssVDColumns::column_type].compare("VD"))
|
||||
{
|
||||
if (AddToExistingVDSignal(m_vdSignals, vss, signalDirection, parts, index))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SSignalVDDefinition signal;
|
||||
signal.vssDefinition = vss;
|
||||
signal.signalDirection = signalDirection;
|
||||
signal.className = GenerateDefaultIfEmpty(parts[vssVDColumns::column_className], "ClassName", index);
|
||||
|
||||
if (AddFunctionVDDefinition(signal, parts[vssVDColumns::column_functionName], parts[vssVDColumns::column_signalName],
|
||||
parts[vssVDColumns::column_canSignalName], parts[vssVDColumns::column_signalCType], index))
|
||||
{
|
||||
ValidateVDCodeStyle(signal, m_verbose);
|
||||
m_vdSignals.push_back(signal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AddToExistingBSSignal(m_bsSignals, vss, signalDirection, parts, index))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::string vssOfVehicleDevice = parts[vssVDColumns::column_vdDefinition];
|
||||
vssOfVehicleDevice = ValidateVSSFormatNumbers(vssOfVehicleDevice);
|
||||
|
||||
SSignalBSDefinition signal;
|
||||
signal.vssDefinition = vss;
|
||||
signal.signalDirection = signalDirection;
|
||||
signal.className = GenerateDefaultIfEmpty(parts[vssVDColumns::column_className], "ClassName", index);
|
||||
signal.vssVDDefinition = vssOfVehicleDevice;
|
||||
if (AddFunctionBSDefinition(signal, parts[vssVDColumns::column_functionName], parts[vssVDColumns::column_signalName],
|
||||
parts[vssVDColumns::column_canSignalName], parts[vssVDColumns::column_signalCType], index))
|
||||
{
|
||||
ValidateBSCodeStyle(signal, m_verbose);
|
||||
m_bsSignals.push_back(signal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CCSVFileReader::AddToExistingVDSignal(std::vector <SSignalVDDefinition>& signals, const std::string& vssDefinition,
|
||||
const sdv::core::ESignalDirection& directionX, const std::vector<std::string>& parts, const uint32_t index)
|
||||
{
|
||||
for (auto& signal : signals)
|
||||
{
|
||||
if ((signal.vssDefinition.compare(vssDefinition) == 0) && (signal.signalDirection == directionX))
|
||||
{
|
||||
if ((signal.className != parts[vssVDColumns::column_className]) && !m_silent)
|
||||
{
|
||||
std::cout << "Signal already found, ignore class name '" << parts[vssVDColumns::column_className] << "', line number " << std::to_string(index) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
AddFunctionVDDefinition(signal, parts[vssVDColumns::column_functionName], parts[vssVDColumns::column_signalName],
|
||||
parts[vssVDColumns::column_canSignalName], parts[vssVDColumns::column_signalCType], index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCSVFileReader::AddToExistingBSSignal(std::vector <SSignalBSDefinition>& signals, const std::string& vssDefinition,
|
||||
const sdv::core::ESignalDirection& directionX, const std::vector<std::string>& parts, const uint32_t index)
|
||||
{
|
||||
for (auto& signal : signals)
|
||||
{
|
||||
if ((signal.vssDefinition.compare(vssDefinition) == 0) && (signal.signalDirection == directionX))
|
||||
{
|
||||
if ((signal.className != parts[vssVDColumns::column_className]) && !m_silent)
|
||||
{
|
||||
std::cout << "Signal already found, ignore class name '" << parts[vssVDColumns::column_className] << "', line number " << std::to_string(index) << std::endl;
|
||||
}
|
||||
|
||||
AddFunctionBSDefinition(signal, parts[vssVDColumns::column_functionName], parts[vssVDColumns::column_signalName],
|
||||
parts[vssVDColumns::column_vdDefinition], parts[vssVDColumns::column_signalCType], index);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCSVFileReader::AddFunctionVDDefinition(SSignalVDDefinition& signal, const std::string& functionName, const std::string& signalName,
|
||||
const std::string& canSignalName, const std::string& idlType, const uint32_t index)
|
||||
{
|
||||
if (!MustContainDotOrIsEmpty(canSignalName, true)) // can signal must must not be empty
|
||||
{
|
||||
if ((m_vdSignals.size() != 0) && (m_bsSignals.size() && !m_silent))
|
||||
{
|
||||
std::cout << "Invalid, contains no charatcer '.' or is empty: '" << canSignalName << "', line number " << std::to_string(index) << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto cType = GetCTypeFromIDLType(idlType);
|
||||
if ((cType.size() == 0) && !m_silent)
|
||||
{
|
||||
std::cout << "Invalid, idl type unknown: '" << idlType << "', line number " << std::to_string(index) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
SFunctionVDDefinition func;
|
||||
func.functionName = GenerateDefaultIfEmpty(functionName, "FunctionName", index);
|
||||
func.signalName = GenerateDefaultIfEmpty(signalName, "variableName", index);
|
||||
func.canSignalName = canSignalName;
|
||||
func.idlType = idlType;
|
||||
|
||||
ValidateVDCodeStyle(func, m_verbose);
|
||||
signal.vecFunctions.push_back(func);
|
||||
|
||||
return true;
|
||||
}
|
||||
bool CCSVFileReader::AddFunctionBSDefinition(SSignalBSDefinition& signal, const std::string& functionName, const std::string& signalName,
|
||||
const std::string& canSignalName, const std::string& idlType, const uint32_t index)
|
||||
{
|
||||
if (!MustContainDotOrIsEmpty(canSignalName, true)) // can signal must must not be empty
|
||||
{
|
||||
if ((m_vdSignals.size() != 0) && (m_bsSignals.size() && !m_silent))
|
||||
{
|
||||
std::cout << "Invalid, contains no charatcer '.' or is empty: '" << canSignalName << "', line number " << std::to_string(index) << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto cType = GetCTypeFromIDLType(idlType);
|
||||
if ((cType.size() == 0) && !m_silent)
|
||||
{
|
||||
std::cout << "Invalid, idl type unknown: '" << idlType << "', line number " << std::to_string(index) << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
SFunctionBSDefinition func;
|
||||
func.functionName = GenerateDefaultIfEmpty(functionName, "FunctionName", index);
|
||||
func.signalName = GenerateDefaultIfEmpty(signalName, "variableName", index);
|
||||
func.idlType = idlType;
|
||||
|
||||
ValidateBSCodeStyle(func, m_verbose);
|
||||
signal.vecFunctions.push_back(func);
|
||||
|
||||
return true;
|
||||
}
|
||||
145
sdv_executables/sdv_vss_util/csv_file_reader.h
Normal file
145
sdv_executables/sdv_vss_util/csv_file_reader.h
Normal file
@@ -0,0 +1,145 @@
|
||||
#ifndef CSV_FILE_READER_H
|
||||
#define CSV_FILE_READER_H
|
||||
|
||||
#include <fstream>
|
||||
#include "vss_helper.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reads the cvs file and parses the signal definitions.
|
||||
*/
|
||||
class CCSVFileReader : public CVSSHelper
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] ssFileName Reference to the cvs file which contains the VSS definition
|
||||
* @param[in] bSilent if true no console output on errors & warnings
|
||||
* @param[in] bVerbose if true validates names and print out warnings in case of code style is not matched
|
||||
*/
|
||||
CCSVFileReader(const std::string& ssFileName, const bool bSilent, const bool bVerbose);
|
||||
|
||||
/**
|
||||
* @brief Get signal definitions for vehicle devices
|
||||
* @return Returns a reference to the variable containing the list of signals;
|
||||
*/
|
||||
const std::vector<SSignalVDDefinition>& GetVDSignals() const
|
||||
{
|
||||
return m_vdSignals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get signal definitions for basic services
|
||||
* @return Returns a reference to the variable containing the list of signals;
|
||||
*/
|
||||
const std::vector<SSignalBSDefinition>& GetBSSignals() const
|
||||
{
|
||||
return m_bsSignals;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Type definitions for the columns in the vehicle device sheets
|
||||
*/
|
||||
typedef enum vssVDColumns
|
||||
{
|
||||
column_type,
|
||||
column_className,
|
||||
column_functionName,
|
||||
column_signalName,
|
||||
column_vssDefinition,
|
||||
column_direction,
|
||||
column_signalCType,
|
||||
column_canSignalName,
|
||||
column_vdDefinition = column_canSignalName,
|
||||
column_end
|
||||
} vssVDColumns;
|
||||
|
||||
|
||||
/**
|
||||
* @brief prints help to the console
|
||||
*/
|
||||
void Help();
|
||||
|
||||
/**
|
||||
* @brief read a csv excel file with ';' separator
|
||||
* @param[in] ssFileName name of the cvs file to be read
|
||||
* @return True if signals definitions could be read and are valid, otherwise false;
|
||||
*/
|
||||
bool ReadCSVVSSFile(const std::string& ssFileName);
|
||||
|
||||
/**
|
||||
* @brief read and interprets a signal line of a cvs file
|
||||
* @param[in] ssLine content of a complete line
|
||||
* @param[in] index line number, may be used for default values
|
||||
* @param[in] endColumn the maximum of columns
|
||||
*/
|
||||
void ReadLine(const std::string& ssLine, const uint32_t index, size_t endColumn);
|
||||
|
||||
/**
|
||||
* @brief If a signal definition is found in the list for the vehicle devices add the function/signal to this definition
|
||||
* @param[in] signals collection of vehicle device signals
|
||||
* @param[in] vssDefinition definition to look for
|
||||
* @param[in] direction signal direction, either rx or tx
|
||||
* @param[in] parts Reference to the list of parts of a single line of the cvs file
|
||||
* @param[in] index line number
|
||||
* @return True if signal was found, otherwise false
|
||||
*/
|
||||
bool AddToExistingVDSignal(std::vector <SSignalVDDefinition>& signals, const std::string& vssDefinition,
|
||||
const sdv::core::ESignalDirection& direction, const std::vector<std::string>& parts, const uint32_t index);
|
||||
|
||||
/**
|
||||
* @brief If a signal definition is found in the list for the basic services add the function/signal to this definition
|
||||
* @param[in] signals collection of basic service signals
|
||||
* @param[in] vssDefinition definition to look for
|
||||
* @param[in] direction signal direction, either rx or tx
|
||||
* @param[in] parts Reference to the list of parts of a single line of the cvs file
|
||||
* @param[in] index line number
|
||||
* @return True if signal was found, otherwise false
|
||||
*/
|
||||
bool AddToExistingBSSignal(std::vector <SSignalBSDefinition>& signals, const std::string& vssDefinition,
|
||||
const sdv::core::ESignalDirection& direction, const std::vector<std::string>& parts, const uint32_t index);
|
||||
|
||||
/**
|
||||
* @brief parse the parts of a line of the vehicle device sheet to get the signal definitions
|
||||
* @param[in] parts Reference to the list of parts of a single line of the cvs file
|
||||
* @param[in] index line number
|
||||
*/
|
||||
void ParseColumns(const std::vector<std::string>& parts, const uint32_t index);
|
||||
|
||||
/**
|
||||
* @brief add function definition to the container of an existing signal (vehicle device)
|
||||
* @param[in] signal the function definition should be added
|
||||
* @param[in] functionName functione name
|
||||
* @param[in] signalName signal name
|
||||
* @param[in] canSignalName can signal name
|
||||
* @param[in] idlType idl type
|
||||
* @param[in] index line number
|
||||
* @return True if function definition was added, otherwise false
|
||||
*/
|
||||
bool AddFunctionVDDefinition(SSignalVDDefinition& signal, const std::string& functionName,
|
||||
const std::string& signalName, const std::string& canSignalName, const std::string& idlType, const uint32_t index);
|
||||
|
||||
/**
|
||||
* @brief add function definition to the container of an existing signal (basic service)
|
||||
* @param[in] signal the function definition should be added
|
||||
* @param[in] functionName functione name
|
||||
* @param[in] signalName signal name
|
||||
* @param[in] canSignalName can signal name
|
||||
* @param[in] idlType idl type
|
||||
* @param[in] index line number
|
||||
* @return True if function definition was added, otherwise false
|
||||
*/
|
||||
bool AddFunctionBSDefinition(SSignalBSDefinition& signal, const std::string& functionName,
|
||||
const std::string& signalName, const std::string& canSignalName, const std::string& idlType, const uint32_t index);
|
||||
|
||||
std::vector <SSignalVDDefinition> m_vdSignals; ///< all signals for vehicle devices
|
||||
std::vector <SSignalBSDefinition> m_bsSignals; ///< all signals for basic services
|
||||
|
||||
bool m_verbose = false;
|
||||
bool m_silent = false;
|
||||
};
|
||||
|
||||
#endif // !defined CSV_FILE_READER_H
|
||||
135
sdv_executables/sdv_vss_util/main.cpp
Normal file
135
sdv_executables/sdv_vss_util/main.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "../../global/process_watchdog.h"
|
||||
#include "../../global/cmdlnparser/cmdlnparser.cpp"
|
||||
#include "../../global/dbcparser/dbcparser.cpp"
|
||||
#include "../../global/localmemmgr.h"
|
||||
#include "../error_msg.h"
|
||||
#include <interfaces/core.h>
|
||||
#include <interfaces/mem.h>
|
||||
|
||||
#include "csv_file_reader.h"
|
||||
#include "vss_vd_generator.h"
|
||||
#include "vss_bs_generator.h"
|
||||
#include "vss_helper.h"
|
||||
|
||||
void makeSignalNamesUnique(std::vector< CVSSHelper::SSignalVDDefinition>& vdSignals)
|
||||
{
|
||||
std::unordered_map<std::string, int> nameCount;
|
||||
std::vector<std::string> allUniqueNames;
|
||||
|
||||
auto process = [&](std::vector< CVSSHelper::SSignalVDDefinition>& signals)
|
||||
{
|
||||
for (auto& signal : signals)
|
||||
{
|
||||
for (auto& func : signal.vecFunctions)
|
||||
{
|
||||
std::string& name = func.signalName;
|
||||
std::string originalName = name;
|
||||
while (nameCount[name] > 0)
|
||||
{
|
||||
name = originalName + "_" + std::to_string(nameCount[originalName]);
|
||||
nameCount[originalName]++;
|
||||
}
|
||||
nameCount[name]++;
|
||||
allUniqueNames.push_back(name);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
process(vdSignals);
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && defined(_UNICODE)
|
||||
extern "C" int wmain(int iArgc, const wchar_t* rgszArgv[])
|
||||
#else
|
||||
extern "C" int main(int iArgc, const char* rgszArgv[])
|
||||
#endif
|
||||
{
|
||||
// Workaround for GCC to make certain that POSIX thread library is loaded before the components are loaded.
|
||||
// REASON: If the first call to a thread is done in a dynamic library, the application is already classified as single
|
||||
// threaded and a termination is initiated.
|
||||
// See: https://stackoverflow.com/questions/51209268/using-stdthread-in-a-library-loaded-with-dlopen-levds-to-a-sigsev
|
||||
// NOTE EVE 27.05.2025: This task has been taken over by the process watchdog.
|
||||
CProcessWatchdog watchdog;
|
||||
|
||||
// Suppress the warning supplied by ccpcheck about an unsused variable. The memory manager registers itself into the system and
|
||||
// needs to stay in scope.
|
||||
// cppcheck-suppress unusedVariable
|
||||
CLocalMemMgr memmgr;
|
||||
|
||||
CCommandLine cmdln(static_cast<uint32_t>(CCommandLine::EParseFlags::no_assignment_character));
|
||||
bool bHelp = false;
|
||||
bool bError = false;
|
||||
bool bSilent = false;
|
||||
bool bVerbose = false;
|
||||
bool bEnableComponents = false;
|
||||
std::string ssVersion;
|
||||
std::string ssPrefix;
|
||||
std::string ssVSSFileName;
|
||||
std::filesystem::path pathOutputDir;
|
||||
try
|
||||
{
|
||||
auto& rArgHelpDef = cmdln.DefineOption("?", bHelp, "Show help");
|
||||
rArgHelpDef.AddSubOptionName("help");
|
||||
auto& rArgSilentDef = cmdln.DefineOption("s", bSilent, "Do not show any information on STDOUT. Not compatible with 'verbose'.");
|
||||
rArgSilentDef.AddSubOptionName("silent");
|
||||
auto& rArgVerboseDef = cmdln.DefineOption("v", bVerbose, "Provide verbose information. Not compatible with 'silent'.");
|
||||
rArgVerboseDef.AddSubOptionName("verbose");
|
||||
cmdln.DefineSubOption("prefix", ssPrefix, "prefix, used by cmake library and signal definition in signal_identifier.h file.");
|
||||
cmdln.DefineSubOption("enable_components", bEnableComponents, "Creates additionally to the idl files the code for the components.");
|
||||
cmdln.DefineSubOption("version", ssVersion, "Optional: version information of the dbc file.");
|
||||
cmdln.DefineOption("O", pathOutputDir, "Set output directory (required).");
|
||||
cmdln.DefineDefaultArgument(ssVSSFileName, "Excel file.");
|
||||
cmdln.Parse(static_cast<size_t>(iArgc), rgszArgv);
|
||||
} catch (const SArgumentParseException& rsExcept)
|
||||
{
|
||||
std::cout << "ERROR: " << rsExcept.what() << std::endl;
|
||||
bHelp = true;
|
||||
bError = true;
|
||||
}
|
||||
if (bSilent)
|
||||
{
|
||||
bVerbose = false;
|
||||
}
|
||||
if (!bSilent)
|
||||
{
|
||||
std::cout << "abtract device / basic services utility" << std::endl;
|
||||
std::cout << "Copyright (C): 2022-2025 ZF Friedrichshafen AG" << std::endl;
|
||||
std::cout << "Author: Thomas Pfleiderer" << std::endl;
|
||||
}
|
||||
|
||||
if (bHelp || (ssVSSFileName.empty() || pathOutputDir.empty() || ssPrefix.empty()))
|
||||
{
|
||||
if (!bSilent)
|
||||
{
|
||||
cmdln.PrintHelp(std::cout);
|
||||
//CCSVFileReader csv("", bSilent, bVerbose);
|
||||
}
|
||||
return bError ? CMDLN_ARG_ERR : NO_ERROR;
|
||||
}
|
||||
|
||||
CCSVFileReader csv(ssVSSFileName, bSilent, bVerbose);
|
||||
auto vdSignals = csv.GetVDSignals();
|
||||
auto bsSignals = csv.GetBSSignals();
|
||||
if (!CVSSHelper::VehicleDeviceVSSDefinitionExists(bSilent, vdSignals, bsSignals))
|
||||
{
|
||||
return BASIC_SERVICE_DATA_ERROR;
|
||||
}
|
||||
|
||||
if (vdSignals.size() > 0)
|
||||
{
|
||||
makeSignalNamesUnique(vdSignals);
|
||||
CVSSVDGenerator vssVD(vdSignals, pathOutputDir, ssPrefix, ssVersion, bEnableComponents);
|
||||
vssVD.GeneratedCode();
|
||||
|
||||
if (bsSignals.size() > 0)
|
||||
{
|
||||
CVSSBSGenerator vssBS(bsSignals, vdSignals, pathOutputDir, ssPrefix, ssVersion, bEnableComponents);
|
||||
vssBS.GeneratedCode();
|
||||
}
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
438
sdv_executables/sdv_vss_util/vss_bs_codingrx.cpp
Normal file
438
sdv_executables/sdv_vss_util/vss_bs_codingrx.cpp
Normal file
@@ -0,0 +1,438 @@
|
||||
#include "vss_bs_codingrx.h"
|
||||
|
||||
void CVSSBSCodingRX::GetKeyWordMap(const SSignalBSDefinition& signal, const SSignalVDDefinition& signalVD, CKeywordMap& mapKeywords) const
|
||||
{
|
||||
std::string vd_vssWithColons = ReplaceCharacters(signal.vssVDDefinition, ".", "::");
|
||||
std::string vssWithColons = ReplaceCharacters(signal.vssDefinition, ".", "::");
|
||||
|
||||
//------------------------------------------------------- basic service header
|
||||
std::stringstream sstreamIncludesVD;
|
||||
std::string vssNoDot = ReplaceCharacters(signal.vssDefinition, ".", "");
|
||||
std::transform(vssNoDot.begin(), vssNoDot.end(), vssNoDot.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
sstreamIncludesVD << Code_BS_RXIncludes(vssNoDot);
|
||||
mapKeywords["rx_bs_includes_list"] = std::move(sstreamIncludesVD.str());
|
||||
|
||||
std::stringstream sstreamBSInterfaces;
|
||||
for (uint32_t index = 0; index < signal.vecFunctions.size(); index++)
|
||||
{
|
||||
if (index >= signalVD.vecFunctions.size())
|
||||
break;
|
||||
auto func = signal.vecFunctions[index];
|
||||
auto funcVD = signalVD.vecFunctions[index];
|
||||
sstreamBSInterfaces << Code_BS_RXInterface(func.functionName, vssWithColons,
|
||||
funcVD.functionName, vd_vssWithColons);
|
||||
}
|
||||
mapKeywords["rx_bs_interface_list"] = std::move(sstreamBSInterfaces.str());
|
||||
|
||||
std::stringstream sstreamBSInterfaceEntries;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamBSInterfaceEntries << Code_BS_RXInterfaceEntry(func.functionName, vssWithColons);
|
||||
}
|
||||
mapKeywords["rx_bs_interface_entry_list"] = std::move(sstreamBSInterfaceEntries.str());
|
||||
|
||||
std::stringstream sstreamBSRegisterEvents;
|
||||
for (uint32_t index = 0; index < signal.vecFunctions.size(); index++)
|
||||
{
|
||||
if (index >= signalVD.vecFunctions.size())
|
||||
break;
|
||||
auto func = signal.vecFunctions[index];
|
||||
auto funcVD = signalVD.vecFunctions[index];
|
||||
sstreamBSRegisterEvents << Code_BS_RXReAndUnregisterEvent(vssWithColons, func, funcVD);
|
||||
}
|
||||
mapKeywords["rx_bs_register_events_list"] = std::move(sstreamBSRegisterEvents.str());
|
||||
|
||||
std::stringstream sstreamPrivateBSHeaderPart;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamPrivateBSHeaderPart << Code_BS_RXPrivateHeaderPart(func, vssWithColons);
|
||||
}
|
||||
mapKeywords["rx_bs_private_vd_header_part"] = std::move(sstreamPrivateBSHeaderPart.str());
|
||||
|
||||
////------------------------------------------------------- basic service cpp
|
||||
std::stringstream sstreamBSConstructor;
|
||||
for (uint32_t index = 0; index < signalVD.vecFunctions.size(); index++)
|
||||
{
|
||||
if (index >= signal.vecFunctions.size())
|
||||
break;
|
||||
auto func = signal.vecFunctions[index];
|
||||
auto funcVD = signalVD.vecFunctions[index];
|
||||
sstreamBSConstructor << Code_BS_RXConstructor(signalVD, vd_vssWithColons, funcVD, func);
|
||||
}
|
||||
mapKeywords["rx_bs_constructor"] = std::move(sstreamBSConstructor.str());
|
||||
|
||||
std::stringstream sstreamBSDeConstructor;
|
||||
for (const auto& func : signalVD.vecFunctions)
|
||||
{
|
||||
sstreamBSDeConstructor << Code_BS_RXDestructor(signalVD, vd_vssWithColons, func);
|
||||
}
|
||||
mapKeywords["rx_bs_deconstructor"] = std::move(sstreamBSDeConstructor.str());
|
||||
|
||||
std::stringstream sstreamBSGetAndSetFunctions;
|
||||
for (uint32_t index = 0; index < signal.vecFunctions.size(); index++)
|
||||
{
|
||||
if (index >= signalVD.vecFunctions.size())
|
||||
break;
|
||||
auto func = signal.vecFunctions[index];
|
||||
auto funcVD = signalVD.vecFunctions[index];
|
||||
sstreamBSGetAndSetFunctions << Code_BS_RXGetAndSetFunctions(signal.className, func, funcVD);
|
||||
}
|
||||
mapKeywords["rx_bs_getandsetfunctions"] = std::move(sstreamBSGetAndSetFunctions.str());
|
||||
|
||||
std::stringstream sstreamBSRegister;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamBSRegister << Code_BS_RXRegister(signal.className, func, vssWithColons);
|
||||
}
|
||||
mapKeywords["rx_bs_register"] = std::move(sstreamBSRegister.str());
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingRX::Code_RXIDLServiceList(const std::vector<std::string>& vssParts,
|
||||
const std::vector <SFunctionBSDefinition>& vecFunctions) const
|
||||
{
|
||||
std::string vssWithColons = "";
|
||||
int8_t loop = 1;
|
||||
std::string nameSpace = "module vss\n{\n";
|
||||
for (auto it = vssParts.begin(); it != vssParts.end(); ++it)
|
||||
{
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop, ' ');
|
||||
nameSpace.append("module ");
|
||||
nameSpace.append(*it);
|
||||
if (it == vssParts.end() - 1)
|
||||
{
|
||||
nameSpace.append("Service");
|
||||
}
|
||||
nameSpace.append("\n");
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop++, ' ');
|
||||
nameSpace.append("{\n");
|
||||
vssWithColons.append("::");
|
||||
vssWithColons.append(*it);
|
||||
}
|
||||
|
||||
nameSpace.append("%interfaces%");
|
||||
loop--;
|
||||
for (size_t i = 0; i < vssParts.size() + 1; i++)
|
||||
{
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop--, ' ');
|
||||
nameSpace.append("};\n");
|
||||
}
|
||||
|
||||
std::string spaces = "";
|
||||
spaces.append(static_cast <int8_t>(4) * (vssParts.size() + 1), ' ');
|
||||
std::stringstream sstreamInterfaces;
|
||||
for (auto func : vecFunctions)
|
||||
{
|
||||
sstreamInterfaces << Code_RXIDLServiceInterface(spaces, vssWithColons, func);
|
||||
}
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["interfaces"] = std::move(sstreamInterfaces.str());
|
||||
|
||||
return ReplaceKeywords(nameSpace, mapKeywords);
|
||||
}
|
||||
|
||||
|
||||
std::string CVSSBSCodingRX::Code_BS_RXIncludes(const std::string& vssOriginalNoDot) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vss_original_no_dot"] = vssOriginalNoDot;
|
||||
|
||||
return ReplaceKeywords(R"code(#include "../vss_%vss_original_no_dot%_bs_rx.h"
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingRX::Code_RXIDLServiceInterface(const std::string& spaces, const std::string& vssWithColons,
|
||||
const SFunctionBSDefinition& function) const
|
||||
{
|
||||
auto signalStartWithUppercase = function.signalName;
|
||||
if (!signalStartWithUppercase.empty())
|
||||
{
|
||||
signalStartWithUppercase[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(signalStartWithUppercase[0])));
|
||||
}
|
||||
|
||||
std::string prefix = "Service";
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["signal_start_with_uppercase"] = signalStartWithUppercase;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["value_idltype"] = function.idlType;
|
||||
mapKeywords["value_ctype"] = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["prefix"] = prefix;
|
||||
mapKeywords["multiple_spaces"] = spaces;
|
||||
mapKeywords["vssWithColons"] = vssWithColons;
|
||||
return ReplaceKeywords(R"code(%multiple_spaces%/**
|
||||
%multiple_spaces%* @brief IVSS_Set%function_name% event interface
|
||||
%multiple_spaces%*/
|
||||
%multiple_spaces%interface IVSS_Set%function_name%_Event
|
||||
%multiple_spaces%{
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Set %signal_name% signal
|
||||
%multiple_spaces% * @param[in] value %signal_name%
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% void Set%function_name%(in %value_idltype% value);
|
||||
%multiple_spaces%};
|
||||
|
||||
%multiple_spaces%/**
|
||||
%multiple_spaces%* @brief IVSS_Get%function_name% %prefix% interface
|
||||
%multiple_spaces%*/
|
||||
%multiple_spaces%interface IVSS_Get%function_name%
|
||||
%multiple_spaces%{
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Get %signal_name% signal
|
||||
%multiple_spaces% * @return Returns the %signal_name%
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% %value_idltype% Get%function_name%() const;
|
||||
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Register Callback on signal change
|
||||
%multiple_spaces% * @param[in] callback function
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% void RegisterOnSignalChangeOf%signal_start_with_uppercase%(in vss%vssWithColons%Service::IVSS_Set%function_name%_Event callback);
|
||||
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Unregister Callback
|
||||
%multiple_spaces% * @param[in] callback function
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% void UnregisterOnSignalChangeOf%signal_start_with_uppercase%(in vss%vssWithColons%Service::IVSS_Set%function_name%_Event callback);
|
||||
%multiple_spaces%};
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingRX::Code_BS_RXInterface(const std::string& functionName, const std::string& vssWithColons,
|
||||
const std::string& vd_functionName, const std::string& vd_vssWithColons) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = functionName;
|
||||
mapKeywords["vssWithColons"] = vssWithColons;
|
||||
mapKeywords["vd_function_name"] = vd_functionName;
|
||||
mapKeywords["vd_vssWithColons"] = vd_vssWithColons;
|
||||
|
||||
return ReplaceKeywords(R"code( , public vss::%vssWithColons%Service::IVSS_Get%function_name%
|
||||
, public vss::%vssWithColons%Service::IVSS_Set%function_name%_Event
|
||||
, public vss::%vd_vssWithColons%Device::IVSS_Write%vd_function_name%_Event
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingRX::Code_BS_RXInterfaceEntry(const std::string& functionName, const std::string& vssWithColons) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = functionName;
|
||||
mapKeywords["vssWithColons"] = vssWithColons;
|
||||
|
||||
return ReplaceKeywords(R"code( SDV_INTERFACE_ENTRY(vss::%vssWithColons%Service::IVSS_Get%function_name%)
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingRX::Code_BS_RXReAndUnregisterEvent(const std::string& vssWithColons,
|
||||
const SFunctionBSDefinition& function, const SFunctionVDDefinition& functionVD) const
|
||||
{
|
||||
auto startWithUppercase = function.signalName;
|
||||
if (!startWithUppercase.empty())
|
||||
{
|
||||
startWithUppercase[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(startWithUppercase[0])));
|
||||
}
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vssWithColons"] = vssWithColons;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["vd_function_name"] = functionVD.functionName;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["start_with_uppercase"] = startWithUppercase;
|
||||
auto signalType = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["casted_value_ctype"] = CastValueType(signalType);
|
||||
mapKeywords["value_ctype"] = GetCTypeFromIDLType(function.idlType);
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
/**
|
||||
* @brief Set %signal_name% signal
|
||||
* @param[in] value %signal_name%
|
||||
*/
|
||||
void Set%function_name%(%casted_value_ctype% value) override;
|
||||
|
||||
/**
|
||||
* @brief Get %signal_name%
|
||||
* @return Returns the %signal_name%
|
||||
*/
|
||||
%value_ctype% Get%function_name%() const override;
|
||||
|
||||
/**
|
||||
* @brief Write %signal_name% signal
|
||||
* @param[in] value %signal_name%
|
||||
*/
|
||||
void Write%vd_function_name%(%casted_value_ctype% value) override;
|
||||
|
||||
/**
|
||||
* @brief Register CallBack function on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void RegisterOnSignalChangeOf%start_with_uppercase%(vss::%vssWithColons%Service::IVSS_Set%function_name%_Event* callback) override;
|
||||
|
||||
/**
|
||||
* @brief Unregister CallBack function on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void UnregisterOnSignalChangeOf%start_with_uppercase%(vss::%vssWithColons%Service::IVSS_Set%function_name%_Event* callback) override;
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingRX::Code_BS_RXPrivateHeaderPart(const SFunctionBSDefinition& function, const std::string& vssWithColons) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vssWithColons"] = vssWithColons;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["value_ctype"] = GetCTypeFromIDLType(function.idlType);
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
%value_ctype% m_%signal_name% { 0 }; ///< %signal_name% signal
|
||||
mutable std::mutex m_%signal_name%MutexCallbacks; ///< Mutex protecting m_%signal_name%Callbacks
|
||||
std::set<vss::%vssWithColons%Service::IVSS_Set%function_name%_Event*> m_%signal_name%Callbacks; ///< collection of events to be called
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingRX::Code_BS_RXConstructor(const SSignalVDDefinition& signalVD, const std::string& vd_vssWithColons,
|
||||
const SFunctionVDDefinition& functionVD, const SFunctionBSDefinition& function) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vd_vss_original"] = signalVD.vssDefinition;
|
||||
mapKeywords["vd_vssWithColons"] = vd_vssWithColons;
|
||||
mapKeywords["vd_function_name"] = functionVD.functionName;
|
||||
mapKeywords["vd_class_name"] = signalVD.className;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
auto %signal_name%Device = sdv::core::GetObject("%vd_vss_original%_Device").GetInterface<vss::%vd_vssWithColons%Device::IVSS_%vd_function_name%>();
|
||||
if (!%signal_name%Device)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_%vd_function_name%': [CBasicService%vd_class_name%]");
|
||||
throw std::runtime_error("%vd_vss_original% mode device not found");
|
||||
}
|
||||
%signal_name%Device->Register%vd_function_name%Event(dynamic_cast<vss::%vd_vssWithColons%Device::IVSS_Write%vd_function_name%_Event*> (this));
|
||||
SDV_LOG_TRACE("CBasicService%vd_class_name% created: [%vd_vss_original%_Device]");
|
||||
|
||||
m_%signal_name% = 0;
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingRX::Code_BS_RXDestructor(const SSignalVDDefinition& signalVD, const std::string& vd_vssWithColons,
|
||||
const SFunctionVDDefinition& functionVD) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vd_signal_name"] = functionVD.signalName;
|
||||
mapKeywords["vd_vss_original"] = signalVD.vssDefinition;
|
||||
mapKeywords["vd_vssWithColons"] = vd_vssWithColons;
|
||||
mapKeywords["vd_function_name"] = functionVD.functionName;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
auto %vd_signal_name%Device = sdv::core::GetObject("%vd_vss_original%_Device").GetInterface<vss::%vd_vssWithColons%Device::IVSS_%vd_function_name%>();
|
||||
if (%vd_signal_name%Device)
|
||||
{
|
||||
%vd_signal_name%Device->Unregister%vd_function_name%Event(dynamic_cast<vss::%vd_vssWithColons%Device::IVSS_Write%vd_function_name%_Event*> (this));
|
||||
}
|
||||
%vd_signal_name%Device = nullptr;
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingRX::Code_BS_RXGetAndSetFunctions(const std::string& class_name, const SFunctionBSDefinition& function,
|
||||
const SFunctionVDDefinition& functionVD) const
|
||||
{
|
||||
std::string class_name_lowercase = class_name;
|
||||
std::transform(class_name_lowercase.begin(), class_name_lowercase.end(), class_name_lowercase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["vd_function_name"] = functionVD.functionName;
|
||||
mapKeywords["class_name"] = class_name;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
auto signalType = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["casted_value_ctype"] = CastValueType(signalType);
|
||||
mapKeywords["value_ctype"] = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["class_name_lowercase"] = class_name_lowercase;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
/**
|
||||
* @brief Set %signal_name%
|
||||
* @param[in] value %signal_name%
|
||||
*/
|
||||
void CBasicService%class_name%::Set%function_name%(%casted_value_ctype% value)
|
||||
{
|
||||
m_%signal_name% = value;
|
||||
std::lock_guard<std::mutex> lock(m_%signal_name%MutexCallbacks);
|
||||
for (auto callback : m_%signal_name%Callbacks)
|
||||
{
|
||||
callback->Set%function_name%(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write %signal_name%
|
||||
* @param[in] value %signal_name%
|
||||
*/
|
||||
void CBasicService%class_name%::Write%vd_function_name%(%casted_value_ctype% value)
|
||||
{
|
||||
Set%function_name%(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get %signal_name%
|
||||
* @return Returns the %signal_name%
|
||||
*/
|
||||
%value_ctype% CBasicService%class_name%::Get%function_name%() const
|
||||
{
|
||||
return m_%signal_name%;
|
||||
}
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingRX::Code_BS_RXRegister(const std::string& class_name, const SFunctionBSDefinition& function,
|
||||
const std::string& vssWithColons) const
|
||||
{
|
||||
auto startWithUppercase = function.signalName;
|
||||
if (!startWithUppercase.empty())
|
||||
{
|
||||
startWithUppercase[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(startWithUppercase[0])));
|
||||
}
|
||||
|
||||
std::string class_name_lowercase = class_name;
|
||||
std::transform(class_name_lowercase.begin(), class_name_lowercase.end(), class_name_lowercase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["start_with_uppercase"] = startWithUppercase;
|
||||
mapKeywords["class_name"] = class_name;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["vssWithColons"] = vssWithColons;
|
||||
mapKeywords["class_name_lowercase"] = class_name_lowercase;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
/**
|
||||
* @brief Register Callback on signal change
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void CBasicService%class_name%::RegisterOnSignalChangeOf%start_with_uppercase%(vss::%vssWithColons%Service::IVSS_Set%function_name%_Event* %signal_name%Callback)
|
||||
{
|
||||
if ( %signal_name%Callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_%signal_name%MutexCallbacks);
|
||||
m_%signal_name%Callbacks.insert(%signal_name%Callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister Callback
|
||||
* @param[in] callback function
|
||||
*/
|
||||
void CBasicService%class_name%::UnregisterOnSignalChangeOf%start_with_uppercase%(vss::%vssWithColons%Service::IVSS_Set%function_name%_Event* %signal_name%Callback)
|
||||
{
|
||||
if (%signal_name%Callback)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_%signal_name%MutexCallbacks);
|
||||
m_%signal_name%Callbacks.erase(%signal_name%Callback);
|
||||
}
|
||||
}
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
142
sdv_executables/sdv_vss_util/vss_bs_codingrx.h
Normal file
142
sdv_executables/sdv_vss_util/vss_bs_codingrx.h
Normal file
@@ -0,0 +1,142 @@
|
||||
#ifndef VSS_BS_CODING_RX_H
|
||||
#define VSS_BS_CODING_RX_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <interfaces/dispatch.h>
|
||||
|
||||
#include "codegen_base.h"
|
||||
#include "vss_helper.h"
|
||||
#include "vss_rx_templates.h"
|
||||
#include "vss_coding.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief VSS code generator coding class.
|
||||
* Beside the definition of the basic service interface also information about the vehicle device is necessary
|
||||
* These 2 definitions must match, there must be a corresponding 'signalVD' definition
|
||||
* the function container of the basic service signal must match the function container if the 'signalVD'
|
||||
* Creates the code out of templates
|
||||
*/
|
||||
class CVSSBSCodingRX : public CCodeGeneratorBase, CVSSHelper
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief create service content for the IDL file of a RX signal
|
||||
* @param[in] vssParts Interface in vss style separated in parts
|
||||
* @param[in] vecFunctions container of all functions of a single vss definition
|
||||
* @return content of the Device part of a IDL Interface of a RX signal
|
||||
*/
|
||||
std::string Code_RXIDLServiceList(const std::vector<std::string>& vssParts, const std::vector <SFunctionBSDefinition>& vecFunctions) const;
|
||||
|
||||
/**
|
||||
* @brief fill the KeyWordMap with all required strings
|
||||
* @param[in] signal signal definition structure to fill the KeyWordMap
|
||||
* @param[in] signalVD signal definition structure from vehicle device
|
||||
* @param[in] mapKeywords KeyWordMap to be filled
|
||||
*/
|
||||
void GetKeyWordMap(const SSignalBSDefinition& signal, const SSignalVDDefinition& signalVD, CKeywordMap& mapKeywords) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief create single or multiple lines containing include files
|
||||
* @param[in] vssOriginalNoDot vss string without points e.g. VehicleChassisSteeringWheelAngle
|
||||
* @return content of a single interface
|
||||
*/
|
||||
std::string Code_BS_RXIncludes(const std::string& vssOriginalNoDot) const;
|
||||
|
||||
/**
|
||||
* @brief create a single line containing a interface
|
||||
* @param[in] functionName function which is part of the interface
|
||||
* @param[in] vssWithColons vss string (complete version) with colons as separator
|
||||
* @param[in] vd_functionName function name (Vehicle Device)
|
||||
* @param[in] vd_vssWithColons vss string (complete version) with colons as separator (Vehicle Device)
|
||||
* @return content of a single interface
|
||||
*/
|
||||
std::string Code_BS_RXInterface(const std::string& functionName, const std::string& vssWithColons,
|
||||
const std::string& vd_functionName, const std::string& vd_vssWithColons) const;
|
||||
|
||||
/**
|
||||
* @brief create a single line containing a interface entry
|
||||
* @param[in] functionName function which is part of the interface
|
||||
* @param[in] vssWithColons vss string (short version) with colons as separator
|
||||
* @return content of a single interface entry
|
||||
*/
|
||||
std::string Code_BS_RXInterfaceEntry(const std::string& functionName, const std::string& vssWithColons) const;
|
||||
|
||||
/**
|
||||
* @brief Get the register and unregister part for the RX VD header
|
||||
* @param[in] vssWithColons vss string with colons as separator
|
||||
* @param[in] function function definition structure (Basic Service)
|
||||
* @param[in] functionVD function definition structure of vehicle device (Vehicle Device)
|
||||
* @return content of a single register and unregister part.
|
||||
*/
|
||||
std::string Code_BS_RXReAndUnregisterEvent(const std::string& vssWithColons, const SFunctionBSDefinition& function,
|
||||
const SFunctionVDDefinition& functionVD) const;
|
||||
|
||||
/**
|
||||
* @brief Get the private header part of the basic service header
|
||||
* @param[in] function function definition structure
|
||||
* @param[in] vssWithColons vss string with colons as separator
|
||||
* @return content of private header part of the basic service header
|
||||
*/
|
||||
std::string Code_BS_RXPrivateHeaderPart(const SFunctionBSDefinition& function, const std::string& vssWithColons) const;
|
||||
|
||||
/**
|
||||
* @brief create service content for the IDL file of a RX signal
|
||||
* @param[in] spaces string containing only space characters for aligning
|
||||
* @param[in] vssWithColons vss string (complete version) with colons as separator
|
||||
* @param[in] function function definition structure
|
||||
* @return content of the Device part of a IDL Interface of a RX signal
|
||||
*/
|
||||
std::string Code_RXIDLServiceInterface(const std::string& spaces, const std::string& vssWithColons,
|
||||
const SFunctionBSDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief unregister signal Event
|
||||
* @param[in] signalVD signal definition structure to fill the KeyWordMap (Vehicle Device)
|
||||
* @param[in] vd_vssWithColons vss string (complete version) with colons as separator (Vehicle Device)
|
||||
* @param[in] functionVD function definition structure (Vehicle Device)
|
||||
* @param[in] function function definition structure (Basic Service)
|
||||
* @return content of a unregister code
|
||||
*/
|
||||
std::string Code_BS_RXConstructor(const SSignalVDDefinition& signalVD, const std::string& vd_vssWithColons,
|
||||
const SFunctionVDDefinition& functionVD, const SFunctionBSDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief unregister signal Event
|
||||
* @param[in] signalVD signal definition structure to fill the KeyWordMap (Vehicle Device)
|
||||
* @param[in] vd_vssWithColons vss string (complete version) with colons as separator (Vehicle Device)
|
||||
* @param[in] functionVD function definition structure (Vehicle Device)
|
||||
* @return content of a unregister code
|
||||
*/
|
||||
std::string Code_BS_RXDestructor(const SSignalVDDefinition& signalVD, const std::string& vd_vssWithColons,
|
||||
const SFunctionVDDefinition& functionVD) const;
|
||||
|
||||
/**
|
||||
* @brief set and get functions for basic service
|
||||
* @param[in] class_name class name which is part of the interface (Basic Service)
|
||||
* @param[in] function function definition structure (Basic Service)
|
||||
* @param[in] functionVD function definition structure (Vehicle Device)
|
||||
* @return content of a single set and get function code
|
||||
*/
|
||||
std::string Code_BS_RXGetAndSetFunctions(const std::string& class_name, const SFunctionBSDefinition& function,
|
||||
const SFunctionVDDefinition& functionVD) const;
|
||||
|
||||
/**
|
||||
* @brief create register/unregister code for basic service
|
||||
* @param[in] class_name class name which is part of the interface
|
||||
* @param[in] function function definition structure
|
||||
* @param[in] vssWithColons vss string with colons as separator
|
||||
* @return content of a single signal register/unregister code
|
||||
*/
|
||||
std::string Code_BS_RXRegister(const std::string& class_name, const SFunctionBSDefinition& function,
|
||||
const std::string& vssWithColons) const;
|
||||
};
|
||||
|
||||
#endif // !defined VSS_BS_CODING_RX_H
|
||||
|
||||
249
sdv_executables/sdv_vss_util/vss_bs_codingtx.cpp
Normal file
249
sdv_executables/sdv_vss_util/vss_bs_codingtx.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
#include "vss_bs_codingtx.h"
|
||||
|
||||
void CVSSBSCodingTX::GetKeyWordMap(const SSignalBSDefinition& signal, const SSignalVDDefinition& signalVD, CKeywordMap& mapKeywords) const
|
||||
{
|
||||
std::string vd_vssWithColons = ReplaceCharacters(signal.vssVDDefinition, ".", "::");
|
||||
std::string vssWithColons = ReplaceCharacters(signal.vssDefinition, ".", "::");
|
||||
|
||||
//------------------------------------------------------- basic service header
|
||||
std::stringstream sstreamIncludesBS;
|
||||
std::string vd_vssNoDot = ReplaceCharacters(signal.vssVDDefinition, ".", "");
|
||||
std::string vssNoDot = ReplaceCharacters(signal.vssDefinition, ".", "");
|
||||
std::transform(vd_vssNoDot.begin(), vd_vssNoDot.end(), vd_vssNoDot.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
std::transform(vssNoDot.begin(), vssNoDot.end(), vssNoDot.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
sstreamIncludesBS << Code_BS_TXIncludes(vd_vssNoDot, vssNoDot);
|
||||
mapKeywords["tx_bs_includes_list"] = std::move(sstreamIncludesBS.str());
|
||||
|
||||
std::stringstream sstreamInterfacesBS;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamInterfacesBS << Code_BS_TXInterface(func.functionName, vssWithColons);
|
||||
}
|
||||
mapKeywords["tx_bs_interface_list"] = std::move(sstreamInterfacesBS.str());
|
||||
|
||||
std::stringstream sstreamInterfaceEntriesBS;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamInterfaceEntriesBS << Code_BS_TXInterfaceEntry(func.functionName, vssWithColons);
|
||||
}
|
||||
mapKeywords["tx_bs_interface_entry_list"] = std::move(sstreamInterfaceEntriesBS.str());
|
||||
|
||||
std::stringstream sstreamFunctionsBS;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamFunctionsBS << Code_BS_TXFunction(func);
|
||||
}
|
||||
mapKeywords["tx_bs_function_list"] = std::move(sstreamFunctionsBS.str());
|
||||
|
||||
std::stringstream sstreamVariablePointers;
|
||||
for (const auto& func : signalVD.vecFunctions)
|
||||
{
|
||||
sstreamVariablePointers << Code_BS_TXVariablePointerFromVD(func, vd_vssWithColons);
|
||||
}
|
||||
mapKeywords["tx_bs_variable_pointer_list"] = std::move(sstreamVariablePointers.str());
|
||||
|
||||
//------------------------------------------------------- basic service cpp
|
||||
std::stringstream sstreamVariablePointerInitializations;
|
||||
for (const auto& func : signalVD.vecFunctions)
|
||||
{
|
||||
sstreamVariablePointerInitializations << Code_BS_TXVariablePointerInitializationFromVD(func,
|
||||
signal.className, signal.vssDefinition, vd_vssWithColons);
|
||||
}
|
||||
mapKeywords["tx_bs_variable_pointer_init_list"] = std::move(sstreamVariablePointerInitializations.str());
|
||||
|
||||
std::stringstream sstreamPointerFunctionImplementation;
|
||||
for (uint32_t index = 0; index < signal.vecFunctions.size(); index++)
|
||||
{
|
||||
if (index >= signalVD.vecFunctions.size())
|
||||
break;
|
||||
auto func = signal.vecFunctions[index];
|
||||
auto funcVD = signalVD.vecFunctions[index];
|
||||
sstreamPointerFunctionImplementation << Code_BS_TXFunctionPointerImplementationFromVD(func, funcVD, signal.className);
|
||||
}
|
||||
mapKeywords["vd_tx_pointer_function_implementations"] = std::move(sstreamPointerFunctionImplementation.str());
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingTX::Code_BS_TXIDLList(const std::vector<std::string>& vssParts,
|
||||
const std::vector <SFunctionBSDefinition>& vecFunctions) const
|
||||
{
|
||||
int8_t loop = 1;
|
||||
std::string nameSpace = "module vss\n{\n";
|
||||
for (auto it = vssParts.begin(); it != vssParts.end(); ++it)
|
||||
{
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop, ' ');
|
||||
nameSpace.append("module ");
|
||||
nameSpace.append(*it);
|
||||
if (it == vssParts.end() - 1)
|
||||
{
|
||||
nameSpace.append("Service");
|
||||
}
|
||||
nameSpace.append("\n");
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop++, ' ');
|
||||
nameSpace.append("{\n");
|
||||
}
|
||||
|
||||
nameSpace.append("%interfaces%");
|
||||
loop--;
|
||||
for (size_t i = 0; i < vssParts.size() + 1; i++)
|
||||
{
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop--, ' ');
|
||||
nameSpace.append("};\n");
|
||||
}
|
||||
|
||||
bool newLine = false;
|
||||
std::string spaces = "";
|
||||
spaces.append(static_cast <int8_t>(4) * (vssParts.size() + 1), ' ');
|
||||
std::stringstream sstreamInterfaces;
|
||||
for (const auto& func : vecFunctions)
|
||||
{
|
||||
if (newLine)
|
||||
sstreamInterfaces << "\n\n";
|
||||
else
|
||||
newLine = true;
|
||||
sstreamInterfaces << Code_BS_TXIDLInterface(spaces, func);
|
||||
}
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["interfaces"] = std::move(sstreamInterfaces.str());
|
||||
|
||||
return ReplaceKeywords(nameSpace, mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingTX::Code_BS_TXIncludes(const std::string& vd_vssOriginalNoDot, const std::string& vssOriginalNoDot) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vd_vss_original_no_dot"] = vd_vssOriginalNoDot;
|
||||
mapKeywords["vss_original_no_dot"] = vssOriginalNoDot;
|
||||
|
||||
return ReplaceKeywords(R"code(#include "../vss_%vd_vss_original_no_dot%_vd_tx.h"
|
||||
#include "../vss_%vss_original_no_dot%_bs_tx.h"
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingTX::Code_BS_TXInterface(const std::string& functionName, const std::string& vssWithColons) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = functionName;
|
||||
mapKeywords["vss_with_colons"] = vssWithColons;
|
||||
|
||||
return ReplaceKeywords(R"code( , public vss::%vss_with_colons%Service::IVSS_Set%function_name%
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingTX::Code_BS_TXInterfaceEntry(const std::string& functionName, const std::string& vssWithColons) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = functionName;
|
||||
mapKeywords["vss_with_colons"] = vssWithColons;
|
||||
|
||||
return ReplaceKeywords(R"code( SDV_INTERFACE_ENTRY(vss::%vss_with_colons%Service::IVSS_Set%function_name%)
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingTX::Code_BS_TXIDLInterface(const std::string& spaces, const SFunctionBSDefinition& function) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["value_idltype"] = function.idlType;
|
||||
mapKeywords["value_ctype"] = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["multiple_spaces"] = spaces;
|
||||
|
||||
return ReplaceKeywords(R"code(%multiple_spaces%/**
|
||||
%multiple_spaces%* @brief IVSS_Set%function_name% Service interface
|
||||
%multiple_spaces%*/
|
||||
%multiple_spaces%interface IVSS_Set%function_name%
|
||||
%multiple_spaces%{
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Set %signal_name% signal
|
||||
%multiple_spaces% * @param[in] value
|
||||
%multiple_spaces% * @return true on success otherwise false
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% boolean Set%function_name%(in %value_idltype% value);
|
||||
%multiple_spaces%};
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingTX::Code_BS_TXFunction(const SFunctionBSDefinition& function) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["value_idltype"] = function.idlType;
|
||||
auto signalType = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["value_ctype"] = CastValueType(signalType);
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
/**
|
||||
* @brief Set %signal_name% signal
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool Set%function_name%(%value_ctype% value) override;
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingTX::Code_BS_TXVariablePointerFromVD(const SFunctionVDDefinition& functionVD,
|
||||
const std::string& vd_vssWithColons) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vd_function_name"] = functionVD.functionName;
|
||||
mapKeywords["vd_vss_with_colons"] = vd_vssWithColons;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
vss::%vd_vss_with_colons%Device::IVSS_Write%vd_function_name%* m_ptr%vd_function_name% = nullptr;)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingTX::Code_BS_TXFunctionPointerImplementationFromVD(const SFunctionBSDefinition& function,
|
||||
const SFunctionVDDefinition& functionVD, const std::string& className) const
|
||||
{
|
||||
std::string class_name_lowercase = className;
|
||||
std::transform(class_name_lowercase.begin(), class_name_lowercase.end(), class_name_lowercase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["vd_function_name"] = functionVD.functionName;
|
||||
mapKeywords["class_name"] = className;
|
||||
mapKeywords["value_idltype"] = function.idlType;
|
||||
auto signalType = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["value_ctype"] = CastValueType(signalType);
|
||||
mapKeywords["class_name_lowercase"] = class_name_lowercase;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
/**
|
||||
* @brief %function_name%
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool CBasicService%class_name%::Set%function_name%(%value_ctype% value)
|
||||
{
|
||||
return m_ptr%vd_function_name%->Write%vd_function_name%(value);
|
||||
}
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSBSCodingTX::Code_BS_TXVariablePointerInitializationFromVD(const SFunctionVDDefinition& functionVD,
|
||||
const std::string& className, const std::string& vssOriginal, const std::string& vd_vssWithColons) const
|
||||
{
|
||||
std::string class_name_lowercase = className;
|
||||
std::transform(class_name_lowercase.begin(), class_name_lowercase.end(), class_name_lowercase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vd_function_name"] = functionVD.functionName;
|
||||
mapKeywords["class_name"] = className;
|
||||
mapKeywords["vd_vss_original"] = vssOriginal;
|
||||
mapKeywords["vd_vss_with_colons"] = vd_vssWithColons;
|
||||
mapKeywords["class_name_lowercase"] = class_name_lowercase;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
m_ptr%vd_function_name% = sdv::core::GetObject("%vd_vss_original%_Device").GetInterface<vss::%vd_vss_with_colons%Device::IVSS_Write%vd_function_name%>();
|
||||
if (!m_ptr%vd_function_name%)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get interface 'IVSS_Write%vd_function_name%': [CBasicService%class_name%]");
|
||||
throw std::runtime_error("%vd_function_name% device not found");
|
||||
}
|
||||
)code", mapKeywords);
|
||||
}
|
||||
114
sdv_executables/sdv_vss_util/vss_bs_codingtx.h
Normal file
114
sdv_executables/sdv_vss_util/vss_bs_codingtx.h
Normal file
@@ -0,0 +1,114 @@
|
||||
#ifndef VSS_BS_CODING_TX_H
|
||||
#define VSS_BS_CODING_TX_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <interfaces/dispatch.h>
|
||||
|
||||
#include "codegen_base.h"
|
||||
#include "vss_helper.h"
|
||||
#include "vss_tx_templates.h"
|
||||
#include "vss_coding.h"
|
||||
|
||||
/**
|
||||
* @brief VSS code generator coding class.
|
||||
* Beside the definition of the basic service interface also information about the vehicle device is necessary
|
||||
* These 2 definitions must match, there must be a corresponding 'signalVD' definition
|
||||
* the function container of the basic service signal must match the function container if the 'signalVD'
|
||||
* Creates the code out of templates
|
||||
*/
|
||||
class CVSSBSCodingTX : public CCodeGeneratorBase, CVSSHelper
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief create basic service content for the IDL file of a TX signal
|
||||
* @param[in] vssParts Interface in vss style separated in parts
|
||||
* @param[in] vecFunctions container of all functions of a single (basic service) vss definition (basic service)
|
||||
* @return content of the basic service part of a IDL Interface of a TX signal
|
||||
*/
|
||||
std::string Code_BS_TXIDLList(const std::vector<std::string>& vssParts, const std::vector <SFunctionBSDefinition>& vecFunctions) const;
|
||||
|
||||
/**
|
||||
* @brief fill the KeyWordMap with all required strings
|
||||
* @param[in] signal signal definition structure to fill the KeyWordMap
|
||||
* @param[in] signalVD signal definition structure from vehicle device
|
||||
* @param[in] mapKeywords KeyWordMap to be filled
|
||||
*/
|
||||
void GetKeyWordMap(const SSignalBSDefinition& signal, const SSignalVDDefinition& signalVD, CKeywordMap& mapKeywords) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief create single or multiple lines containing include files
|
||||
* @param[in] vd_vssOriginalNoDot vss string without points of the corresponding vehicle device
|
||||
* @param[in] vssOriginalNoDot vss string without points e.g. VehicleChassisSteeringWheelAngle
|
||||
* @return content of a single interface
|
||||
*/
|
||||
std::string Code_BS_TXIncludes(const std::string& vd_vssOriginalNoDot, const std::string& vssOriginalNoDot) const;
|
||||
|
||||
/**
|
||||
* @brief create a single line containing a interface for basic service
|
||||
* @param[in] functionName function which is part of the interface
|
||||
* @param[in] vssWithColons vss string (complete version) with colons as separator
|
||||
* @return content of a single interface
|
||||
*/
|
||||
std::string Code_BS_TXInterface(const std::string& functionName, const std::string& vssWithColons) const;
|
||||
|
||||
/**
|
||||
* @brief create a single line containing a interface entry for basic service
|
||||
* @param[in] functionName function which is part of the interface
|
||||
* @param[in] vssWithColons vss string (complete version) with colons as separator
|
||||
* @return content of a single interface entry
|
||||
*/
|
||||
std::string Code_BS_TXInterfaceEntry(const std::string& functionName, const std::string& vssWithColons) const;
|
||||
|
||||
/**
|
||||
* @brief create list of interfaces (TX signals) for IDL file (Basic Service)
|
||||
* @param[in] spaces string containing only space characters for aligning
|
||||
* @param[in] function function definition structure
|
||||
* @return content of a single interface entry
|
||||
*/
|
||||
std::string Code_BS_TXIDLInterface(const std::string& spaces, const SFunctionBSDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief create function definition part (TX signals) for basic service
|
||||
* @param[in] function function definition structure
|
||||
* @return content of a single function declaration
|
||||
*/
|
||||
std::string Code_BS_TXFunction(const SFunctionBSDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief create definition of a interface pointer (TX signals) for basic service header file
|
||||
* @param[in] functionVD which is part of the interface (Vehicle Device)
|
||||
* @param[in] vd_vssWithColons vss string (complete version) with colons as separator (Vehicle Device)
|
||||
* @return content of a definition of a interface pointer
|
||||
*/
|
||||
std::string Code_BS_TXVariablePointerFromVD(const SFunctionVDDefinition& functionVD, const std::string& vd_vssWithColons) const;
|
||||
|
||||
/**
|
||||
* @brief create function pointer implementation part (TX signals) for basic service cpp file
|
||||
* @param[in] function function definition structure (Basic Service)
|
||||
* @param[in] functionVD function definition structure from vehicle device (Vehicle Device)
|
||||
* @param[in] className class name of the signal (Basic Service)
|
||||
* @return content of a single function pointer implementation
|
||||
*/
|
||||
std::string Code_BS_TXFunctionPointerImplementationFromVD(const SFunctionBSDefinition& function,
|
||||
const SFunctionVDDefinition& functionVD, const std::string& className) const;
|
||||
|
||||
/**
|
||||
* @brief create check if a interface pointer is valid (TX signals) for IDL file
|
||||
* @param[in] functionVD which is part of the interface (Vehicle Device)
|
||||
* @param[in] className class name of the signal (Basic Service)
|
||||
* @param[in] vssOriginal original vvs string (Basic Service)
|
||||
* @param[in] vd_vssWithColons vss string (complete version) with colons as separator (Vehicle Device)
|
||||
* @return content of a check if a interface pointer is valid
|
||||
*/
|
||||
std::string Code_BS_TXVariablePointerInitializationFromVD(const SFunctionVDDefinition& functionVD, const std::string& className,
|
||||
const std::string& vssOriginal, const std::string& vd_vssWithColons) const;
|
||||
};
|
||||
|
||||
#endif // !defined VSS_BS_CODING_TX_H
|
||||
|
||||
250
sdv_executables/sdv_vss_util/vss_bs_generator.cpp
Normal file
250
sdv_executables/sdv_vss_util/vss_bs_generator.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
#include "vss_bs_generator.h"
|
||||
#include "vss_coding.h"
|
||||
#include "vss_bs_codingrx.h"
|
||||
#include "vss_bs_codingtx.h"
|
||||
|
||||
|
||||
bool CVSSBSGenerator::GeneratedCode()
|
||||
{
|
||||
// Create project directory
|
||||
if (!m_pathProject.empty())
|
||||
{
|
||||
m_pathProject /= "vss_files";
|
||||
if (CreateFolder(m_pathProject, ""))
|
||||
{
|
||||
//CVSSCodingCommon coding(m_ssPrefix);
|
||||
CreateFiles(m_ssVersion);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string CVSSBSGenerator::AppendExtension(const std::string& prefix, const std::string& filename,
|
||||
const std::string& extension) const
|
||||
{
|
||||
return prefix + filename + extension;
|
||||
}
|
||||
|
||||
void CVSSBSGenerator::CreateFiles(const std::string& ssVersion)
|
||||
{
|
||||
for (const SSignalBSDefinition& signal : m_signals)
|
||||
{
|
||||
if (signal.signalDirection == sdv::core::ESignalDirection::sigdir_rx)
|
||||
m_RXsignals.push_back(signal);
|
||||
else
|
||||
m_TXsignals.push_back(signal);
|
||||
}
|
||||
CreateRXFiles(ssVersion);
|
||||
CreateTXFiles(ssVersion);
|
||||
}
|
||||
|
||||
void CVSSBSGenerator::CreateRXFiles(const std::string& ssVersion) const
|
||||
{
|
||||
for (const auto& rxSignal : m_RXsignals)
|
||||
{
|
||||
if (m_enableComponentCreation)
|
||||
{
|
||||
CreateBasicServiceFilesForRXSignal(rxSignal, ssVersion);
|
||||
}
|
||||
CreateIDLBasicServiceFileForRXSignal(rxSignal, ssVersion);
|
||||
}
|
||||
}
|
||||
|
||||
void CVSSBSGenerator::CreateBasicServiceFilesForRXSignal(const SSignalBSDefinition& signal, const std::string& ssVersion) const
|
||||
{
|
||||
std::string folderName = "BS_";
|
||||
folderName.append(signal.className);
|
||||
std::transform(folderName.begin(), folderName.end(), folderName.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
if (!CreateFolder(m_pathProject, folderName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::filesystem::path pathBSHeader = m_pathProject / folderName / AppendExtension("BS_", signal.className, ".h");
|
||||
std::filesystem::path pathBSClass = m_pathProject / folderName / AppendExtension("BS_", signal.className, ".cpp");
|
||||
std::filesystem::path pathCMakeLists = m_pathProject / folderName / "CMakeLists.txt";
|
||||
std::ofstream fstreamBSHeader;
|
||||
std::ofstream fstreamBSClass;
|
||||
auto pathLowerCaseHeader = MakeLowercaseFilename(pathBSHeader);
|
||||
auto pathLowerCaseClass = MakeLowercaseFilename(pathBSClass);
|
||||
fstreamBSHeader.open(pathLowerCaseHeader, std::ios::out | std::ios::trunc);
|
||||
fstreamBSClass.open(pathLowerCaseClass, std::ios::out | std::ios::trunc);
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
CVSSCodingCommon coding(m_ssPrefix);
|
||||
coding.GetCommonKeyWordMap(signal, mapKeywords, ssVersion);
|
||||
mapKeywords["bs_safeguard"] = coding.Code_SafeGuard(pathBSHeader.filename().generic_u8string());
|
||||
|
||||
mapKeywords["basic_service_h"] = pathLowerCaseHeader.filename().generic_u8string();
|
||||
mapKeywords["basic_service_cpp"] = pathLowerCaseClass.filename().generic_u8string();
|
||||
|
||||
CVSSBSCodingRX codingRX;
|
||||
auto signalVD = GetVDSignal(signal.vssVDDefinition);
|
||||
if (!signalVD.vecFunctions.size())
|
||||
{
|
||||
mapKeywords["vss_from_vd_not_found"] = "// corresponding vehicle device interface not found";
|
||||
}
|
||||
codingRX.GetKeyWordMap(signal, signalVD, mapKeywords);
|
||||
|
||||
fstreamBSHeader << ReplaceKeywords(szRXBasicServiceHeaderTemplate, mapKeywords);
|
||||
fstreamBSClass << ReplaceKeywords(szRXBasicServiceClassTemplate, mapKeywords);
|
||||
fstreamBSHeader.close();
|
||||
fstreamBSClass.close();
|
||||
|
||||
std::string classNameLowerCase = signal.className;
|
||||
std::transform(classNameLowerCase.begin(), classNameLowerCase.end(), classNameLowerCase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
std::string libaryName = m_ssPrefix + "_bs_" + classNameLowerCase + "_rx";
|
||||
auto cmakeContent = coding.Code_CMakeProject(libaryName, folderName);
|
||||
CreateCMakeFile(pathCMakeLists, cmakeContent);
|
||||
}
|
||||
|
||||
void CVSSBSGenerator::CreateIDLBasicServiceFileForRXSignal(const SSignalBSDefinition& signal, const std::string& ssVersion) const
|
||||
{
|
||||
std::stringstream ss(signal.vssDefinition);
|
||||
std::string item;
|
||||
std::string filenameBS = "VSS_";
|
||||
std::vector<std::string> parts;
|
||||
while (std::getline(ss, item, '.'))
|
||||
{
|
||||
parts.push_back(item);
|
||||
filenameBS.append(item);
|
||||
}
|
||||
filenameBS.append("_bs_rx");
|
||||
DeleteHeaderFile(m_pathProject, filenameBS);
|
||||
filenameBS.append(".idl");
|
||||
|
||||
std::filesystem::path pathBSRXIDL = m_pathProject / filenameBS;
|
||||
std::ofstream fstreamBSRXIDL;
|
||||
auto pathLowerCase = MakeLowercaseFilename(pathBSRXIDL);
|
||||
fstreamBSRXIDL.open(pathLowerCase, std::ios::out | std::ios::trunc);
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
CVSSCodingCommon coding(m_ssPrefix);
|
||||
coding.GetCommonKeyWordMap(signal, mapKeywords, ssVersion);
|
||||
mapKeywords["_bs_idl_h"] = pathLowerCase.filename().generic_u8string();
|
||||
|
||||
CVSSBSCodingRX codingRX;
|
||||
mapKeywords["vss_service"] = codingRX.Code_RXIDLServiceList(parts, signal.vecFunctions);
|
||||
|
||||
std::string vdIDLFileLowerCase = "vss_";
|
||||
vdIDLFileLowerCase.append(ReplaceCharacters(signal.vssVDDefinition, ".", ""));
|
||||
vdIDLFileLowerCase.append("_vd_rx.idl");
|
||||
std::transform(vdIDLFileLowerCase.begin(), vdIDLFileLowerCase.end(), vdIDLFileLowerCase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
mapKeywords["vd_idl_file"] = vdIDLFileLowerCase;
|
||||
|
||||
auto signalVD = GetVDSignal(signal.vssVDDefinition);
|
||||
if (signalVD.vecFunctions.size())
|
||||
{
|
||||
std::string vssNoDot = ReplaceCharacters(signal.vssVDDefinition, ".", "");
|
||||
mapKeywords["vd_vss_original_no_dot"] = vssNoDot;
|
||||
}
|
||||
else
|
||||
{
|
||||
mapKeywords["vss_device"] = "// corresponding vehicle device interface not found";
|
||||
}
|
||||
|
||||
fstreamBSRXIDL << ReplaceKeywords(szBSRXIDLTemplate, mapKeywords);
|
||||
fstreamBSRXIDL.close();
|
||||
}
|
||||
|
||||
void CVSSBSGenerator::CreateTXFiles(const std::string& ssVersion) const
|
||||
{
|
||||
for (const auto& txSignal : m_TXsignals)
|
||||
{
|
||||
if (m_enableComponentCreation)
|
||||
{
|
||||
CreateBasicServiceFilesForTXSignal(txSignal, ssVersion);
|
||||
}
|
||||
CreateIDLBasicServiceFileForTXSignal(txSignal, ssVersion);
|
||||
}
|
||||
}
|
||||
|
||||
void CVSSBSGenerator::CreateBasicServiceFilesForTXSignal(const SSignalBSDefinition& signal, const std::string& ssVersion) const
|
||||
{
|
||||
std::string folderName = "BS_";
|
||||
folderName.append(signal.className);
|
||||
std::transform(folderName.begin(), folderName.end(), folderName.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
if (!CreateFolder(m_pathProject, folderName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::filesystem::path pathBSHeader = m_pathProject / folderName / AppendExtension("BS_", signal.className, ".h");
|
||||
std::filesystem::path pathBSClass = m_pathProject / folderName / AppendExtension("BS_", signal.className, ".cpp");
|
||||
std::filesystem::path pathCMakeLists = m_pathProject / folderName / "CMakeLists.txt";
|
||||
std::ofstream fstreamBSHeader;
|
||||
std::ofstream fstreamBSClass;
|
||||
auto pathLowerCaseHeader = MakeLowercaseFilename(pathBSHeader);
|
||||
auto pathLowerCaseClass = MakeLowercaseFilename(pathBSClass);
|
||||
fstreamBSHeader.open(pathLowerCaseHeader, std::ios::out | std::ios::trunc);
|
||||
fstreamBSClass.open(pathLowerCaseClass, std::ios::out | std::ios::trunc);
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
CVSSCodingCommon coding(m_ssPrefix);
|
||||
coding.GetCommonKeyWordMap(signal, mapKeywords, ssVersion);
|
||||
mapKeywords["bs_safeguard"] = coding.Code_SafeGuard(pathBSHeader.filename().generic_u8string());
|
||||
|
||||
mapKeywords["basic_service_h"] = pathLowerCaseHeader.filename().generic_u8string();
|
||||
mapKeywords["basic_service_cpp"] = pathLowerCaseClass.filename().generic_u8string();
|
||||
|
||||
CVSSBSCodingTX codingTX;
|
||||
auto signalVD = GetVDSignal(signal.vssVDDefinition);
|
||||
if (!signalVD.vecFunctions.size())
|
||||
{
|
||||
mapKeywords["vss_from_vd_not_found"] = "// corresponding vehicle device interface not found";
|
||||
}
|
||||
codingTX.GetKeyWordMap(signal, signalVD, mapKeywords);
|
||||
|
||||
mapKeywords["basic_service_h"] = pathBSHeader.filename().generic_u8string();
|
||||
mapKeywords["basic_service_cpp"] = pathBSClass.filename().generic_u8string();
|
||||
|
||||
fstreamBSHeader << ReplaceKeywords(szTXBasicServiceHeaderTemplate, mapKeywords);
|
||||
fstreamBSClass << ReplaceKeywords(szTXBasicServiceClassTemplate, mapKeywords);
|
||||
fstreamBSHeader.close();
|
||||
fstreamBSClass.close();
|
||||
|
||||
std::string classNameLowerCase = signal.className;
|
||||
std::transform(classNameLowerCase.begin(), classNameLowerCase.end(), classNameLowerCase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
std::string libaryName = m_ssPrefix + "_bs_" + classNameLowerCase + "_tx";
|
||||
auto cmakeContent = coding.Code_CMakeProject(libaryName, folderName);
|
||||
CreateCMakeFile(pathCMakeLists, cmakeContent);
|
||||
}
|
||||
|
||||
|
||||
void CVSSBSGenerator::CreateIDLBasicServiceFileForTXSignal(const SSignalBSDefinition& signal, const std::string& ssVersion) const
|
||||
{
|
||||
std::stringstream ss(signal.vssDefinition);
|
||||
std::string item;
|
||||
std::string filenameBS = "VSS_";
|
||||
std::vector<std::string> parts;
|
||||
while (std::getline(ss, item, '.'))
|
||||
{
|
||||
parts.push_back(item);
|
||||
filenameBS.append(item);
|
||||
}
|
||||
filenameBS.append("_bs_tx");
|
||||
DeleteHeaderFile(m_pathProject, filenameBS);
|
||||
filenameBS.append(".idl");
|
||||
|
||||
std::filesystem::path pathBSTXIDL = m_pathProject / filenameBS;
|
||||
std::ofstream fstreamBSTXIDL;
|
||||
auto pathLowerCase = MakeLowercaseFilename(pathBSTXIDL);
|
||||
fstreamBSTXIDL.open(pathLowerCase, std::ios::out | std::ios::trunc);
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
CVSSCodingCommon coding(m_ssPrefix);
|
||||
coding.GetCommonKeyWordMap(signal, mapKeywords, ssVersion);
|
||||
mapKeywords["_bs_idl_h"] = pathLowerCase.filename().generic_u8string();
|
||||
|
||||
CVSSBSCodingTX codingTX;
|
||||
mapKeywords["vss_service"] = codingTX.Code_BS_TXIDLList(parts, signal.vecFunctions);
|
||||
|
||||
fstreamBSTXIDL << ReplaceKeywords(szBSTXIDLTemplate, mapKeywords);
|
||||
fstreamBSTXIDL.close();
|
||||
}
|
||||
127
sdv_executables/sdv_vss_util/vss_bs_generator.h
Normal file
127
sdv_executables/sdv_vss_util/vss_bs_generator.h
Normal file
@@ -0,0 +1,127 @@
|
||||
#ifndef VSS_BS_GENERATOR_H
|
||||
#define VSS_BS_GENERATOR_H
|
||||
|
||||
#include <fstream>
|
||||
#include "codegen_base.h"
|
||||
#include "vss_helper.h"
|
||||
|
||||
/**
|
||||
* @brief Basic Service generator.
|
||||
*/
|
||||
class CVSSBSGenerator : public CCodeGeneratorBase, CVSSHelper
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] signals Reference to a vector containing all signals (basic services)
|
||||
* @param[in] signalsVD Reference to a vector containing all signals (vehicle device)
|
||||
* @param[in] rpathOutputDir Reference to the outpur directory.
|
||||
* @param[in] rsPrefix used by cmake library and signal definition in signal_identifier.h file
|
||||
* @param[in] rsVersion optional version tag, will be wriiten in header of the files
|
||||
* @param[in] enableComponentCreation optional version tag, will be wriiten in header of the files
|
||||
*/
|
||||
|
||||
CVSSBSGenerator(const std::vector<SSignalBSDefinition>& signals, const std::vector<SSignalVDDefinition>& signalsVD, const std::filesystem::path& rpathOutputDir, const std::string& rsPrefix,
|
||||
const std::string& rsVersion, const bool enableComponentCreation) :
|
||||
m_enableComponentCreation(enableComponentCreation),
|
||||
m_ssPrefix(rsPrefix),
|
||||
m_ssVersion(rsVersion),
|
||||
m_pathProject(rpathOutputDir),
|
||||
m_signals(signals),
|
||||
m_signalsVD(signalsVD)
|
||||
{}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Auto generate the Files
|
||||
* @return true on success, otherwise false
|
||||
*/
|
||||
bool GeneratedCode();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief create a file name including prefix and extension
|
||||
* @param[in] prefix
|
||||
* @param[in] filename
|
||||
* @param[in] extension
|
||||
* @return combined file name
|
||||
*/
|
||||
std::string AppendExtension(const std::string& prefix, const std::string& filename, const std::string& extension) const;
|
||||
|
||||
/**
|
||||
* @brief create vehicle device and basic service .h an .cpp files
|
||||
* create IDL files
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateFiles(const std::string& ssVersion);
|
||||
|
||||
/**
|
||||
* @brief create IDL files and vehicle device and basic service files of RX signals
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateRXFiles(const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief create basic service files of a single RX signal
|
||||
* @param[in] signal single signal definition
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateBasicServiceFilesForRXSignal(const SSignalBSDefinition& signal, const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief create IDL file of a single RX signal (basic service)
|
||||
* @param[in] signal single signal definition
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateIDLBasicServiceFileForRXSignal(const SSignalBSDefinition& signal, const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief create IDL files and vehicle device and basic service files of TX signals
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateTXFiles(const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief create basic service files of a single TX signal
|
||||
* @param[in] signal single signal definition
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateBasicServiceFilesForTXSignal(const SSignalBSDefinition& signal, const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief create IDL file for a single TX signal (basic service)
|
||||
* @param[in] signal single signal definition
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateIDLBasicServiceFileForTXSignal(const SSignalBSDefinition& signal, const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief find a vss definition in the signal list of the vehicle device collection and return the signal
|
||||
* @param[in] vssDefinition vss name
|
||||
* @return signal if a signal was found, otherwise a empty signal definition
|
||||
*/
|
||||
SSignalVDDefinition GetVDSignal(const std::string& vssDefinition) const
|
||||
{
|
||||
SSignalVDDefinition noSignal;
|
||||
for (const auto& signal : m_signalsVD)
|
||||
{
|
||||
if (signal.vssDefinition.compare(vssDefinition) == 0)
|
||||
{
|
||||
return signal;
|
||||
}
|
||||
}
|
||||
return noSignal;
|
||||
}
|
||||
|
||||
bool m_enableComponentCreation; ///< if set, the code for the components are created, otherwise only idl files
|
||||
std::string m_ssPrefix; ///< prefix, used by cmake library and signal definition in signal_identifier.h file.
|
||||
std::string m_ssVersion; ///< optional version tag, will be wriiten in header of the files
|
||||
std::filesystem::path m_pathProject; ///< Project file path
|
||||
std::vector <SSignalBSDefinition> m_signals; ///< all signals
|
||||
std::vector <SSignalVDDefinition> m_signalsVD; ///< all signals
|
||||
std::vector <SSignalBSDefinition> m_TXsignals; ///< vector containing the RX signals
|
||||
std::vector <SSignalBSDefinition> m_RXsignals; ///< vector containing the TX signals
|
||||
};
|
||||
|
||||
#endif // !defined VSS_BS_GENERATOR_H
|
||||
256
sdv_executables/sdv_vss_util/vss_coding.cpp
Normal file
256
sdv_executables/sdv_vss_util/vss_coding.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
#include "vss_coding.h"
|
||||
|
||||
|
||||
void CVSSCodingCommon::GetCommonKeyWordMap(const SSignalVDDefinition& signal, CKeywordMap& mapKeywords, const std::string& rsVersion) const
|
||||
{
|
||||
CVSSCodingCommon coding(m_ssPrefix);
|
||||
//---------------------------------------------------------------------------------------------- Common file
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto in_time_t = std::chrono::system_clock::to_time_t(now);
|
||||
std::stringstream sstreamDate;
|
||||
sstreamDate << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X");
|
||||
mapKeywords["creation_date"] = sstreamDate.str();
|
||||
mapKeywords["version"] = coding.Code_VSSFileVersion(rsVersion);
|
||||
|
||||
//---------------------------------------------------------------------------------------------- Common
|
||||
// original vss example: Vehicle.Chassis.SteeringWheel.Angle
|
||||
// vssNoDot: VehicleChassisSteeringWheelAngle
|
||||
// vssWithUnderscores: Vehicle_Chassis_SteeringWheel_Angle
|
||||
// vssUppercase: VEHICLE_CHASSIS_STEERINGWHEEL_ANGLE
|
||||
// vssWithColons: Vehicle::Chassis::SteeringWheel::Angle
|
||||
// vssShorten: Vehicle.Chassis.SteeringWheel
|
||||
// vssShortenNoDot: VehicleChassisSteeringWheel
|
||||
// vssShortenWithColons: Vehicle::Chassis::SteeringWheel
|
||||
|
||||
mapKeywords["vss_original"] = signal.vssDefinition;
|
||||
std::string vssNoDot = ReplaceCharacters(signal.vssDefinition, ".", "");
|
||||
std::string vssWithUnderscores = ReplaceCharacters(signal.vssDefinition, ".", "_");
|
||||
std::string vssUppercase = ToUpper(vssWithUnderscores);
|
||||
std::string vssWithColons = ReplaceCharacters(signal.vssDefinition, ".", "::");
|
||||
std::string vssShorten = ShortenVSSString(signal.vssDefinition);
|
||||
std::string vssShortenNoDot = ReplaceCharacters(vssShorten, ".", "");
|
||||
std::string vssShortenWithColons = ReplaceCharacters(vssShorten, ".", "::");
|
||||
std::string class_name_lowercase = signal.className;
|
||||
std::transform(class_name_lowercase.begin(), class_name_lowercase.end(), class_name_lowercase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
mapKeywords["vss_original_no_dot"] = vssNoDot;
|
||||
mapKeywords["vss_uppercase"] = vssUppercase;
|
||||
mapKeywords["vss_with_colons"] = vssWithColons;
|
||||
mapKeywords["vss_shorten"] = vssShorten;
|
||||
mapKeywords["vss_shorten_no_dot"] = vssShortenNoDot;
|
||||
mapKeywords["vss_shorten_with_colons"] = vssShortenWithColons;
|
||||
mapKeywords["class_name"] = signal.className;
|
||||
mapKeywords["class_name_lowercase"] = class_name_lowercase;
|
||||
}
|
||||
|
||||
void CVSSCodingCommon::GetCommonKeyWordMap(const SSignalBSDefinition& signal, CKeywordMap& mapKeywords, const std::string& rsVersion) const
|
||||
{
|
||||
CVSSCodingCommon coding(m_ssPrefix);
|
||||
//---------------------------------------------------------------------------------------------- Common file
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto in_time_t = std::chrono::system_clock::to_time_t(now);
|
||||
std::stringstream sstreamDate;
|
||||
sstreamDate << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X");
|
||||
mapKeywords["creation_date"] = sstreamDate.str();
|
||||
mapKeywords["version"] = coding.Code_VSSFileVersion(rsVersion);
|
||||
|
||||
//---------------------------------------------------------------------------------------------- Common
|
||||
// original vss example: Vehicle.Chassis.SteeringWheel.Angle
|
||||
// vssNoDot: VehicleChassisSteeringWheelAngle
|
||||
// vssWithUnderscores: Vehicle_Chassis_SteeringWheel_Angle
|
||||
// vssUppercase: VEHICLE_CHASSIS_STEERINGWHEEL_ANGLE
|
||||
// vssWithColons: Vehicle::Chassis::SteeringWheel::Angle
|
||||
// vssShorten: Vehicle.Chassis.SteeringWheel
|
||||
// vssShortenNoDot: VehicleChassisSteeringWheel
|
||||
// vssShortenWithColons: Vehicle::Chassis::SteeringWheel
|
||||
|
||||
mapKeywords["vss_original"] = signal.vssDefinition;
|
||||
std::string vssNoDot = ReplaceCharacters(signal.vssDefinition, ".", "");
|
||||
std::string vssWithUnderscores = ReplaceCharacters(signal.vssDefinition, ".", "_");
|
||||
std::string vssUppercase = ToUpper(vssWithUnderscores);
|
||||
std::string vssWithColons = ReplaceCharacters(signal.vssDefinition, ".", "::");
|
||||
std::string vssShorten = ShortenVSSString(signal.vssDefinition);
|
||||
std::string vssShortenNoDot = ReplaceCharacters(vssShorten, ".", "");
|
||||
std::string vssShortenWithColons = ReplaceCharacters(vssShorten, ".", "::");
|
||||
std::string class_name_lowercase = signal.className;
|
||||
std::transform(class_name_lowercase.begin(), class_name_lowercase.end(), class_name_lowercase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
mapKeywords["vss_original_no_dot"] = vssNoDot;
|
||||
mapKeywords["vss_uppercase"] = vssUppercase;
|
||||
mapKeywords["vss_with_colons"] = vssWithColons;
|
||||
mapKeywords["vss_shorten"] = vssShorten;
|
||||
mapKeywords["vss_shorten_no_dot"] = vssShortenNoDot;
|
||||
mapKeywords["vss_shorten_with_colons"] = vssShortenWithColons;
|
||||
mapKeywords["class_name"] = signal.className;
|
||||
mapKeywords["class_name_lowercase"] = class_name_lowercase;
|
||||
}
|
||||
|
||||
std::string CVSSCodingCommon::Code_VSSFileVersion(const std::string& ssVersion) const
|
||||
{
|
||||
std::string version = ".";
|
||||
CKeywordMap mapKeywords;
|
||||
if (!ssVersion.empty())
|
||||
{
|
||||
version = "\n * VSS Version:" + ssVersion;
|
||||
}
|
||||
|
||||
mapKeywords["version"] = version;
|
||||
return ReplaceKeywords(R"code(File is auto generated from VSS utility%version%)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSCodingCommon::Code_SafeGuard(const std::string& ssFileName) const
|
||||
{
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto in_time_t = std::chrono::system_clock::to_time_t(now);
|
||||
std::string startWith = "__VSS_GENERATED__" + ssFileName + "_";
|
||||
|
||||
std::stringstream sstreamSafeguard;
|
||||
sstreamSafeguard << ToUpper(ReplaceCharacters(startWith, ".", "_")); //"__DBC_GENERATED__CONFIG_H__";
|
||||
sstreamSafeguard << std::put_time(std::localtime(&in_time_t), "%Y%m%d_%H%M%S") << "_";
|
||||
sstreamSafeguard << std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count() % 1000;
|
||||
sstreamSafeguard << "__";
|
||||
return sstreamSafeguard.str();
|
||||
}
|
||||
|
||||
std::string CVSSCodingCommon::Code_SignalIdentifier(const std::vector <SSignalVDDefinition>& allSignals,
|
||||
const std::string& ssFileName, const std::string& ssVersion) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
if (allSignals.size() > 0)
|
||||
{
|
||||
std::string signalTitle = "signal names";
|
||||
std::string canSignalTitle = "dbc variable names";
|
||||
std::string cTypeTitle = "C-type";
|
||||
std::string directionTitle = "RX/TX";
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto in_time_t = std::chrono::system_clock::to_time_t(now);
|
||||
std::stringstream sstreamDate;
|
||||
sstreamDate << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d %X");
|
||||
mapKeywords["creation_date"] = sstreamDate.str();
|
||||
mapKeywords["version"] = Code_VSSFileVersion(ssVersion);
|
||||
mapKeywords["file_name"] = ssFileName;
|
||||
mapKeywords["safeguard"] = Code_SafeGuard(ssFileName);
|
||||
|
||||
mapKeywords["object_prefix"] = m_ssPrefix;
|
||||
mapKeywords["signals"] = Code_AllSignalsIdentifierList(allSignals, signalTitle, canSignalTitle, cTypeTitle);
|
||||
mapKeywords["spaces01"] = Align(signalTitle, GetMaxSignalName(allSignals, signalTitle) + 1);
|
||||
mapKeywords["spaces02"] = Align(canSignalTitle, GetMaxCANSignalName(allSignals, canSignalTitle) + 1);
|
||||
mapKeywords["spaces03"] = Align(cTypeTitle, GetMaxCTypeFromIDLType(allSignals, cTypeTitle));
|
||||
mapKeywords["spaces04"] = Align(directionTitle, directionTitle.size() + 1);
|
||||
}
|
||||
|
||||
return ReplaceKeywords(R"code(/**
|
||||
* @file %file_name%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#ifndef %safeguard%
|
||||
#define %safeguard%
|
||||
|
||||
namespace %object_prefix%
|
||||
{
|
||||
// Data Dispatch Service %spaces01%to %spaces02% %spaces03% %spaces04% vss name space
|
||||
%signals%} // %object_prefix%
|
||||
|
||||
#endif // %safeguard%
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSCodingCommon::Code_AllSignalsIdentifierList(const std::vector <SSignalVDDefinition>& allSignals,
|
||||
const std::string& signalTitle, const std::string& canSignalTitle, const std::string& cTypeTitle) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
|
||||
std::stringstream sstreamSignals;
|
||||
for (const auto& signal : allSignals)
|
||||
{
|
||||
for (auto func : signal.vecFunctions)
|
||||
{
|
||||
sstreamSignals << Code_SignalIdentifierList(allSignals, signal, func, signalTitle, canSignalTitle, cTypeTitle);
|
||||
}
|
||||
}
|
||||
mapKeywords["signals_list"] = std::move(sstreamSignals.str());
|
||||
|
||||
return ReplaceKeywords(R"code(%signals_list%)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSCodingCommon::Code_SignalIdentifierList(const std::vector <SSignalVDDefinition>& allSignals, const SSignalVDDefinition& signal,
|
||||
const SFunctionVDDefinition& func, const std::string& signalTitle, const std::string& canSignalTitle, const std::string& cTypeTitle) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
auto startWithUppercase = Align(func.signalName, GetMaxSignalName(allSignals, "") + 1);
|
||||
if (!startWithUppercase.empty())
|
||||
{
|
||||
startWithUppercase[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(startWithUppercase[0])));
|
||||
}
|
||||
mapKeywords["start_with_uppercase"] = Align(startWithUppercase, GetMaxSignalName(allSignals, signalTitle) + 1);
|
||||
mapKeywords["can_signal_name"] = Align(AddQuotationMarks(func.canSignalName), GetMaxCANSignalName(allSignals, canSignalTitle) + 1);
|
||||
mapKeywords["value_ctype"] = Align(GetCTypeFromIDLType(func.idlType), GetMaxCTypeFromIDLType(allSignals, cTypeTitle));
|
||||
|
||||
if (signal.signalDirection == sdv::core::ESignalDirection::sigdir_rx)
|
||||
mapKeywords["signal_dir"] = "RX ";
|
||||
else
|
||||
mapKeywords["signal_dir"] = "TX ";
|
||||
mapKeywords["vss"] = Align(signal.vssDefinition, GetMaxVSSDefinition(allSignals, ""));
|
||||
|
||||
return ReplaceKeywords(R"code( static std::string ds%start_with_uppercase%= %can_signal_name%; ///< %value_ctype% %signal_dir% %vss%
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSCodingCommon::Code_CMakeProject(const std::string& targetLibName, const std::string& targetComponentName) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["target_lib_name"] = targetLibName;
|
||||
mapKeywords["component_file_name"] = targetComponentName;
|
||||
return ReplaceKeywords(R"code(# Enforce CMake version 3.20 or newer needed for path function
|
||||
cmake_minimum_required (VERSION 3.20)
|
||||
|
||||
# Use new policy for project version settings and default warning level
|
||||
cmake_policy(SET CMP0048 NEW) # requires CMake 3.14
|
||||
cmake_policy(SET CMP0092 NEW) # requires CMake 3.15
|
||||
|
||||
# Define project
|
||||
project(%target_lib_name% VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
# Use C++17 support
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
# Library symbols are hidden by default
|
||||
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
|
||||
# Set target name.
|
||||
set(TARGET_NAME %target_lib_name%)
|
||||
|
||||
# Set the SDV_FRAMEWORK_DEV_INCLUDE if not defined yet
|
||||
if (NOT DEFINED SDV_FRAMEWORK_DEV_INCLUDE)
|
||||
if (NOT DEFINED ENV{SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
message( FATAL_ERROR "The environment variable SDV_FRAMEWORK_DEV_INCLUDE needs to be pointing to the SDV V-API development include files location!")
|
||||
endif()
|
||||
set (SDV_FRAMEWORK_DEV_INCLUDE "$ENV{SDV_FRAMEWORK_DEV_INCLUDE}")
|
||||
endif()
|
||||
|
||||
# Include link to export directory of SDV V-API development include files location
|
||||
include_directories(${SDV_FRAMEWORK_DEV_INCLUDE})
|
||||
|
||||
# Set platform specific compile flags
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
add_compile_options(/W4 /WX /wd4996 /wd4100 /permissive- /Zc:rvalueCast)
|
||||
else()
|
||||
add_compile_options(-Werror -Wall -Wextra -Wshadow -Wpedantic -Wunreachable-code -fno-common)
|
||||
endif()
|
||||
|
||||
# Add the dynamic library
|
||||
add_library(${TARGET_NAME} SHARED
|
||||
%component_file_name%.h
|
||||
%component_file_name%.cpp)
|
||||
|
||||
# Set extension to .sdv
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES SUFFIX ".sdv")
|
||||
|
||||
# TODO: set target name.
|
||||
#add_dependencies(${TARGET_NAME} <add_cmake_target_this_depends_on>)
|
||||
)code", mapKeywords);
|
||||
}
|
||||
106
sdv_executables/sdv_vss_util/vss_coding.h
Normal file
106
sdv_executables/sdv_vss_util/vss_coding.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#ifndef VSS_CODING_H
|
||||
#define VSS_CODING_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <interfaces/dispatch.h>
|
||||
|
||||
#include "codegen_base.h"
|
||||
#include "vss_helper.h"
|
||||
|
||||
/**
|
||||
* @brief VSS code generator coding class.
|
||||
* Creates the code out of templates
|
||||
*/
|
||||
class CVSSCodingCommon : public CCodeGeneratorBase, CVSSHelper
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] rsPrefix used by cmake library and signal definition in signal_identifier.h file
|
||||
*/
|
||||
CVSSCodingCommon(const std::string& rsPrefix) : m_ssPrefix(rsPrefix) {}
|
||||
|
||||
/**
|
||||
* @brief fill the KeyWordMap with all required strings
|
||||
* @param[in] signal signal definition structure to fill the KeyWordMap
|
||||
* @param[in] mapKeywords KeyWordMap to be filled
|
||||
* @param[in] rsVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void GetCommonKeyWordMap(const SSignalVDDefinition& signal, CKeywordMap& mapKeywords, const std::string& rsVersion) const;
|
||||
|
||||
/**
|
||||
* @brief fill the KeyWordMap with all required strings
|
||||
* @param[in] signal signal definition structure to fill the KeyWordMap
|
||||
* @param[in] mapKeywords KeyWordMap to be filled
|
||||
* @param[in] rsVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void GetCommonKeyWordMap(const SSignalBSDefinition& signal, CKeywordMap& mapKeywords, const std::string& rsVersion) const;
|
||||
|
||||
/**
|
||||
* @brief create content of the signal_identifier.h file
|
||||
* @param[in] allSignals container of all signal definitions
|
||||
* @param[in] ssFileName file name of the signal_identifier.h file
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
* @return content of the signal_identifier.h file
|
||||
*/
|
||||
std::string Code_SignalIdentifier(const std::vector <SSignalVDDefinition>& allSignals, const std::string& ssFileName,
|
||||
const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief get the version line which will be added in the header of the files
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
* @return line for the header of the files to know the file is auto generated
|
||||
*/
|
||||
std::string Code_VSSFileVersion(const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief generates the unique define to avoid duplicate loading of a header file
|
||||
* @param[in] ssFileName file name which will be included in the unique define
|
||||
* @return unique define string
|
||||
*/
|
||||
std::string Code_SafeGuard(const std::string& ssFileName) const;
|
||||
|
||||
/**
|
||||
* @brief generates the cmakelist.txt file
|
||||
* @param[in] targetLibName project cmake name
|
||||
* @param[in] targetComponentName is the name of the header and cpp file
|
||||
* @return content of the CMakeList.txt file
|
||||
*/
|
||||
std::string Code_CMakeProject(const std::string& targetLibName, const std::string& targetComponentName) const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief create a signal line for the signal_identifier file
|
||||
* @param[in] allSignals container of all signals for aligning of the string
|
||||
* @param[in] signal single signal the function belongs to
|
||||
* @param[in] func the function which should be returned in a line
|
||||
* @param[in] signalTitle signal title string in file signal_identifier.h
|
||||
* @param[in] canSignalTitle can signal title string in file signal_identifier.h
|
||||
* @param[in] cTypeTitle c-type title string in file signal_identifier.h
|
||||
* @return content of a single function for the signal_identifier file
|
||||
*/
|
||||
std::string Code_SignalIdentifierList(const std::vector <SSignalVDDefinition>& allSignals, const SSignalVDDefinition& signal,
|
||||
const SFunctionVDDefinition& func, const std::string& signalTitle, const std::string& canSignalTitle, const std::string& cTypeTitle) const;
|
||||
|
||||
/**
|
||||
* @brief create a list of all signals for the signal_identifier file
|
||||
* @param[in] allSignals container of all signals
|
||||
* @param[in] signalTitle signal title string in file signal_identifier.h
|
||||
* @param[in] canSignalTitle can signal title string in file signal_identifier.h
|
||||
* @param[in] cTypeTitle c-type title string in file signal_identifier.h
|
||||
* @return content of list of all signals for the signal_identifier file
|
||||
*/
|
||||
std::string Code_AllSignalsIdentifierList(const std::vector <SSignalVDDefinition>& allSignals,
|
||||
const std::string& signalTitle, const std::string& canSignalTitle, const std::string& cTypeTitle) const;
|
||||
|
||||
std::string m_ssPrefix; ///< prefix, used by cmake library and signal definition in signal_identifier.h file.
|
||||
};
|
||||
|
||||
#endif // !defined VSS_CODING_H
|
||||
|
||||
535
sdv_executables/sdv_vss_util/vss_helper.cpp
Normal file
535
sdv_executables/sdv_vss_util/vss_helper.cpp
Normal file
@@ -0,0 +1,535 @@
|
||||
#include "vss_helper.h"
|
||||
|
||||
std::string CVSSHelper::MapDeclType2CType(const sdv::vss::EDeclType eDeclType) const
|
||||
{
|
||||
switch (eDeclType)
|
||||
{
|
||||
case sdv::vss::EDeclType::decltype_short: return "int16_t";
|
||||
case sdv::vss::EDeclType::decltype_long: return "int32_t";
|
||||
case sdv::vss::EDeclType::decltype_long_long: return "int64_t";
|
||||
case sdv::vss::EDeclType::decltype_unsigned_short: return "uint16_t";
|
||||
case sdv::vss::EDeclType::decltype_unsigned_long: return "uint32_t";
|
||||
case sdv::vss::EDeclType::decltype_unsigned_long_long: return "uint64_t";
|
||||
case sdv::vss::EDeclType::decltype_float: return "float";
|
||||
case sdv::vss::EDeclType::decltype_double: return "double";
|
||||
case sdv::vss::EDeclType::decltype_long_double: return "long double";
|
||||
case sdv::vss::EDeclType::decltype_fixed: return "uint32_t"; // TODO: Not implemented!
|
||||
case sdv::vss::EDeclType::decltype_char: return "char";
|
||||
case sdv::vss::EDeclType::decltype_char16: return "char16_t";
|
||||
case sdv::vss::EDeclType::decltype_char32: return "char32_t";
|
||||
case sdv::vss::EDeclType::decltype_wchar: return "wchar_t";
|
||||
case sdv::vss::EDeclType::decltype_boolean: return "bool";
|
||||
case sdv::vss::EDeclType::decltype_native: return "size_t";
|
||||
case sdv::vss::EDeclType::decltype_octet: return "uint8_t";
|
||||
case sdv::vss::EDeclType::decltype_string: return "sdv::string";
|
||||
case sdv::vss::EDeclType::decltype_u8string: return "sdv::u8string";
|
||||
case sdv::vss::EDeclType::decltype_u16string: return "sdv::u16string";
|
||||
case sdv::vss::EDeclType::decltype_u32string: return "sdv::u32string";
|
||||
case sdv::vss::EDeclType::decltype_wstring: return "sdv::wstring";
|
||||
case sdv::vss::EDeclType::decltype_enum: return "enum class";
|
||||
case sdv::vss::EDeclType::decltype_struct: return "struct";
|
||||
case sdv::vss::EDeclType::decltype_union: return "union";
|
||||
case sdv::vss::EDeclType::decltype_module: return "namespace";
|
||||
case sdv::vss::EDeclType::decltype_interface: return "interface";
|
||||
case sdv::vss::EDeclType::decltype_exception: return "struct";
|
||||
case sdv::vss::EDeclType::decltype_attribute: return "";
|
||||
case sdv::vss::EDeclType::decltype_operation: return "";
|
||||
case sdv::vss::EDeclType::decltype_parameter: return "";
|
||||
case sdv::vss::EDeclType::decltype_enum_entry: return "";
|
||||
case sdv::vss::EDeclType::decltype_case_entry: return "";
|
||||
case sdv::vss::EDeclType::decltype_typedef: return "typedef";
|
||||
case sdv::vss::EDeclType::decltype_sequence: return "sdv::sequence";
|
||||
case sdv::vss::EDeclType::decltype_pointer: return "sdv::pointer";
|
||||
case sdv::vss::EDeclType::decltype_map: return "uint32_t"; // TODO: Not implemented!
|
||||
case sdv::vss::EDeclType::decltype_bitset: return "uint32_t"; // TODO: Not implemented!
|
||||
case sdv::vss::EDeclType::decltype_bitfield: return "uint32_t"; // TODO: Not implemented!
|
||||
case sdv::vss::EDeclType::decltype_bitmask: return "uint32_t"; // TODO: Not implemented!
|
||||
case sdv::vss::EDeclType::decltype_any: return "sdv::any_t";
|
||||
case sdv::vss::EDeclType::decltype_interface_id: return "sdv::interface_id";
|
||||
case sdv::vss::EDeclType::decltype_interface_type: return "sdv::interface_t";
|
||||
case sdv::vss::EDeclType::decltype_exception_id: return "sdv::exception_id";
|
||||
case sdv::vss::EDeclType::decltype_void: return "void";
|
||||
case sdv::vss::EDeclType::decltype_unknown:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVSSHelper::CreateCMakeFile(const std::filesystem::path& filePath, const std::string& cmakeContent) const
|
||||
{
|
||||
try
|
||||
{
|
||||
// create/write CMakeLists.txt only if content has changed
|
||||
std::string cmakeExisitingContent = "";
|
||||
|
||||
if (std::filesystem::exists(filePath))
|
||||
{
|
||||
std::ifstream stream;
|
||||
stream.open(filePath);
|
||||
if (stream.is_open())
|
||||
{
|
||||
std::stringstream sstream;
|
||||
sstream << stream.rdbuf();
|
||||
cmakeExisitingContent = std::move(sstream.str());
|
||||
}
|
||||
stream.close();
|
||||
}
|
||||
|
||||
if (cmakeContent.compare(cmakeExisitingContent) != 0)
|
||||
{
|
||||
std::ofstream fstreamCMakeFile;
|
||||
fstreamCMakeFile.open(filePath, std::ios::out | std::ios::trunc);
|
||||
fstreamCMakeFile << cmakeContent;
|
||||
fstreamCMakeFile.close();
|
||||
}
|
||||
}
|
||||
catch (const std::filesystem::filesystem_error& e)
|
||||
{
|
||||
std::cout << "Filesystem error: " << e.what() << '\n';
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
std::cout << "Error: " << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
std::filesystem::path CVSSHelper::MakeLowercaseFilename(std::filesystem::path & fullPath) const
|
||||
{
|
||||
std::filesystem::path parentPath = fullPath.parent_path();
|
||||
std::string filename = fullPath.filename().string();
|
||||
|
||||
std::transform(filename.begin(), filename.end(), filename.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
return parentPath / filename;
|
||||
}
|
||||
|
||||
std::string CVSSHelper::Align(const std::string& ssInput, size_t size) const
|
||||
{
|
||||
auto alignedString = ssInput;
|
||||
while (alignedString.size() < size)
|
||||
{
|
||||
alignedString.append(" ");
|
||||
}
|
||||
return alignedString.c_str();
|
||||
}
|
||||
|
||||
size_t CVSSHelper::GetMaxClassName(const std::vector <SSignalVDDefinition>& signals, const std::string& ssTitle) const
|
||||
{
|
||||
size_t max = ssTitle.size();
|
||||
for (const auto& signal : signals)
|
||||
{
|
||||
if (max < signal.className.size())
|
||||
{
|
||||
max = signal.className.size();
|
||||
}
|
||||
}
|
||||
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
size_t CVSSHelper::GetMaxIDLType(const std::vector <SSignalVDDefinition>& signals, const std::string& ssTitle) const
|
||||
{
|
||||
size_t max = ssTitle.size();
|
||||
for (const auto& signal : signals)
|
||||
{
|
||||
for (auto func : signal.vecFunctions)
|
||||
{
|
||||
if (max < func.idlType.size())
|
||||
{
|
||||
max = func.idlType.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
size_t CVSSHelper::GetMaxCTypeFromIDLType(const std::vector <SSignalVDDefinition>& signals, const std::string& ssTitle) const
|
||||
{
|
||||
size_t max = ssTitle.size();
|
||||
for (const auto& signal : signals)
|
||||
{
|
||||
for (auto func : signal.vecFunctions)
|
||||
{
|
||||
if (max < GetCTypeFromIDLType(func.idlType).size())
|
||||
{
|
||||
max = GetCTypeFromIDLType(func.idlType).size();
|
||||
}
|
||||
}
|
||||
}
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
size_t CVSSHelper::GetMaxSignalName(const std::vector <SSignalVDDefinition>& signals, const std::string& ssTitle) const
|
||||
{
|
||||
size_t max = ssTitle.size();
|
||||
for (const auto& signal : signals)
|
||||
{
|
||||
for (auto func : signal.vecFunctions)
|
||||
{
|
||||
if (max < func.signalName.size())
|
||||
{
|
||||
max = func.signalName.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
size_t CVSSHelper::GetMaxCANSignalName(const std::vector <SSignalVDDefinition>& signals, const std::string& ssTitle) const
|
||||
{
|
||||
size_t max = ssTitle.size();
|
||||
for (const auto& signal : signals)
|
||||
{
|
||||
for (auto func : signal.vecFunctions)
|
||||
{
|
||||
if (max < func.canSignalName.size())
|
||||
{
|
||||
max = func.canSignalName.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
size_t CVSSHelper::GetMaxFunctionName(const std::vector <SSignalVDDefinition>& signals, const std::string& ssTitle) const
|
||||
{
|
||||
size_t max = ssTitle.size();
|
||||
for (const auto& signal : signals)
|
||||
{
|
||||
for (auto func : signal.vecFunctions)
|
||||
{
|
||||
if (max < func.functionName.size())
|
||||
{
|
||||
max = func.functionName.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
size_t CVSSHelper::GetMaxVSSDefinition(const std::vector <SSignalVDDefinition>& signals, const std::string& ssTitle) const
|
||||
{
|
||||
size_t max = ssTitle.size();
|
||||
for (const auto& signal : signals)
|
||||
{
|
||||
if (max < signal.vssDefinition.size())
|
||||
{
|
||||
max = signal.vssDefinition.size();
|
||||
}
|
||||
}
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
std::string CVSSHelper::GenerateDefaultIfEmpty(const std::string& ssInput, std::string ssDefaultString, const uint32_t& index) const
|
||||
{
|
||||
if (ssInput.size() > 0)
|
||||
{
|
||||
return ssInput;
|
||||
}
|
||||
if (index != 0)
|
||||
{
|
||||
ssDefaultString.append("_");
|
||||
ssDefaultString.append(std::to_string(index));
|
||||
}
|
||||
return ssDefaultString;
|
||||
}
|
||||
|
||||
std::string CVSSHelper::Trim(const std::string& ssInput) const
|
||||
{
|
||||
size_t first = ssInput.find_first_not_of(' ');
|
||||
if (first == std::string::npos)
|
||||
{
|
||||
return ""; // No content
|
||||
}
|
||||
size_t last = ssInput.find_last_not_of(' ');
|
||||
return ssInput.substr(first, (last - first + 1));
|
||||
}
|
||||
|
||||
bool CVSSHelper::MustNotContainSpaces(const std::string& ssInput) const
|
||||
{
|
||||
if (ssInput.find(' ') != std::string::npos)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVSSHelper::IsNumber(const std::string& ssInput) const
|
||||
{
|
||||
if (!ssInput.empty())
|
||||
{
|
||||
auto character = ssInput[0];
|
||||
return std::isdigit(character);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string CVSSHelper::ValidateVSSFormatNumbers(const std::string& ssInput) const
|
||||
{
|
||||
std::stringstream ss(ssInput);
|
||||
std::string part;
|
||||
std::vector<std::string> parts;
|
||||
|
||||
while (std::getline(ss, part, '.'))
|
||||
{
|
||||
if (IsNumber(part))
|
||||
{
|
||||
parts.push_back("_" + part);
|
||||
}
|
||||
else {
|
||||
parts.push_back(part);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ssInput.empty() && ssInput.back() == '.')
|
||||
{
|
||||
parts.push_back("");
|
||||
}
|
||||
|
||||
std::ostringstream result;
|
||||
for (size_t i = 0; i < parts.size(); ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
result << ".";
|
||||
}
|
||||
result << parts[i];
|
||||
}
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
bool CVSSHelper::MustContainDotOrIsEmpty(const std::string& ssInput, bool mustBeEmpty) const
|
||||
{
|
||||
if ((ssInput.size() == 0) && (mustBeEmpty)) // empty is not allowed
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (ssInput.size() == 0) // empty is allowed
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (ssInput.find('.') != std::string::npos)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string CVSSHelper::AddQuotationMarks(const std::string& value) const
|
||||
{
|
||||
std::string returnString = "\"";
|
||||
returnString.append(value);
|
||||
returnString.append("\"");
|
||||
return returnString;
|
||||
}
|
||||
|
||||
std::string CVSSHelper::ReplaceCharacters(const std::string& ssInput, const std::string& from, const std::string& to) const
|
||||
{
|
||||
std::string str = ssInput;
|
||||
|
||||
size_t start_pos = 0;
|
||||
while ((start_pos = str.find(from, start_pos)) != std::string::npos)
|
||||
{
|
||||
str.replace(start_pos, from.length(), to);
|
||||
start_pos += to.length(); // Move past the replacement
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string CVSSHelper::ToUpper(const std::string& ssInput) const
|
||||
{
|
||||
std::stringstream sstreamToUpper;
|
||||
for (char c : ssInput)
|
||||
{
|
||||
sstreamToUpper << static_cast<char>(std::toupper(c));
|
||||
}
|
||||
|
||||
return sstreamToUpper.str();
|
||||
}
|
||||
|
||||
std::string CVSSHelper::ShortenVSSString(const std::string& ssInput) const
|
||||
{
|
||||
size_t start_pos = ssInput.size();
|
||||
start_pos = ssInput.rfind(".", start_pos);
|
||||
if (start_pos != std::string::npos)
|
||||
{
|
||||
return ssInput.substr(0, start_pos);
|
||||
}
|
||||
|
||||
return ssInput;
|
||||
}
|
||||
|
||||
std::string CVSSHelper::CastValueType(const std::string& ssSignalType) const
|
||||
{
|
||||
std::vector<std::string> stringTypes = { "sdv::string", "sdv::u8string", "sdv::u16string", "sdv::u32string", "sdv::wstring" };
|
||||
if (std::find(stringTypes.begin(), stringTypes.end(), ssSignalType) != stringTypes.end())
|
||||
{
|
||||
std::string type = "const " + ssSignalType + "&";
|
||||
return type;
|
||||
}
|
||||
|
||||
return ssSignalType;
|
||||
}
|
||||
|
||||
std::string CVSSHelper::GetCTypeFromIDLType(const std::string& ssIDLType) const
|
||||
|
||||
{
|
||||
for (const auto& type : m_vecDeclTypes)
|
||||
{
|
||||
if (ssIDLType == type.first)
|
||||
{
|
||||
auto s = type.second;
|
||||
return MapDeclType2CType(s);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool CVSSHelper::ValidateIDLTypes(const std::vector<std::string>& vecTypes, const bool silent) const
|
||||
{
|
||||
for (const auto& type : vecTypes)
|
||||
{
|
||||
if (GetCTypeFromIDLType(type).empty())
|
||||
{
|
||||
if (!silent)
|
||||
{
|
||||
std::cout << "ERROR! Invalid IDL type: '" << type << "'" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CVSSHelper::ValidateVDCodeStyle(const SSignalVDDefinition& signal, const bool verbose) const
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
if (!std::isupper(static_cast<unsigned char>(signal.className[0])))
|
||||
{
|
||||
std::cout << "Class name should start with upper case: '" << signal.className << "'" <<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
void CVSSHelper::ValidateBSCodeStyle(const SSignalBSDefinition& signal, const bool verbose) const
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
if (!std::isupper(static_cast<unsigned char>(signal.className[0])))
|
||||
{
|
||||
std::cout << "Class name should start with upper case: '" << signal.className << "'" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CVSSHelper::ValidateVDCodeStyle(const SFunctionVDDefinition& function, const bool verbose) const
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
if (std::isupper(static_cast<unsigned char>(function.signalName[0])))
|
||||
{
|
||||
std::cout << "Signal name should start with lower case: '" << function.signalName << "'" << std::endl;
|
||||
}
|
||||
if (!std::isupper(static_cast<unsigned char>(function.functionName[0])))
|
||||
{
|
||||
std::cout << "Function name should start with upper case: '" << function.functionName << "'" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
void CVSSHelper::ValidateBSCodeStyle(const SFunctionBSDefinition& function, const bool verbose) const
|
||||
{
|
||||
if (verbose)
|
||||
{
|
||||
if (std::isupper(static_cast<unsigned char>(function.signalName[0])))
|
||||
{
|
||||
std::cout << "Signal name should start with lower case: '" << function.signalName << "'" << std::endl;
|
||||
}
|
||||
if (!std::isupper(static_cast<unsigned char>(function.functionName[0])))
|
||||
{
|
||||
std::cout << "Function name should start with upper case: '" << function.functionName << "'" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CVSSHelper::CreateFolder(const std::filesystem::path& rootPath, const std::string& subfolder) const
|
||||
{
|
||||
auto path = rootPath;
|
||||
if (!subfolder.empty())
|
||||
{
|
||||
path = rootPath / subfolder;
|
||||
}
|
||||
try
|
||||
{
|
||||
for (size_t nCnt = 0; nCnt < 5; nCnt++)
|
||||
{
|
||||
if (!std::filesystem::exists(path))
|
||||
{
|
||||
std::filesystem::create_directories(path);
|
||||
}
|
||||
else
|
||||
break;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
}
|
||||
}
|
||||
catch (const std::filesystem::filesystem_error& e)
|
||||
{
|
||||
std::cout << "catch (const std::filesystem::filesystem_error& e)" << std::endl;
|
||||
std::cout << "Error removing directory: " << e.what() << '\n';
|
||||
}
|
||||
return std::filesystem::exists(path);
|
||||
}
|
||||
|
||||
void CVSSHelper::DeleteHeaderFile(const std::filesystem::path& path, const std::string& fileNameNoExtension) const
|
||||
{
|
||||
auto headerFile = fileNameNoExtension;
|
||||
headerFile.append(".h");
|
||||
auto file = path / headerFile;
|
||||
try
|
||||
{
|
||||
if (!std::filesystem::is_directory(file))
|
||||
{
|
||||
std::filesystem::remove(file);
|
||||
}
|
||||
}
|
||||
catch (const std::filesystem::filesystem_error& e)
|
||||
{
|
||||
std::cout << "catch (const std::filesystem::filesystem_error& e)" << std::endl;
|
||||
std::cout << "Error removing directory: " << e.what() << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
bool CVSSHelper::VehicleDeviceVSSDefinitionExists(bool bSilent, const std::vector <SSignalVDDefinition>& vdSignals,
|
||||
const std::vector <SSignalBSDefinition>& bsSignals)
|
||||
{
|
||||
if (bsSignals.size())
|
||||
{
|
||||
std::unordered_set<std::string> vssVDDefinitions;
|
||||
for (const auto& vssDefinition : vdSignals)
|
||||
{
|
||||
vssVDDefinitions.insert(vssDefinition.vssDefinition);
|
||||
}
|
||||
|
||||
for (const auto& vssDefinition : bsSignals)
|
||||
{
|
||||
if (vssVDDefinitions.find(vssDefinition.vssVDDefinition) == vssVDDefinitions.end())
|
||||
{
|
||||
if (!bSilent)
|
||||
{
|
||||
std::cout << vssDefinition.vssVDDefinition << " cannot be found, requested by " << vssDefinition.vssDefinition << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
487
sdv_executables/sdv_vss_util/vss_helper.h
Normal file
487
sdv_executables/sdv_vss_util/vss_helper.h
Normal file
@@ -0,0 +1,487 @@
|
||||
#ifndef VSS_HELPER_H
|
||||
#define VSS_HELPER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
//#include <algorithm>
|
||||
#include <interfaces/dispatch.h>
|
||||
|
||||
namespace sdv
|
||||
{
|
||||
/**
|
||||
* @brief vss namespace
|
||||
*/
|
||||
namespace vss
|
||||
{
|
||||
/**
|
||||
* @brief The entity declaration type.
|
||||
*/
|
||||
enum class EDeclType : uint32_t
|
||||
{
|
||||
/// Unknown type
|
||||
decltype_unknown,
|
||||
/// Integer type (int16_t)
|
||||
decltype_short,
|
||||
/// Integer type (int32_t)
|
||||
decltype_long,
|
||||
/// Integer type (int64_t)
|
||||
decltype_long_long,
|
||||
/// Octet type (uint8_t)
|
||||
decltype_octet,
|
||||
/// Integer type (uint16_t)
|
||||
decltype_unsigned_short,
|
||||
/// Integer type (uint32)
|
||||
decltype_unsigned_long,
|
||||
/// Integer type (uint64_t)
|
||||
decltype_unsigned_long_long,
|
||||
/// Floating point type
|
||||
decltype_float,
|
||||
/// Floating point type
|
||||
decltype_double,
|
||||
/// Floating point type
|
||||
decltype_long_double,
|
||||
/// Fixed point templated type
|
||||
decltype_fixed,
|
||||
/// Character type (int8_t)
|
||||
decltype_char,
|
||||
/// UTF-16 character
|
||||
decltype_char16,
|
||||
/// UTF-32 character
|
||||
decltype_char32,
|
||||
/// Character type
|
||||
decltype_wchar,
|
||||
/// Boolean type
|
||||
decltype_boolean,
|
||||
/// Native type
|
||||
decltype_native,
|
||||
/// ASCII templated string type
|
||||
decltype_string,
|
||||
/// UTF-8 templated string type
|
||||
decltype_u8string,
|
||||
/// UTF-16 templated string type
|
||||
decltype_u16string,
|
||||
/// UTF-32 templated string type
|
||||
decltype_u32string,
|
||||
/// Wide templated string type
|
||||
decltype_wstring,
|
||||
/// Enum type
|
||||
decltype_enum,
|
||||
/// Struct type
|
||||
decltype_struct,
|
||||
/// Union type
|
||||
decltype_union,
|
||||
/// Module type
|
||||
decltype_module,
|
||||
/// Interface type (not used in declarations)
|
||||
decltype_interface,
|
||||
/// Interface type (not used in declarations)
|
||||
decltype_exception,
|
||||
/// Attribute type (not used in declarations)
|
||||
decltype_attribute,
|
||||
/// Operation type (not used in declarations)
|
||||
decltype_operation,
|
||||
/// Parameter type (only for operations)
|
||||
decltype_parameter,
|
||||
/// Enum entry type (only for enums)
|
||||
decltype_enum_entry,
|
||||
/// Case entry type (only for unions)
|
||||
decltype_case_entry,
|
||||
/// Typedef type
|
||||
decltype_typedef,
|
||||
/// Void type (only for operations)
|
||||
decltype_void,
|
||||
/// Meta data type
|
||||
decltype_meta,
|
||||
/// Pointer templated data type
|
||||
decltype_pointer,
|
||||
/// Sequence templated data type
|
||||
decltype_sequence,
|
||||
/// Map templated data type
|
||||
decltype_map,
|
||||
/// Bitset data type
|
||||
decltype_bitset,
|
||||
/// Bitfield templated data type
|
||||
decltype_bitfield,
|
||||
/// Bitmask data type
|
||||
decltype_bitmask,
|
||||
/// Any composite data type
|
||||
decltype_any,
|
||||
/// Interface ID data type
|
||||
decltype_interface_id,
|
||||
/// Interface data type
|
||||
decltype_interface_type,
|
||||
/// Exception ID data type
|
||||
decltype_exception_id,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief VSS code generator helper class.
|
||||
*/
|
||||
class CVSSHelper
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Signal definition structure (vehicle device) with a single function/value combination
|
||||
*/
|
||||
struct SFunctionVDDefinition
|
||||
{
|
||||
std::string idlType; ///< signal value type (IDL: boolean, float, uint8, ...)
|
||||
std::string functionName; ///< signal value set function name
|
||||
std::string signalName; ///< signal name
|
||||
std::string canSignalName; ///< can signal name (combination of signak messages and signal name)
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Signal definition structure (basic service) with a single function/value combination
|
||||
*/
|
||||
struct SFunctionBSDefinition
|
||||
{
|
||||
std::string idlType; ///< signal value type (IDL: boolean, float, uint8, ...)
|
||||
std::string functionName; ///< signal value set function name
|
||||
std::string signalName; ///< signal name
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Signal definition structure (vehicle device) with a single function/value combination
|
||||
*/
|
||||
struct SSignalVDDefinition
|
||||
{
|
||||
std::string vssDefinition; ///< vss interface string
|
||||
std::string className; ///< class name
|
||||
sdv::core::ESignalDirection signalDirection = sdv::core::ESignalDirection::sigdir_rx; ///< signal direction, either rx or tx
|
||||
std::vector<SFunctionVDDefinition> vecFunctions; ///< list of functions of the vss interface
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Signal definition structure (basic service) with a single function/value combination
|
||||
*/
|
||||
struct SSignalBSDefinition
|
||||
{
|
||||
std::string vssDefinition; ///< vss interface string
|
||||
std::string vssVDDefinition; ///< vss interface string
|
||||
std::string className; ///< class name
|
||||
sdv::core::ESignalDirection signalDirection = sdv::core::ESignalDirection::sigdir_rx; ///< signal direction, either rx or tx
|
||||
std::vector<SFunctionBSDefinition> vecFunctions; ///< list of functions of the vss interface
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Check if all required VD definitions are found required by the BS signals
|
||||
* @param[in] bSilent if true do not print error to console.
|
||||
* @param[in] vdSignals containing all signals definitions of the vehicle devices.
|
||||
* @param[in] bsSignals containing all signals definitions of the basic services.
|
||||
* @return Returns true on success when all definitions are found, otherwise false.
|
||||
*/
|
||||
static bool VehicleDeviceVSSDefinitionExists(bool bSilent, const std::vector<SSignalVDDefinition>& vdSignals,
|
||||
const std::vector<SSignalBSDefinition>& bsSignals);
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief Create the cmake if not exists and if content has changed
|
||||
* @param[in] filePath full path to the file
|
||||
* @param[in] cmakeContent content of the cmake file
|
||||
*/
|
||||
void CreateCMakeFile(const std::filesystem::path& filePath, const std::string& cmakeContent) const;
|
||||
|
||||
/**
|
||||
* @brief Converts the filename of a full path to lowercase
|
||||
* @param[in] fullPath full path
|
||||
* @return Returns full path but the filename is lowercase
|
||||
*/
|
||||
std::filesystem::path MakeLowercaseFilename(std::filesystem::path& fullPath) const;
|
||||
|
||||
/**
|
||||
* @brief Add multiple space characters to increase the input string to a certain size.
|
||||
* @param[in] ssInput Reference to the input string.
|
||||
* @param[in] size of the final string.
|
||||
* @return Returns the string increased by space characters.
|
||||
*/
|
||||
std::string Align(const std::string& ssInput, size_t size) const;
|
||||
|
||||
/**
|
||||
* @brief trim spaces from begin of the string and end of the string
|
||||
* @param[in] ssInput Reference to the input string to be checked.
|
||||
* @return Returns string without the spaces at front and at the end
|
||||
*/
|
||||
std::string Trim(const std::string& ssInput) const;
|
||||
|
||||
/**
|
||||
* @brief check for space characters in the string.
|
||||
* @param[in] ssInput Reference to the input string to be checked.
|
||||
* @return Returns true if string contains no space character, otherwise false.
|
||||
*/
|
||||
bool MustNotContainSpaces(const std::string& ssInput) const;
|
||||
|
||||
/**
|
||||
* @brief Get the maximal string size of all class names in the vector container.
|
||||
* @param[in] signals containing all signals definitions which have to be checked.
|
||||
* @param[in] ssTitle Reference to the title string. Is minimum of the return value.
|
||||
* @return Returns the string size of the largest class name string.
|
||||
*/
|
||||
size_t GetMaxClassName(const std::vector<SSignalVDDefinition>& signals, const std::string& ssTitle) const;
|
||||
|
||||
/**
|
||||
* @brief Get the maximal string size of all IDL type strings in the vector container.
|
||||
* @param[in] signals containing all signals definitions which have to be checked.
|
||||
* @param[in] ssTitle Reference to the title string. Is minimum of the return value.
|
||||
* @return Returns the string size of the largest IDL type string.
|
||||
*/
|
||||
size_t GetMaxIDLType(const std::vector<SSignalVDDefinition>& signals, const std::string& ssTitle) const;
|
||||
|
||||
/**
|
||||
* @brief Get the maximal string size of all ctype strings in the vector container.
|
||||
* @param[in] signals containing all signals definitions which have to be checked.
|
||||
* @param[in] ssTitle Reference to the title string. Is minimum of the return value.
|
||||
* @return Returns the string size of the largest ctype string.
|
||||
*/
|
||||
size_t GetMaxCTypeFromIDLType(const std::vector<SSignalVDDefinition>& signals, const std::string& ssTitle) const;
|
||||
|
||||
/**
|
||||
* @brief Get the maximal string size of all signal name strings in the vector container.
|
||||
* @param[in] signals containing all signals definitions which have to be checked.
|
||||
* @param[in] ssTitle Reference to the title string. Is minimum of the return value.
|
||||
* @return Returns the string size of the largest signal names string.
|
||||
*/
|
||||
size_t GetMaxSignalName(const std::vector<SSignalVDDefinition>& signals, const std::string& ssTitle) const;
|
||||
|
||||
/**
|
||||
* @brief Get the maximal string size of all CAN signal name strings in the vector container.
|
||||
* @param[in] signals containing all signals definitions which have to be checked.
|
||||
* @param[in] ssTitle Reference to the title string. Is minimum of the return value.
|
||||
* @return Returns the string size of the largest signal names string.
|
||||
*/
|
||||
size_t GetMaxCANSignalName(const std::vector<SSignalVDDefinition>& signals, const std::string& ssTitle) const;
|
||||
|
||||
/**
|
||||
* @brief Get the maximal string size of all function name strings in the vector container.
|
||||
* @param[in] signals containing all signals definitions which have to be checked.
|
||||
* @param[in] ssTitle Reference to the title string. Is minimum of the return value.
|
||||
* @return Returns the string size of the largest function names string.
|
||||
*/
|
||||
size_t GetMaxFunctionName(const std::vector<SSignalVDDefinition>& signals, const std::string& ssTitle) const;
|
||||
|
||||
/**
|
||||
* @brief Get the maximal string size of all vss strings in the vector container.
|
||||
* @param[in] signals containing all signals definitions which have to be checked.
|
||||
* @param[in] ssTitle Reference to the title string. Is minimum of the return value.
|
||||
* @return Returns the string size of the largest vss string.
|
||||
*/
|
||||
size_t GetMaxVSSDefinition(const std::vector<SSignalVDDefinition>& signals, const std::string& ssTitle) const;
|
||||
|
||||
/**
|
||||
* @brief check for '.' characters in the string.
|
||||
* @param[in] ssInput Reference to the input string to be checked.
|
||||
* @param[in] mustBeEmpty If true input string must not be empty
|
||||
* @return Returns true if string contains '.' or is empty depending on mustBeEmpty, otherwise false.
|
||||
*/
|
||||
bool MustContainDotOrIsEmpty(const std::string& ssInput, bool mustBeEmpty) const;
|
||||
|
||||
/**
|
||||
* @brief check if vss parts are string and no number. If number add '_'
|
||||
* for vehicle.chassis.axel.01.left return vehicle.chassis.axel._01.left
|
||||
* @param[in] ssInput Reference to the input string to be checked.
|
||||
* @return Returns valid vss string.
|
||||
*/
|
||||
std::string ValidateVSSFormatNumbers(const std::string& ssInput) const;
|
||||
|
||||
/**
|
||||
* @brief check if string is a number
|
||||
* @param[in] ssInput Reference to the input string to be checked.
|
||||
* @return Returns false if it is a number, otherwise true.
|
||||
*/
|
||||
bool IsNumber(const std::string& ssInput) const;
|
||||
|
||||
/**
|
||||
* @brief Returns input string or if empty, returns default string.
|
||||
* @param[in] ssInput string
|
||||
* @param[in] ssDefaultString string used as default if input string is empty
|
||||
* @param[in] index number will be added to the default string.
|
||||
* @return Returns input string or if empty returns default string added by the number.
|
||||
*/
|
||||
std::string GenerateDefaultIfEmpty(const std::string& ssInput, std::string ssDefaultString, const uint32_t& index) const;
|
||||
|
||||
/**
|
||||
* @brief Returns input string but starts and ends with "'".
|
||||
* @param[in] ssInput string
|
||||
* @return Returns the input string with "'" added at the frond and the end.
|
||||
*/
|
||||
std::string AddQuotationMarks(const std::string& ssInput) const;
|
||||
|
||||
/**
|
||||
* @brief Replaces some characters of the input string.
|
||||
* @param[in] ssInput string.
|
||||
* @param[in] from character to be replaced
|
||||
* @param[in] to replacement character.
|
||||
* @return Returns the string with replacements.
|
||||
*/
|
||||
std::string ReplaceCharacters(const std::string& ssInput, const std::string& from, const std::string& to) const;
|
||||
|
||||
/**
|
||||
* @brief turn the input string to upper case
|
||||
* @param[in] ssInput string.
|
||||
* @return Returns the input string but all characters are upper case
|
||||
*/
|
||||
std::string ToUpper(const std::string& ssInput) const;
|
||||
|
||||
/**
|
||||
* @brief remove the last part of the vss string
|
||||
* @param[in] ssInput vss string
|
||||
* @return Returns the string but removed the last part after charatcer '.'.
|
||||
*/
|
||||
std::string ShortenVSSString(const std::string& ssInput) const;
|
||||
|
||||
/**
|
||||
* @brief add to the type a cast, for example for 'std::string' it adds "const std::string&'
|
||||
* @param[in]ssSignalType the string representing the type
|
||||
* @return Returns either original string or 'const' and '&' added.
|
||||
*/
|
||||
std::string CastValueType(const std::string& ssSignalType) const;
|
||||
|
||||
/**
|
||||
* @brief find IDL type and return CType
|
||||
* @param[in] ssIDLType string representing IDL type
|
||||
* @return CType string if IDL type found, otherwise empty string
|
||||
*/
|
||||
std::string GetCTypeFromIDLType(const std::string& ssIDLType) const;
|
||||
|
||||
/**
|
||||
* @brief validate if all IDL type are valid
|
||||
* @param[in] vecTypes container of the IDL types
|
||||
* @param[in] silent information to console if not silent
|
||||
* @return True if IDL types are valid, otherwise false
|
||||
*/
|
||||
bool ValidateIDLTypes(const std::vector<std::string>& vecTypes, const bool silent) const;
|
||||
|
||||
/**
|
||||
* @brief Create folder or sub folder
|
||||
* @param[in] rootPath complete root path
|
||||
* @param[in] subfolder in case this parameter is empty only root path is created otherwise rootPath + subfolder
|
||||
* @return true if directory exists or is created successfully, otherwise false
|
||||
*/
|
||||
bool CreateFolder(const std::filesystem::path& rootPath, const std::string& subfolder) const;
|
||||
|
||||
/**
|
||||
* @brief deletes a header file
|
||||
* @param[in] path full path to a folder
|
||||
* @param[in] fileNameNoExtension a file name without the extension
|
||||
*/
|
||||
void DeleteHeaderFile(const std::filesystem::path& path, const std::string& fileNameNoExtension) const;
|
||||
|
||||
/**
|
||||
* @brief Validates the code style (signal name starts with lower case, function name upper case ...
|
||||
* @param[in] function function definition structure
|
||||
* @param[in] verbose print information to console only if true
|
||||
*/
|
||||
void ValidateVDCodeStyle(const SFunctionVDDefinition& function, const bool verbose) const;
|
||||
|
||||
/**
|
||||
* @brief Validates the code style (signal name starts with lower case, function name upper case ...
|
||||
* @param[in] function function definition structure
|
||||
* @param[in] verbose print information to console only if true
|
||||
*/
|
||||
void ValidateBSCodeStyle(const SFunctionBSDefinition& function, const bool verbose) const;
|
||||
|
||||
/**
|
||||
* @brief Validates the code style (signal name starts with lower case, function name upper case ...
|
||||
* @param[in] signal signal definition structure
|
||||
* @param[in] verbose print information to console only if true
|
||||
*/
|
||||
void ValidateVDCodeStyle(const SSignalVDDefinition& signal, const bool verbose) const;
|
||||
|
||||
/**
|
||||
* @brief Validates the code style (signal name starts with lower case, function name upper case ...
|
||||
* @param[in] signal signal definition structure
|
||||
* @param[in] verbose print information to console only if true
|
||||
*/
|
||||
void ValidateBSCodeStyle(const SSignalBSDefinition& signal, const bool verbose) const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief Declaration type name association.
|
||||
*/
|
||||
using TDeclTypeAssoc = std::pair<std::string, sdv::vss::EDeclType>;
|
||||
|
||||
/**
|
||||
* @brief change EDeclType to cType string
|
||||
* @param[in] eDeclType EDeclTyp type
|
||||
* @return Returns cType stringif available, otherwise empty string
|
||||
*/
|
||||
std::string MapDeclType2CType(const sdv::vss::EDeclType eDeclType) const;
|
||||
|
||||
/**
|
||||
* @brief Mapping between declaration type and string name.
|
||||
* @attention Some types have multiple string representatives (e.g. sdv::vss::EDeclType::decltype_short vs. 'short' and
|
||||
* 'int16').
|
||||
* @attention Based on the provided extensions on the command line, the types might be extended by: char16, char32, u8string,
|
||||
* u16string, u32string, pointer, interface_id, interface_t and exception_id
|
||||
*/
|
||||
const std::vector<TDeclTypeAssoc> m_vecDeclTypes = {
|
||||
{"short", sdv::vss::EDeclType::decltype_short},
|
||||
{"unsigned short", sdv::vss::EDeclType::decltype_unsigned_short},
|
||||
{"long", sdv::vss::EDeclType::decltype_long},
|
||||
{"unsigned long", sdv::vss::EDeclType::decltype_unsigned_long},
|
||||
{"long long", sdv::vss::EDeclType::decltype_long_long},
|
||||
{"unsigned long long", sdv::vss::EDeclType::decltype_unsigned_long_long},
|
||||
{"fixed", sdv::vss::EDeclType::decltype_fixed},
|
||||
{"float", sdv::vss::EDeclType::decltype_float},
|
||||
{"double", sdv::vss::EDeclType::decltype_double},
|
||||
{"long double", sdv::vss::EDeclType::decltype_long_double},
|
||||
{"char", sdv::vss::EDeclType::decltype_char},
|
||||
{"wchar", sdv::vss::EDeclType::decltype_wchar},
|
||||
{"int8", sdv::vss::EDeclType::decltype_char},
|
||||
{"int16", sdv::vss::EDeclType::decltype_short},
|
||||
{"int32", sdv::vss::EDeclType::decltype_long},
|
||||
{"int64", sdv::vss::EDeclType::decltype_long_long},
|
||||
{"int", sdv::vss::EDeclType::decltype_long},
|
||||
{"uint8", sdv::vss::EDeclType::decltype_octet},
|
||||
{"uint16", sdv::vss::EDeclType::decltype_unsigned_short},
|
||||
{"uint32", sdv::vss::EDeclType::decltype_unsigned_long},
|
||||
{"uint64", sdv::vss::EDeclType::decltype_unsigned_long_long},
|
||||
{"uint", sdv::vss::EDeclType::decltype_unsigned_long},
|
||||
{"boolean", sdv::vss::EDeclType::decltype_boolean},
|
||||
{"native", sdv::vss::EDeclType::decltype_native},
|
||||
{"octet", sdv::vss::EDeclType::decltype_octet},
|
||||
{"byte", sdv::vss::EDeclType::decltype_octet},
|
||||
{"string", sdv::vss::EDeclType::decltype_string},
|
||||
{"wstring", sdv::vss::EDeclType::decltype_wstring},
|
||||
{"enum", sdv::vss::EDeclType::decltype_enum},
|
||||
{"struct", sdv::vss::EDeclType::decltype_struct},
|
||||
{"union", sdv::vss::EDeclType::decltype_union},
|
||||
{"operation", sdv::vss::EDeclType::decltype_operation},
|
||||
{"attribute", sdv::vss::EDeclType::decltype_parameter},
|
||||
{"enum_entry", sdv::vss::EDeclType::decltype_enum_entry},
|
||||
{"case_entry", sdv::vss::EDeclType::decltype_case_entry},
|
||||
{"typedef", sdv::vss::EDeclType::decltype_typedef},
|
||||
{"sequence", sdv::vss::EDeclType::decltype_sequence},
|
||||
{"map", sdv::vss::EDeclType::decltype_map},
|
||||
{"bitset", sdv::vss::EDeclType::decltype_bitset},
|
||||
{"bitfield", sdv::vss::EDeclType::decltype_bitfield},
|
||||
{"bitmask", sdv::vss::EDeclType::decltype_bitmask},
|
||||
{"any", sdv::vss::EDeclType::decltype_any},
|
||||
{"void", sdv::vss::EDeclType::decltype_void},
|
||||
// Add additional types based on enabled extensions
|
||||
{"interface_id", sdv::vss::EDeclType::decltype_interface_id},
|
||||
{"interface_t", sdv::vss::EDeclType::decltype_interface_type},
|
||||
{"exception_id", sdv::vss::EDeclType::decltype_exception_id},
|
||||
{"pointer", sdv::vss::EDeclType::decltype_pointer},
|
||||
{"char16", sdv::vss::EDeclType::decltype_char16},
|
||||
{"char32", sdv::vss::EDeclType::decltype_char32},
|
||||
{"u8string", sdv::vss::EDeclType::decltype_u8string},
|
||||
{"u16string", sdv::vss::EDeclType::decltype_u16string},
|
||||
{"u32string", sdv::vss::EDeclType::decltype_u32string}
|
||||
};
|
||||
};
|
||||
|
||||
#endif // !defined VSS_HELPER_H
|
||||
248
sdv_executables/sdv_vss_util/vss_rx_templates.h
Normal file
248
sdv_executables/sdv_vss_util/vss_rx_templates.h
Normal file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* @brief file template for the RX signals (device header)
|
||||
*/
|
||||
const char szRXVehicleDeviceHeaderTemplate[] = R"code(/**
|
||||
* @file %abstract_device_h%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#ifndef %vd_safeguard%
|
||||
#define %vd_safeguard%
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/signal_support.h>
|
||||
%rx_vd_includes_list%
|
||||
#include "../signal_identifier.h"
|
||||
|
||||
/**
|
||||
* @brief Vehicle device %vss_original%
|
||||
*/
|
||||
class CVehicleDevice%class_name%
|
||||
: public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
%rx_vd_interface_list%{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
%rx_vd_interface_entry_list% END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("%vss_original%_Device")
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CVehicleDevice%class_name%();
|
||||
|
||||
/**
|
||||
* @brief initialize device to get the object name or use the default.
|
||||
* @param[in] objectConfig Configuration containing the object name
|
||||
*/
|
||||
void Initialize(const sdv::u8string& objectConfig) override;
|
||||
|
||||
/**
|
||||
* @brief Gets the current status of the object
|
||||
* @return EObjectStatus The current status of the object
|
||||
*/
|
||||
sdv::EObjectStatus GetStatus() const override;
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overlovd of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(/*in*/ sdv::EOperationMode eMode) override;
|
||||
|
||||
/**
|
||||
* @brief Shutdown function is to shutdown the execution of request thread
|
||||
*/
|
||||
void Shutdown() override;
|
||||
%rx_vd_register_events_list%
|
||||
private:
|
||||
%rx_vd_private_vd_header_part%
|
||||
std::atomic<sdv::EObjectStatus> m_status = { sdv::EObjectStatus::initialization_pending }; ///< To update the object status when it changes.
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CVehicleDevice%class_name%)
|
||||
|
||||
#endif // !define %vd_safeguard%
|
||||
)code";
|
||||
|
||||
/**
|
||||
* @brief file template for the RX signals (device cpp file)
|
||||
*/
|
||||
const char szRXVehicleDeviceClassTemplate[] = R"code(/**
|
||||
* @file %abstract_device_cpp%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "vd_%class_name_lowercase%.h"
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CVehicleDevice%class_name%::CVehicleDevice%class_name%()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initialize device to get the object name or use the default.
|
||||
* @param[in] objectConfig Configuration containing the object name
|
||||
*/
|
||||
void CVehicleDevice%class_name%::Initialize(const sdv::u8string&)
|
||||
{
|
||||
if (m_status != sdv::EObjectStatus::initialization_pending)
|
||||
{
|
||||
return;
|
||||
}
|
||||
sdv::core::CDispatchService dispatch;
|
||||
%rx_vd_subscribe_signals%
|
||||
%rx_check_subscriptions%
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the current status of the object
|
||||
* @return EObjectStatus The current status of the object
|
||||
*/
|
||||
sdv::EObjectStatus CVehicleDevice%class_name%::GetStatus() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overlovd of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void CVehicleDevice%class_name%::SetOperationMode(/*in*/ sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_status == sdv::EObjectStatus::running || m_status == sdv::EObjectStatus::initialized)
|
||||
m_status = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_status == sdv::EObjectStatus::configuring || m_status == sdv::EObjectStatus::initialized)
|
||||
m_status = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shutdown function is to shutdown the execution of request thread
|
||||
*/
|
||||
void CVehicleDevice%class_name%::Shutdown()
|
||||
{
|
||||
%rx_reset_signals%
|
||||
m_status = sdv::EObjectStatus::destruction_pending;
|
||||
}
|
||||
%rx_vd_register%
|
||||
)code";
|
||||
|
||||
/**
|
||||
* @brief file template for the RX signals (service header)
|
||||
*/
|
||||
const char szRXBasicServiceHeaderTemplate[] = R"code(/**
|
||||
* @file %basic_service_h%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#ifndef %bs_safeguard%
|
||||
#define %bs_safeguard%
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/signal_support.h>
|
||||
%rx_bs_includes_list%
|
||||
/**
|
||||
* @brief Basic Service %vss_original%
|
||||
*/
|
||||
class CBasicService%class_name%
|
||||
: public sdv::CSdvObject
|
||||
%rx_bs_interface_list%{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
%rx_bs_interface_entry_list% END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService)
|
||||
DECLARE_OBJECT_CLASS_NAME("%vss_original%_Service")
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CBasicService%class_name%();
|
||||
|
||||
/**
|
||||
* @brief User-Defined Destructor
|
||||
*/
|
||||
~CBasicService%class_name%();
|
||||
%rx_bs_register_events_list%
|
||||
private:
|
||||
%rx_bs_private_vd_header_part%
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CBasicService%class_name%)
|
||||
|
||||
#endif // !define %bs_safeguard%
|
||||
)code";
|
||||
|
||||
/**
|
||||
* @brief file template for the RX signals (service cpp file)
|
||||
*/
|
||||
const char szRXBasicServiceClassTemplate[] = R"code(/**
|
||||
* @file %basic_service_cpp%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "bs_%class_name_lowercase%.h"
|
||||
%vss_from_vd_not_found%
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CBasicService%class_name%::CBasicService%class_name%()
|
||||
{%rx_bs_constructor%}
|
||||
|
||||
/**
|
||||
* @brief User-Defined Destructor
|
||||
*/
|
||||
CBasicService%class_name%::~CBasicService%class_name%()
|
||||
{%rx_bs_deconstructor%}
|
||||
%rx_bs_getandsetfunctions%%rx_bs_register%
|
||||
)code";
|
||||
|
||||
/**
|
||||
* @brief file template for the RX signals (Vehicle Device IDL files)
|
||||
*/
|
||||
const char szVDRXIDLTemplate[] = R"code(
|
||||
/**
|
||||
* @file %_vd_idl_h%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#include "interfaces/core.idl"
|
||||
|
||||
%vss_device%
|
||||
)code";
|
||||
|
||||
/**
|
||||
* @brief file template for the RX signals (Basic Service IDL files)
|
||||
*/
|
||||
const char szBSRXIDLTemplate[] = R"code(
|
||||
/**
|
||||
* @file %_bs_idl_h%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#include "interfaces/core.idl"
|
||||
#include "%vd_idl_file%"
|
||||
%vss_device%
|
||||
%vss_service%
|
||||
)code";
|
||||
239
sdv_executables/sdv_vss_util/vss_tx_templates.h
Normal file
239
sdv_executables/sdv_vss_util/vss_tx_templates.h
Normal file
@@ -0,0 +1,239 @@
|
||||
/**
|
||||
* @brief file template for the TX signals (device header)
|
||||
*/
|
||||
const char szTXVehicleDeviceHeaderTemplate[] = R"code(/**
|
||||
* @file %abstract_device_h%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#ifndef %vd_safeguard%
|
||||
#define %vd_safeguard%
|
||||
|
||||
#include <iostream>
|
||||
#include <support/component_impl.h>
|
||||
#include <support/signal_support.h>
|
||||
%tx_vd_includes_list%
|
||||
#include "../signal_identifier.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Vehicle device %vss_shorten_no_dot%
|
||||
*/
|
||||
class CVehicleDevice%class_name%
|
||||
: public sdv::CSdvObject
|
||||
, public sdv::IObjectControl
|
||||
%tx_vd_interface_list%{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
|
||||
%tx_vd_interface_entry_list% END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
|
||||
DECLARE_OBJECT_CLASS_NAME("%vss_original%_Device")
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CVehicleDevice%class_name%();
|
||||
|
||||
/**
|
||||
* @brief initialize device to get the object name or use the default.
|
||||
* @param[in] objectConfig Configuration containing the object name
|
||||
*/
|
||||
void Initialize(const sdv::u8string& objectConfig) override;
|
||||
|
||||
/**
|
||||
* @brief Gets the current status of the object
|
||||
* @return EObjectStatus The current status of the object
|
||||
*/
|
||||
sdv::EObjectStatus GetStatus() const override;
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overlovd of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void SetOperationMode(/*in*/ sdv::EOperationMode eMode) override;
|
||||
|
||||
/**
|
||||
* @brief Shutdown function is to shutdown the execution of request thread
|
||||
*/
|
||||
void Shutdown() override;
|
||||
%tx_vd_function_list%
|
||||
private:
|
||||
%tx_variable_list%
|
||||
std::atomic<sdv::EObjectStatus> m_status = { sdv::EObjectStatus::initialization_pending }; ///< To update the object status when it changes.
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CVehicleDevice%class_name%)
|
||||
|
||||
#endif // !define %vd_safeguard%
|
||||
)code";
|
||||
|
||||
/**
|
||||
* @brief file template for the TX signals (device cpp file)
|
||||
*/
|
||||
const char szTXVehicleDeviceClassTemplate[] = R"code(/**
|
||||
* @file %abstract_device_cpp%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "vd_%class_name_lowercase%.h"
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CVehicleDevice%class_name%::CVehicleDevice%class_name%()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initialize device to get the object name or use the default.
|
||||
* @param[in] objectConfig Configuration containing the object name
|
||||
*/
|
||||
void CVehicleDevice%class_name%::Initialize(const sdv::u8string&)
|
||||
{
|
||||
if (m_status != sdv::EObjectStatus::initialization_pending)
|
||||
{
|
||||
return;
|
||||
}
|
||||
sdv::core::CDispatchService dispatch;
|
||||
%tx_variable_init_list%
|
||||
%tx_variable_check_list%
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gets the current status of the object
|
||||
* @return EObjectStatus The current status of the object
|
||||
*/
|
||||
sdv::EObjectStatus CVehicleDevice%class_name%::GetStatus() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the component operation mode. Overlovd of sdv::IObjectControl::SetOperationMode.
|
||||
* @param[in] eMode The operation mode, the component should run in.
|
||||
*/
|
||||
void CVehicleDevice%class_name%::SetOperationMode(/*in*/ sdv::EOperationMode eMode)
|
||||
{
|
||||
switch (eMode)
|
||||
{
|
||||
case sdv::EOperationMode::configuring:
|
||||
if (m_status == sdv::EObjectStatus::running || m_status == sdv::EObjectStatus::initialized)
|
||||
m_status = sdv::EObjectStatus::configuring;
|
||||
break;
|
||||
case sdv::EOperationMode::running:
|
||||
if (m_status == sdv::EObjectStatus::configuring || m_status == sdv::EObjectStatus::initialized)
|
||||
m_status = sdv::EObjectStatus::running;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shutdown function is to shutdown the execution of request thread
|
||||
*/
|
||||
void CVehicleDevice%class_name%::Shutdown()
|
||||
{
|
||||
%tx_reset_signals%
|
||||
m_status = sdv::EObjectStatus::destruction_pending;
|
||||
}
|
||||
|
||||
%tx_function_implementations%
|
||||
)code";
|
||||
|
||||
/**
|
||||
* @brief file template for the TX signals (service header)
|
||||
*/
|
||||
const char szTXBasicServiceHeaderTemplate[] = R"code(/**
|
||||
* @file %basic_service_h%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#ifndef %bs_safeguard%
|
||||
#define %bs_safeguard%
|
||||
|
||||
#include <iostream>
|
||||
#include <support/component_impl.h>
|
||||
%tx_bs_includes_list%
|
||||
/**
|
||||
* @brief basic service %class_name%
|
||||
*/
|
||||
class CBasicService%class_name%
|
||||
: public sdv::CSdvObject
|
||||
%tx_bs_interface_list%{
|
||||
public:
|
||||
|
||||
BEGIN_SDV_INTERFACE_MAP()
|
||||
SDV_INTERFACE_ENTRY(sdv::CSdvObject)
|
||||
%tx_bs_interface_entry_list% END_SDV_INTERFACE_MAP()
|
||||
|
||||
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService)
|
||||
DECLARE_OBJECT_CLASS_NAME("%vss_original%_Service")
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CBasicService%class_name%();
|
||||
%tx_bs_function_list%
|
||||
private:
|
||||
%tx_bs_variable_pointer_list%
|
||||
};
|
||||
|
||||
DEFINE_SDV_OBJECT(CBasicService%class_name%)
|
||||
|
||||
#endif // !define %bs_safeguard%
|
||||
|
||||
)code";
|
||||
|
||||
|
||||
/**
|
||||
* @brief file template for the TX signals (service cpp file)
|
||||
*/
|
||||
const char szTXBasicServiceClassTemplate[] = R"code(/**
|
||||
* @file %basic_service_cpp%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#include <iostream>
|
||||
#include "bs_%class_name_lowercase%.h"
|
||||
%vss_from_vd_not_found%
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
CBasicService%class_name%::CBasicService%class_name%()
|
||||
{%tx_bs_variable_pointer_init_list%
|
||||
SDV_LOG_TRACE("CBasicService%class_name% created.");
|
||||
}
|
||||
%vd_tx_pointer_function_implementations%
|
||||
)code";
|
||||
|
||||
/**
|
||||
* @brief file template for the TX signals (Vehicle Device IDL files)
|
||||
*/
|
||||
const char szVDTXIDLTemplate[] = R"code(/**
|
||||
* @file %_vd_idl_h%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#include <interfaces/core.idl>
|
||||
|
||||
%vss_device%
|
||||
)code";
|
||||
|
||||
/**
|
||||
* @brief file template for the TX signals (Basic service IDL files)
|
||||
*/
|
||||
const char szBSTXIDLTemplate[] = R"code(/**
|
||||
* @file %_bs_idl_h%
|
||||
* @date %creation_date%
|
||||
* %version%
|
||||
*/
|
||||
#include <interfaces/core.idl>
|
||||
|
||||
%vss_service%
|
||||
)code";
|
||||
469
sdv_executables/sdv_vss_util/vss_vd_codingrx.cpp
Normal file
469
sdv_executables/sdv_vss_util/vss_vd_codingrx.cpp
Normal file
@@ -0,0 +1,469 @@
|
||||
#include "vss_vd_codingrx.h"
|
||||
|
||||
void CVSSVDCodingRX::GetKeyWordMap(const SSignalVDDefinition& signal, CKeywordMap& mapKeywords) const
|
||||
{
|
||||
std::string vssWithColons = ReplaceCharacters(signal.vssDefinition, ".", "::");
|
||||
|
||||
//------------------------------------------------------- vehicle device header
|
||||
std::stringstream sstreamIncludesVD;
|
||||
std::string vssNoDot = ReplaceCharacters(signal.vssDefinition, ".", "");
|
||||
std::transform(vssNoDot.begin(), vssNoDot.end(), vssNoDot.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
sstreamIncludesVD << Code_VD_RXIncludes(vssNoDot);
|
||||
mapKeywords["rx_vd_includes_list"] = std::move(sstreamIncludesVD.str());
|
||||
|
||||
std::stringstream sstreamInterfaces;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamInterfaces << Code_VD_RXInterface(func.functionName, vssWithColons);
|
||||
}
|
||||
mapKeywords["rx_vd_interface_list"] = std::move(sstreamInterfaces.str());
|
||||
|
||||
std::stringstream sstreamVDInterfaceEntries;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamVDInterfaceEntries << Code_VD_RXInterfaceEntry(func.functionName, vssWithColons);
|
||||
}
|
||||
mapKeywords["rx_vd_interface_entry_list"] = std::move(sstreamVDInterfaceEntries.str());
|
||||
|
||||
std::stringstream sstreamVDRegisterEvents;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamVDRegisterEvents << Code_VD_RXReAndUnregisterEvent(vssWithColons, func);
|
||||
}
|
||||
mapKeywords["rx_vd_register_events_list"] = std::move(sstreamVDRegisterEvents.str());
|
||||
|
||||
std::stringstream sstreamPrivateVDHeaderPart;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamPrivateVDHeaderPart << Code_VD_RXPrivateHeaderPart(func, vssWithColons, signal.className);
|
||||
}
|
||||
mapKeywords["rx_vd_private_vd_header_part"] = std::move(sstreamPrivateVDHeaderPart.str());
|
||||
|
||||
//------------------------------------------------------- vehicle device cpp
|
||||
std::stringstream sstreamVDSubscribe;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamVDSubscribe << Code_VD_RXSubscribeSignal(signal.className, func);
|
||||
}
|
||||
mapKeywords["rx_vd_subscribe_signals"] = std::move(sstreamVDSubscribe.str());
|
||||
|
||||
if (signal.vecFunctions.size() > 0)
|
||||
{
|
||||
mapKeywords["rx_check_subscriptions"] = Code_VD_RXCheckSignalSubscribtions(signal.vecFunctions);
|
||||
}
|
||||
|
||||
std::stringstream sstreamVDResetSignal;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamVDResetSignal << Code_VD_RXResetSignal(func);
|
||||
}
|
||||
mapKeywords["rx_reset_signals"] = std::move(sstreamVDResetSignal.str());
|
||||
|
||||
std::stringstream sstreamVDRegister;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamVDRegister << Code_VD_RXRegister(signal.className, func, vssWithColons);
|
||||
}
|
||||
mapKeywords["rx_vd_register"] = std::move(sstreamVDRegister.str());
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingRX::Code_RXIDLDeviceList(const std::vector<std::string>& vssParts,
|
||||
const std::vector <SFunctionVDDefinition>& vecFunctions) const
|
||||
{
|
||||
std::string prefix = "Device";
|
||||
int8_t loop = 1;
|
||||
std::string nameSpace = "module vss\n{\n";
|
||||
for (auto it = vssParts.begin(); it != vssParts.end(); ++it)
|
||||
{
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop, ' ');
|
||||
nameSpace.append("module ");
|
||||
nameSpace.append(*it);
|
||||
if (it == vssParts.end() - 1)
|
||||
{
|
||||
nameSpace.append(prefix);
|
||||
}
|
||||
nameSpace.append("\n");
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop++, ' ');
|
||||
nameSpace.append("{\n");
|
||||
}
|
||||
|
||||
nameSpace.append("%interfaces%");
|
||||
loop--;
|
||||
for (size_t i = 0; i < vssParts.size() + 1; i++)
|
||||
{
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop--, ' ');
|
||||
nameSpace.append("};\n");
|
||||
}
|
||||
|
||||
std::string spaces = "";
|
||||
spaces.append(static_cast <int8_t>(4) * (vssParts.size() + 1), ' ');
|
||||
std::stringstream sstreamInterfaces;
|
||||
for (const auto& func : vecFunctions)
|
||||
{
|
||||
sstreamInterfaces << Code_RXIDLDeviceInterface(spaces, func);
|
||||
}
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["interfaces"] = std::move(sstreamInterfaces.str());
|
||||
|
||||
return ReplaceKeywords(nameSpace, mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingRX::Code_RXIDLServiceList(const std::vector<std::string>& vssParts,
|
||||
const std::vector <SFunctionVDDefinition>& vecFunctions) const
|
||||
{
|
||||
std::string vssWithColons = "";
|
||||
int8_t loop = 1;
|
||||
std::string nameSpace = "module vss\n{\n";
|
||||
for (auto it = vssParts.begin(); it != vssParts.end(); ++it)
|
||||
{
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop, ' ');
|
||||
nameSpace.append("module ");
|
||||
nameSpace.append(*it);
|
||||
if (it == vssParts.end() - 1)
|
||||
{
|
||||
nameSpace.append("Service");
|
||||
}
|
||||
nameSpace.append("\n");
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop++, ' ');
|
||||
nameSpace.append("{\n");
|
||||
vssWithColons.append("::");
|
||||
vssWithColons.append(*it);
|
||||
}
|
||||
|
||||
nameSpace.append("%interfaces%");
|
||||
loop--;
|
||||
for (size_t i = 0; i < vssParts.size() + 1; i++)
|
||||
{
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop--, ' ');
|
||||
nameSpace.append("};\n");
|
||||
}
|
||||
|
||||
std::string spaces = "";
|
||||
spaces.append(static_cast <int8_t>(4) * (vssParts.size() + 1), ' ');
|
||||
std::stringstream sstreamInterfaces;
|
||||
for (const auto& func : vecFunctions)
|
||||
{
|
||||
sstreamInterfaces << Code_RXIDLServiceInterface(spaces, vssWithColons, func);
|
||||
}
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["interfaces"] = std::move(sstreamInterfaces.str());
|
||||
|
||||
return ReplaceKeywords(nameSpace, mapKeywords);
|
||||
}
|
||||
|
||||
|
||||
std::string CVSSVDCodingRX::Code_VD_RXIncludes(const std::string& vssOriginalNoDot) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vss_original_no_dot"] = vssOriginalNoDot;
|
||||
|
||||
return ReplaceKeywords(R"code(#include "../vss_%vss_original_no_dot%_vd_rx.h")code", mapKeywords);
|
||||
}
|
||||
|
||||
|
||||
std::string CVSSVDCodingRX::Code_RXIDLDeviceInterface(const std::string& spaces, const SFunctionVDDefinition& function) const
|
||||
{
|
||||
std::string prefix = "Device";
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["value_idltype"] = function.idlType;
|
||||
mapKeywords["value_ctype"] = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["prefix"] = prefix;
|
||||
mapKeywords["multiple_spaces"] = spaces;
|
||||
return ReplaceKeywords(R"code(%multiple_spaces%/**
|
||||
%multiple_spaces%* @brief IVSS_Write%function_name% event interface
|
||||
%multiple_spaces%*/
|
||||
%multiple_spaces%interface IVSS_Write%function_name%_Event
|
||||
%multiple_spaces%{
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Write %signal_name% signal
|
||||
%multiple_spaces% * @param[in] value %signal_name%
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% void Write%function_name%(in %value_idltype% value);
|
||||
%multiple_spaces%};
|
||||
|
||||
%multiple_spaces%/**
|
||||
%multiple_spaces%* @brief IVSS_%function_name% abstract %prefix% interface
|
||||
%multiple_spaces%*/
|
||||
%multiple_spaces%interface IVSS_%function_name%
|
||||
%multiple_spaces%{
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Register Write%function_name% event on signal change
|
||||
%multiple_spaces% * Register all events and call them on signal change
|
||||
%multiple_spaces% * @param[in] event function
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% void Register%function_name%Event(in IVSS_Write%function_name%_Event event);
|
||||
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Unregister %function_name% event
|
||||
%multiple_spaces% * @param[in] event function
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% void Unregister%function_name%Event(in IVSS_Write%function_name%_Event event);
|
||||
%multiple_spaces%};
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingRX::Code_RXIDLServiceInterface(const std::string& spaces, const std::string& vssWithColons,
|
||||
const SFunctionVDDefinition& function) const
|
||||
{
|
||||
auto signalStartWithUppercase = function.signalName;
|
||||
if (!signalStartWithUppercase.empty())
|
||||
{
|
||||
signalStartWithUppercase[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(signalStartWithUppercase[0])));
|
||||
}
|
||||
|
||||
std::string prefix = "Service";
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["signal_start_with_uppercase"] = signalStartWithUppercase;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["value_idltype"] = function.idlType;
|
||||
mapKeywords["value_ctype"] = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["prefix"] = prefix;
|
||||
mapKeywords["multiple_spaces"] = spaces;
|
||||
mapKeywords["vssWithColons"] = vssWithColons;
|
||||
return ReplaceKeywords(R"code(%multiple_spaces%/**
|
||||
%multiple_spaces%* @brief IVSS_Set%function_name% event interface
|
||||
%multiple_spaces%*/
|
||||
%multiple_spaces%interface IVSS_Set%function_name%_Event
|
||||
%multiple_spaces%{
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Set %signal_name% signal
|
||||
%multiple_spaces% * @param[in] value %signal_name%
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% void Set%function_name%(in %value_idltype% value);
|
||||
%multiple_spaces%};
|
||||
|
||||
%multiple_spaces%/**
|
||||
%multiple_spaces%* @brief IVSS_Get%function_name% %prefix% interface
|
||||
%multiple_spaces%*/
|
||||
%multiple_spaces%interface IVSS_Get%function_name%
|
||||
%multiple_spaces%{
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Get %signal_name% signal
|
||||
%multiple_spaces% * @return Returns the %signal_name%
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% %value_idltype% Get%function_name%() const;
|
||||
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Register Callback on signal change
|
||||
%multiple_spaces% * @param[in] callback function
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% void RegisterOnSignalChangeOf%signal_start_with_uppercase%(in vss%vssWithColons%Service::IVSS_Set%function_name%_Event callback);
|
||||
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Unregister Callback
|
||||
%multiple_spaces% * @param[in] callback function
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% void UnregisterOnSignalChangeOf%signal_start_with_uppercase%(in vss%vssWithColons%Service::IVSS_Set%function_name%_Event callback);
|
||||
%multiple_spaces%};
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingRX::Code_VD_RXInterface(const std::string & functionName, const std::string& vssShortenWithColons) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = functionName;
|
||||
mapKeywords["vss_shorten_with_colons"] = vssShortenWithColons;
|
||||
|
||||
return ReplaceKeywords(R"code( , public vss::%vss_shorten_with_colons%Device::IVSS_%function_name%
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingRX::Code_VD_RXInterfaceEntry(const std::string& functionName, const std::string& vssWithColons) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = functionName;
|
||||
mapKeywords["vssWithColons"] = vssWithColons;
|
||||
|
||||
return ReplaceKeywords(R"code( SDV_INTERFACE_ENTRY(vss::%vssWithColons%Device::IVSS_%function_name%)
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingRX::Code_VD_RXReAndUnregisterEvent( const std::string& vssWithColons, const SFunctionVDDefinition& function) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vssWithColons"] = vssWithColons;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
/**
|
||||
* @brief Register IVSS_Write%function_name%_Event on signal change
|
||||
* Collect all events and call them on signal change
|
||||
* @param[in] event function
|
||||
*/
|
||||
void Register%function_name%Event(vss::%vssWithColons%Device::IVSS_Write%function_name%_Event* event) override;
|
||||
|
||||
/**
|
||||
* @brief Unregister IVSS_%function_name%_Event
|
||||
* @param[in] event function
|
||||
*/
|
||||
void Unregister%function_name%Event(vss::%vssWithColons%Device::IVSS_Write%function_name%_Event* event) override;
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingRX::Code_VD_RXPrivateHeaderPart(const SFunctionVDDefinition& function,
|
||||
const std::string& vssWithColons, const std::string& class_name) const
|
||||
{
|
||||
auto startWithUppercase = function.signalName;
|
||||
if (!startWithUppercase.empty())
|
||||
{
|
||||
startWithUppercase[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(startWithUppercase[0])));
|
||||
}
|
||||
|
||||
std::string class_name_lowercase = class_name;
|
||||
std::transform(class_name_lowercase.begin(), class_name_lowercase.end(), class_name_lowercase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["vssWithColons"] = vssWithColons;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["start_with_uppercase"] = startWithUppercase;
|
||||
mapKeywords["class_name"] = class_name;
|
||||
mapKeywords["class_name_lowercase"] = class_name_lowercase;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
/**
|
||||
* @brief Execute all callbacks
|
||||
*/
|
||||
void ExecuteAllCallBacksFor%start_with_uppercase%(sdv::any_t value);
|
||||
|
||||
sdv::core::CSignal m_%signal_name%Signal; ///< Signal of the vehicle device
|
||||
mutable std::mutex m_%signal_name%MutexCallbacks; ///< Mutex protecting m_%signal_name%Callbacks
|
||||
std::set<vss::%vssWithColons%Device::IVSS_Write%function_name%_Event*> m_%signal_name%Callbacks; ///< collection of events to be called
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingRX::Code_VD_RXSubscribeSignal(const std::string& class_name, const SFunctionVDDefinition& function) const
|
||||
{
|
||||
auto startWithUppercase = function.signalName;
|
||||
if (!startWithUppercase.empty())
|
||||
{
|
||||
startWithUppercase[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(startWithUppercase[0])));
|
||||
}
|
||||
|
||||
std::string class_name_lowercase = class_name;
|
||||
std::transform(class_name_lowercase.begin(), class_name_lowercase.end(), class_name_lowercase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["object_prefix"] = m_ssPrefix;
|
||||
mapKeywords["start_with_uppercase"] = startWithUppercase;
|
||||
mapKeywords["class_name"] = class_name;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["class_name_lowercase"] = class_name_lowercase;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
m_%signal_name%Signal = dispatch.Subscribe(%object_prefix%::ds%start_with_uppercase%, [&](sdv::any_t value) { ExecuteAllCallBacksFor%start_with_uppercase%( value ); });
|
||||
if (!m_%signal_name%Signal)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get signal: ", %object_prefix%::ds%start_with_uppercase%, " [CVehicleDevice%class_name%]");
|
||||
}
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingRX::Code_VD_RXCheckSignalSubscribtions(const std::vector <SFunctionVDDefinition>& vecFunctions) const
|
||||
{
|
||||
uint32_t count{ 0 };
|
||||
std::stringstream sstreamFunctions;
|
||||
sstreamFunctions << " if (!";
|
||||
for (const auto& func : vecFunctions)
|
||||
{
|
||||
count++;
|
||||
sstreamFunctions << "m_" << func.signalName << "Signal";
|
||||
if (count != vecFunctions.size())
|
||||
{
|
||||
sstreamFunctions << " || !";
|
||||
}
|
||||
}
|
||||
sstreamFunctions << ")" << std::endl;
|
||||
sstreamFunctions << " {" << std::endl;
|
||||
sstreamFunctions << " m_status = sdv::EObjectStatus::initialization_failure;" << std::endl;
|
||||
sstreamFunctions << " return;" << std::endl;
|
||||
sstreamFunctions << " }" << std::endl;
|
||||
sstreamFunctions << " m_status = sdv::EObjectStatus::initialized;";
|
||||
|
||||
return sstreamFunctions.str();
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingRX::Code_VD_RXResetSignal(const SFunctionVDDefinition& function) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
|
||||
return ReplaceKeywords(R"code( m_%signal_name%Signal.Reset();
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingRX::Code_VD_RXRegister( const std::string& class_name, const SFunctionVDDefinition& function,
|
||||
const std::string& vssWithColons) const
|
||||
{
|
||||
auto startWithUppercase = function.signalName;
|
||||
if (!startWithUppercase.empty())
|
||||
{
|
||||
startWithUppercase[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(startWithUppercase[0])));
|
||||
}
|
||||
std::string class_name_lowercase = class_name;
|
||||
std::transform(class_name_lowercase.begin(), class_name_lowercase.end(), class_name_lowercase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vssWithColons"] = vssWithColons;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["start_with_uppercase"] = startWithUppercase;
|
||||
mapKeywords["class_name"] = class_name;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["value_ctype"] = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["class_name_lowercase"] = class_name_lowercase;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
/**
|
||||
* @brief Register %function_name% event on signal change
|
||||
* Collect all events and call them on signal change
|
||||
* @param[in] event function
|
||||
*/
|
||||
void CVehicleDevice%class_name%::Register%function_name%Event(vss::%vssWithColons%Device::IVSS_Write%function_name%_Event* event)
|
||||
{
|
||||
if (event)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_%signal_name%MutexCallbacks);
|
||||
m_%signal_name%Callbacks.insert(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister %function_name% event
|
||||
* @param[in] event function
|
||||
*/
|
||||
void CVehicleDevice%class_name%::Unregister%function_name%Event(vss::%vssWithColons%Device::IVSS_Write%function_name%_Event* event)
|
||||
{
|
||||
if (event)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_%signal_name%MutexCallbacks);
|
||||
m_%signal_name%Callbacks.erase(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Execute all callbacks
|
||||
*/
|
||||
void CVehicleDevice%class_name%::ExecuteAllCallBacksFor%start_with_uppercase%(sdv::any_t value)
|
||||
{
|
||||
%value_ctype% %signal_name% = value.get<%value_ctype%>();
|
||||
|
||||
//
|
||||
// TODO:
|
||||
// Convert vehicle specific value to abstract unit/range
|
||||
//
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_%signal_name%MutexCallbacks);
|
||||
for (const auto& callback : m_%signal_name%Callbacks)
|
||||
{
|
||||
callback->Write%function_name%(%signal_name%);
|
||||
}
|
||||
}
|
||||
)code", mapKeywords);
|
||||
}
|
||||
150
sdv_executables/sdv_vss_util/vss_vd_codingrx.h
Normal file
150
sdv_executables/sdv_vss_util/vss_vd_codingrx.h
Normal file
@@ -0,0 +1,150 @@
|
||||
#ifndef VSS_VD_CODING_RX_H
|
||||
#define VSS_VD_CODING_RX_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <interfaces/dispatch.h>
|
||||
|
||||
#include "codegen_base.h"
|
||||
#include "vss_helper.h"
|
||||
#include "vss_rx_templates.h"
|
||||
#include "vss_coding.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief VSS code generator coding class for vehicle devices.
|
||||
* Creates the code out of templates
|
||||
*/
|
||||
class CVSSVDCodingRX : public CCodeGeneratorBase, CVSSHelper
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] rsPrefix used by cmake library and signal definition in signal_identifier.h file
|
||||
*/
|
||||
CVSSVDCodingRX(const std::string& rsPrefix) : m_ssPrefix(rsPrefix) {}
|
||||
|
||||
/**
|
||||
* @brief create device content for the IDL file of a RX signal
|
||||
* @param[in] vssParts Interface in vss style separated in parts
|
||||
* @param[in] vecFunctions container of all functions of a single vss definition
|
||||
* @return content of the Device part of a IDL Interface of a RX signal
|
||||
*/
|
||||
std::string Code_RXIDLDeviceList(const std::vector<std::string>& vssParts, const std::vector <SFunctionVDDefinition>& vecFunctions) const;
|
||||
|
||||
/**
|
||||
* @brief create service content for the IDL file of a RX signal
|
||||
* @param[in] vssParts Interface in vss style separated in parts
|
||||
* @param[in] vecFunctions container of all functions of a single vss definition
|
||||
* @return content of the Device part of a IDL Interface of a RX signal
|
||||
*/
|
||||
std::string Code_RXIDLServiceList(const std::vector<std::string>& vssParts, const std::vector <SFunctionVDDefinition>& vecFunctions) const;
|
||||
|
||||
/**
|
||||
* @brief fill the KeyWordMap with all required strings
|
||||
* @param[in] signal signal definition structure to fill the KeyWordMap
|
||||
* @param[in] mapKeywords KeyWordMap to be filled
|
||||
*/
|
||||
void GetKeyWordMap(const SSignalVDDefinition& signal, CKeywordMap& mapKeywords) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief create single or multiple lines containing include files
|
||||
* @param[in] vssOriginalNoDot vss string without points e.g. VehicleChassisSteeringWheelAngle
|
||||
* @return content of a single interface
|
||||
*/
|
||||
std::string Code_VD_RXIncludes(const std::string& vssOriginalNoDot) const;
|
||||
|
||||
/**
|
||||
* @brief create a single line containing a interface
|
||||
* @param[in] functionName function which is part of the interface
|
||||
* @param[in] vssShortenWithColons vss string (short version) with colons as separator
|
||||
* @return content of a single interface
|
||||
*/
|
||||
std::string Code_VD_RXInterface(const std::string& functionName, const std::string& vssShortenWithColons) const;
|
||||
|
||||
/**
|
||||
* @brief create a single line containing a interface entry
|
||||
* @param[in] functionName function which is part of the interface
|
||||
* @param[in] vssWithColons vss string (complete version) with colons as separator
|
||||
* @return content of a single interface entry
|
||||
*/
|
||||
std::string Code_VD_RXInterfaceEntry(const std::string& functionName, const std::string& vssWithColons) const;
|
||||
|
||||
/**
|
||||
* @brief Get the register and unregister part for the RX VD header
|
||||
* @param[in] vssWithColons vss string (complete version) with colons as separator
|
||||
* @param[in] function function definition structure
|
||||
* @return content of a single register and unregister part.
|
||||
*/
|
||||
std::string Code_VD_RXReAndUnregisterEvent(const std::string& vssWithColons, const SFunctionVDDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief Get the private header part of the vehicle device header
|
||||
* @param[in] function function definition structure
|
||||
* @param[in] vssWithColons vss string (complete version) with colons as separator
|
||||
* @param[in] class_name class name which is part of the interface
|
||||
* @return content of private header part of the vehicle device header
|
||||
*/
|
||||
std::string Code_VD_RXPrivateHeaderPart(const SFunctionVDDefinition& function, const std::string& vssWithColons,
|
||||
const std::string& class_name) const;
|
||||
|
||||
/**
|
||||
* @brief create device content for the IDL file of a RX signal
|
||||
* @param[in] spaces string containing only space characters for aligning
|
||||
* @param[in] function function definition structure
|
||||
* @return content of the Device part of a IDL Interface of a RX signal
|
||||
*/
|
||||
std::string Code_RXIDLDeviceInterface(const std::string& spaces, const SFunctionVDDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief create service content for the IDL file of a RX signal
|
||||
* @param[in] spaces string containing only space characters for aligning
|
||||
* @param[in] vssWithColons vss string (complete version) with colons as separator
|
||||
* @param[in] function function definition structure
|
||||
* @return content of the Device part of a IDL Interface of a RX signal
|
||||
*/
|
||||
std::string Code_RXIDLServiceInterface(const std::string& spaces, const std::string& vssWithColons,
|
||||
const SFunctionVDDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief subscribe signals (RX type) for vehicle device
|
||||
* @param[in] class_name class name which is part of the interface
|
||||
* @param[in] function function definition structure
|
||||
* @return content of a initializing code
|
||||
*/
|
||||
std::string Code_VD_RXSubscribeSignal(const std::string& class_name, const SFunctionVDDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief subscribe signals (RX type) for vehicle device
|
||||
* @param[in] vecFunctions list of functions of the vss interface
|
||||
* @return content of a initializing code
|
||||
*/
|
||||
std::string Code_VD_RXCheckSignalSubscribtions(const std::vector <SFunctionVDDefinition>& vecFunctions) const;
|
||||
|
||||
/**
|
||||
* @brief Rest signal (RX signals) for vehicle device cpp file
|
||||
* @param[in] function function definition structure
|
||||
* @return content of a single signal reset implementation
|
||||
*/
|
||||
std::string Code_VD_RXResetSignal(const SFunctionVDDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief create register/unregister and callback function code for vehicle device
|
||||
* @param[in] class_name class name which is part of the interface
|
||||
* @param[in] function function definition structure
|
||||
* @param[in] vssWithColons vss string with colons as separator
|
||||
* @return content of a single signal register/unregister and callback code
|
||||
*/
|
||||
std::string Code_VD_RXRegister(const std::string& class_name, const SFunctionVDDefinition& function,
|
||||
const std::string& vssWithColons) const;
|
||||
|
||||
std::string m_ssPrefix; ///< prefix, used by cmake library and signal definition in signal_identifier.h file.
|
||||
};
|
||||
|
||||
#endif // !defined VSS_VD_CODING_RX_H
|
||||
|
||||
286
sdv_executables/sdv_vss_util/vss_vd_codingtx.cpp
Normal file
286
sdv_executables/sdv_vss_util/vss_vd_codingtx.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
#include "vss_vd_codingtx.h"
|
||||
|
||||
void CVSSVDCodingTX::GetKeyWordMap(const SSignalVDDefinition& signal, CKeywordMap& mapKeywords) const
|
||||
{
|
||||
std::string vssWithColons = ReplaceCharacters(signal.vssDefinition, ".", "::");
|
||||
|
||||
//------------------------------------------------------- vehicle device header
|
||||
std::stringstream sstreamIncludesVD;
|
||||
std::string vssNoDot = ReplaceCharacters(signal.vssDefinition, ".", "");
|
||||
std::transform(vssNoDot.begin(), vssNoDot.end(), vssNoDot.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
sstreamIncludesVD << Code_VD_TXIncludes(vssNoDot);
|
||||
mapKeywords["tx_vd_includes_list"] = std::move(sstreamIncludesVD.str());
|
||||
|
||||
std::stringstream sstreamInterfacesVD;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamInterfacesVD << Code_VD_TXInterface(func.functionName, vssWithColons);
|
||||
}
|
||||
mapKeywords["tx_vd_interface_list"] = std::move(sstreamInterfacesVD.str());
|
||||
|
||||
std::stringstream sstreamInterfaceEntriesVD;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamInterfaceEntriesVD << Code_VD_TXInterfaceEntry(func.functionName, vssWithColons);
|
||||
}
|
||||
mapKeywords["tx_vd_interface_entry_list"] = std::move(sstreamInterfaceEntriesVD.str());
|
||||
|
||||
std::stringstream sstreamFunctionsVD;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamFunctionsVD << Code_VD_TXFunction(func);
|
||||
}
|
||||
mapKeywords["tx_vd_function_list"] = std::move(sstreamFunctionsVD.str());
|
||||
|
||||
std::stringstream sstreamVariables;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamVariables << Code_VD_TXVariable(func.signalName);
|
||||
}
|
||||
mapKeywords["tx_variable_list"] = std::move(sstreamVariables.str());
|
||||
|
||||
//------------------------------------------------------- vehicle device cpp
|
||||
std::stringstream sstreamVariableInitializations;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamVariableInitializations << Code_VD_TXVariableInitialization(func);
|
||||
}
|
||||
mapKeywords["tx_variable_init_list"] = std::move(sstreamVariableInitializations.str());
|
||||
|
||||
if (signal.vecFunctions.size() > 0)
|
||||
{
|
||||
mapKeywords["tx_variable_check_list"] = Code_VD_TXVariableCheckInitialization(signal.vecFunctions);
|
||||
}
|
||||
|
||||
std::stringstream sstreamResetSignal;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamResetSignal << Code_VD_TXResetSignal(func);
|
||||
}
|
||||
mapKeywords["tx_reset_signals"] = std::move(sstreamResetSignal.str());
|
||||
|
||||
std::stringstream sstreamFunctionImplementation;
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstreamFunctionImplementation << Code_VD_TXFunctionImplementation(func, signal.className);
|
||||
}
|
||||
mapKeywords["tx_function_implementations"] = std::move(sstreamFunctionImplementation.str());
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingTX::Code_VD_TXIDLList(const std::vector<std::string>& vssParts,
|
||||
const std::vector <SFunctionVDDefinition>& vecFunctions) const
|
||||
{
|
||||
int8_t loop = 1;
|
||||
std::string nameSpace = "module vss\n{\n";
|
||||
for (auto it = vssParts.begin(); it != vssParts.end(); ++it)
|
||||
{
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop, ' ');
|
||||
nameSpace.append("module ");
|
||||
nameSpace.append(*it);
|
||||
if (it == vssParts.end() - 1)
|
||||
{
|
||||
nameSpace.append("Device");
|
||||
}
|
||||
nameSpace.append("\n");
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop++, ' ');
|
||||
nameSpace.append("{\n");
|
||||
}
|
||||
|
||||
nameSpace.append("%interfaces%");
|
||||
loop--;
|
||||
for (size_t i = 0; i < vssParts.size() + 1; i++)
|
||||
{
|
||||
nameSpace.append(static_cast <int8_t>(4) * loop--, ' ');
|
||||
nameSpace.append("};\n");
|
||||
}
|
||||
|
||||
bool newLine = false;
|
||||
std::string spaces = "";
|
||||
spaces.append(static_cast <int8_t>(4) * (vssParts.size() + 1), ' ');
|
||||
std::stringstream sstreamInterfaces;
|
||||
for (auto func : vecFunctions)
|
||||
{
|
||||
if (newLine)
|
||||
sstreamInterfaces << "\n\n";
|
||||
else
|
||||
newLine = true;
|
||||
sstreamInterfaces << Code_VD_TXIDLInterface(spaces, func);
|
||||
}
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["interfaces"] = std::move(sstreamInterfaces.str());
|
||||
|
||||
return ReplaceKeywords(nameSpace, mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingTX::Code_VD_TXIncludes(const std::string& vssOriginalNoDot) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["vss_original_no_dot"] = vssOriginalNoDot;
|
||||
|
||||
return ReplaceKeywords(R"code(#include "../vss_%vss_original_no_dot%_vd_tx.h")code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingTX::Code_VD_TXInterface(const std::string& functionName, const std::string& vssWithColons) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = functionName;
|
||||
mapKeywords["vss_with_colons"] = vssWithColons;
|
||||
|
||||
return ReplaceKeywords(R"code( , public vss::%vss_with_colons%Device::IVSS_Write%function_name%
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingTX::Code_VD_TXInterfaceEntry(const std::string& functionName, const std::string& vssWithColons) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = functionName;
|
||||
mapKeywords["vss_with_colons"] = vssWithColons;
|
||||
|
||||
return ReplaceKeywords(R"code( SDV_INTERFACE_ENTRY(vss::%vss_with_colons%Device::IVSS_Write%function_name%)
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingTX::Code_VD_TXIDLInterface(const std::string& spaces, const SFunctionVDDefinition& function) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["value_idltype"] = function.idlType;
|
||||
mapKeywords["value_ctype"] = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["multiple_spaces"] = spaces;
|
||||
|
||||
return ReplaceKeywords(R"code(%multiple_spaces%/**
|
||||
%multiple_spaces%* @brief IVSS_Write%function_name% Device interface
|
||||
%multiple_spaces%*/
|
||||
%multiple_spaces%interface IVSS_Write%function_name%
|
||||
%multiple_spaces%{
|
||||
%multiple_spaces% /**
|
||||
%multiple_spaces% * @brief Write %signal_name% signal
|
||||
%multiple_spaces% * @param[in] value
|
||||
%multiple_spaces% * @return true on success otherwise false
|
||||
%multiple_spaces% */
|
||||
%multiple_spaces% boolean Write%function_name%(in %value_idltype% value);
|
||||
%multiple_spaces%};
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingTX::Code_VD_TXFunction(const SFunctionVDDefinition& function) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["value_idltype"] = function.idlType;
|
||||
auto signalType = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["value_ctype"] = CastValueType(signalType);
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
/**
|
||||
* @brief Set %signal_name% signal
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool Write%function_name%(%value_ctype% value) override;
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingTX::Code_VD_TXResetSignal(const SFunctionVDDefinition& function) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
|
||||
return ReplaceKeywords(R"code( m_%signal_name%.Reset();
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingTX::Code_VD_TXFunctionImplementation(const SFunctionVDDefinition& function, const std::string& className) const
|
||||
{
|
||||
std::string class_name_lowercase = className;
|
||||
std::transform(class_name_lowercase.begin(), class_name_lowercase.end(), class_name_lowercase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["function_name"] = function.functionName;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["class_name"] = className;
|
||||
auto signalType = GetCTypeFromIDLType(function.idlType);
|
||||
mapKeywords["value_ctype"] = CastValueType(signalType);
|
||||
mapKeywords["class_name_lowercase"] = class_name_lowercase;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
/**
|
||||
* @brief %function_name%
|
||||
* @param[in] value
|
||||
* @return true on success otherwise false
|
||||
*/
|
||||
bool CVehicleDevice%class_name%::Write%function_name%(%value_ctype% value)
|
||||
{
|
||||
if (m_%signal_name%)
|
||||
{
|
||||
//
|
||||
// TODO:
|
||||
// Convert abstract value to vehicle specific unit/range
|
||||
//
|
||||
|
||||
m_%signal_name%.Write(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingTX::Code_VD_TXVariable(const std::string& signalName) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
mapKeywords["signal_name"] = signalName;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
sdv::core::CSignal m_%signal_name%; ///< %signal_name% signal)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingTX::Code_VD_TXVariableInitialization(const SFunctionVDDefinition& function) const
|
||||
{
|
||||
CKeywordMap mapKeywords;
|
||||
auto startWithUppercase = function.signalName;
|
||||
if (!startWithUppercase.empty())
|
||||
{
|
||||
startWithUppercase[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(startWithUppercase[0])));
|
||||
}
|
||||
mapKeywords["start_with_uppercase"] = startWithUppercase;
|
||||
mapKeywords["signal_name"] = function.signalName;
|
||||
mapKeywords["object_prefix"] = m_ssPrefix;
|
||||
|
||||
return ReplaceKeywords(R"code(
|
||||
m_%signal_name% = dispatch.AddPublisher(%object_prefix%::ds%start_with_uppercase%);
|
||||
if (!m_%signal_name%)
|
||||
{
|
||||
SDV_LOG_ERROR("Could not get signal: ", %object_prefix%::ds%start_with_uppercase%, " [CVehicleDevice%class_name%]");
|
||||
}
|
||||
)code", mapKeywords);
|
||||
}
|
||||
|
||||
std::string CVSSVDCodingTX::Code_VD_TXVariableCheckInitialization(const std::vector <SFunctionVDDefinition>& vecFunctions) const
|
||||
{
|
||||
uint32_t count { 0 };
|
||||
std::stringstream sstreamFunctions;
|
||||
sstreamFunctions << " if (!";
|
||||
for (auto func : vecFunctions)
|
||||
{
|
||||
count++;
|
||||
sstreamFunctions << "m_" << func.signalName;
|
||||
if (count != vecFunctions.size())
|
||||
{
|
||||
sstreamFunctions << " || !";
|
||||
}
|
||||
}
|
||||
sstreamFunctions << ")" << std::endl;
|
||||
sstreamFunctions << " {" << std::endl;
|
||||
sstreamFunctions << " m_status = sdv::EObjectStatus::initialization_failure;" << std::endl;
|
||||
sstreamFunctions << " return;" << std::endl;
|
||||
sstreamFunctions << " }" << std::endl;
|
||||
sstreamFunctions << " m_status = sdv::EObjectStatus::initialized;";
|
||||
|
||||
return sstreamFunctions.str();
|
||||
}
|
||||
125
sdv_executables/sdv_vss_util/vss_vd_codingtx.h
Normal file
125
sdv_executables/sdv_vss_util/vss_vd_codingtx.h
Normal file
@@ -0,0 +1,125 @@
|
||||
#ifndef VSS_CODING_TX_H
|
||||
#define VSS_CODING_TX_H
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <interfaces/dispatch.h>
|
||||
|
||||
#include "codegen_base.h"
|
||||
#include "vss_helper.h"
|
||||
#include "vss_tx_templates.h"
|
||||
#include "vss_coding.h"
|
||||
|
||||
/**
|
||||
* @brief VSS code generator coding class.
|
||||
* Creates the code out of templates
|
||||
*/
|
||||
class CVSSVDCodingTX : public CCodeGeneratorBase, CVSSHelper
|
||||
{
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] rsPrefix used by cmake library and signal definition in signal_identifier.h file
|
||||
*/
|
||||
CVSSVDCodingTX(const std::string& rsPrefix) : m_ssPrefix(rsPrefix) {}
|
||||
|
||||
/**
|
||||
* @brief create vehicle device content for the IDL file of a TX signal
|
||||
* @param[in] vssParts Interface in vss style separated in parts
|
||||
* @param[in] vecFunctions container of all functions of a single vss definition
|
||||
* @return content of the vehicle device part of a IDL Interface of a TX signal
|
||||
*/
|
||||
std::string Code_VD_TXIDLList(const std::vector<std::string>& vssParts,
|
||||
const std::vector <SFunctionVDDefinition>& vecFunctions) const;
|
||||
|
||||
/**
|
||||
* @brief fill the KeyWordMap with all required strings
|
||||
* @param[in] signal signal definition structure to fill the KeyWordMap
|
||||
* @param[in] mapKeywords KeyWordMap to be filled
|
||||
*/
|
||||
void GetKeyWordMap(const SSignalVDDefinition& signal, CKeywordMap& mapKeywords) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief create single or multiple lines containing include files
|
||||
* @param[in] vssOriginalNoDot vss string without points e.g. VehicleChassisSteeringWheelAngle
|
||||
* @return content of a single interface
|
||||
*/
|
||||
std::string Code_VD_TXIncludes(const std::string& vssOriginalNoDot) const;
|
||||
|
||||
/**
|
||||
* @brief create a single line containing a interface for vehicle device
|
||||
* @param[in] functionName function which is part of the interface
|
||||
* @param[in] vssWithColons vss string (complete version) with colons as separator
|
||||
* @return content of a single interface
|
||||
*/
|
||||
std::string Code_VD_TXInterface(const std::string& functionName, const std::string& vssWithColons) const;
|
||||
|
||||
/**
|
||||
* @brief create a single line containing a interface entry for vehicle device
|
||||
* @param[in] functionName function which is part of the interface
|
||||
* @param[in] vssWithColons vss string (complete version) with colons as separator
|
||||
* @return content of a single interface entry
|
||||
*/
|
||||
std::string Code_VD_TXInterfaceEntry(const std::string& functionName, const std::string& vssWithColons) const;
|
||||
|
||||
/**
|
||||
* @brief create list of interfaces (TX signals) for IDL file (Vehicle Device)
|
||||
* @param[in] spaces string containing only space characters for aligning
|
||||
* @param[in] function function definition structure
|
||||
* @return content of a single interface entry
|
||||
*/
|
||||
std::string Code_VD_TXIDLInterface(const std::string& spaces, const SFunctionVDDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief create function definition part (TX signals) for vehicle device
|
||||
* @param[in] function function definition structure
|
||||
* @return content of a single function declaration
|
||||
*/
|
||||
std::string Code_VD_TXFunction(const SFunctionVDDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief Rest signal (TX signals) for vehicle device cpp file
|
||||
* @param[in] function function definition structure
|
||||
* @return content of a single signal reset implementation
|
||||
*/
|
||||
std::string Code_VD_TXResetSignal(const SFunctionVDDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief create function implementation part (TX signals) for vehicle device cpp file
|
||||
* @param[in] function function definition structure
|
||||
* @param[in] className class name of the signal
|
||||
* @return content of a single function implementation
|
||||
*/
|
||||
std::string Code_VD_TXFunctionImplementation(const SFunctionVDDefinition& function, const std::string& className) const;
|
||||
|
||||
/**
|
||||
* @brief create single variable definition (TX signals) for vehicle device header
|
||||
* @param[in] signalName name of the signal
|
||||
* @return content of a single variable definition
|
||||
*/
|
||||
std::string Code_VD_TXVariable(const std::string& signalName) const;
|
||||
|
||||
/**
|
||||
* @brief create single variable initialization (TX signals) for vehicle device cpp file
|
||||
* @param[in] function which is part of the interface
|
||||
* @return content of a single variable initialization
|
||||
*/
|
||||
std::string Code_VD_TXVariableInitialization(const SFunctionVDDefinition& function) const;
|
||||
|
||||
/**
|
||||
* @brief create check if all interfaces are valid (TX signals) for vehicle device cpp file
|
||||
* @param[in] vecFunctions container of all functions of a single vss definition
|
||||
* @return content to check if all interfaces are valid
|
||||
*/
|
||||
std::string Code_VD_TXVariableCheckInitialization(const std::vector <SFunctionVDDefinition>& vecFunctions) const;
|
||||
|
||||
std::string m_ssPrefix; ///< prefix, used by cmake library and signal definition in signal_identifier.h file.
|
||||
};
|
||||
|
||||
#endif // !defined VSS_CODING_TX_H
|
||||
|
||||
287
sdv_executables/sdv_vss_util/vss_vd_generator.cpp
Normal file
287
sdv_executables/sdv_vss_util/vss_vd_generator.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
#include "vss_vd_generator.h"
|
||||
#include "vss_coding.h"
|
||||
#include "vss_vd_codingrx.h"
|
||||
#include "vss_vd_codingtx.h"
|
||||
|
||||
|
||||
bool CVSSVDGenerator::GeneratedCode()
|
||||
{
|
||||
// Create project directory
|
||||
if (!m_pathProject.empty())
|
||||
{
|
||||
m_pathProject /= "vss_files";
|
||||
if (CreateFolder(m_pathProject, ""))
|
||||
{
|
||||
std::filesystem::path pathSummary = m_pathProject / "summary.txt";
|
||||
std::filesystem::path pathSignalIds = m_pathProject / "signal_identifier.h";
|
||||
|
||||
CVSSCodingCommon coding(m_ssPrefix);
|
||||
CreateFiles(m_ssVersion);
|
||||
|
||||
std::ofstream fstreamSummary; ///< Build description summery.txt file
|
||||
fstreamSummary.open(pathSummary, std::ios::out | std::ios::trunc);
|
||||
fstreamSummary << SummaryTextFile();
|
||||
fstreamSummary.close();
|
||||
|
||||
std::ofstream fstreamSignalIds; ///< Build description SignalIdetifier.h file
|
||||
fstreamSignalIds.open(pathSignalIds, std::ios::out | std::ios::trunc);
|
||||
fstreamSignalIds << coding.Code_SignalIdentifier(m_signals, pathSignalIds.filename().generic_u8string(), m_ssVersion);
|
||||
fstreamSignalIds.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string CVSSVDGenerator::SummaryTextFile() const
|
||||
{
|
||||
//std::string titlePrefix ="Object prefix";
|
||||
std::string titleClassName = "Class name";
|
||||
std::string titleSignalName = "Signal name";
|
||||
std::string titleCANSignalName = "CAN Signal name";
|
||||
std::string titleFunctionname = "Function name";
|
||||
std::string titleIDLType = "IDL-Type";
|
||||
std::string titleCType = "C-Type";
|
||||
std::string titleVSS = "vss Definition";
|
||||
bool addTitle = true;
|
||||
std::stringstream sstream;
|
||||
for (const auto& signal : m_signals)
|
||||
{
|
||||
if (addTitle)
|
||||
{
|
||||
addTitle = false;
|
||||
sstream << "\n";
|
||||
sstream << Align(titleClassName, GetMaxClassName(m_signals, titleClassName)) << "\t";
|
||||
sstream << Align(titleSignalName, GetMaxSignalName(m_signals, titleSignalName)) << "\t";
|
||||
sstream << Align(titleCANSignalName, GetMaxCANSignalName(m_signals, titleCANSignalName)) << "\t";
|
||||
sstream << Align(titleFunctionname, GetMaxFunctionName(m_signals, titleFunctionname)) << "\t";
|
||||
sstream << Align("RX/TX ", 6) << "\t";
|
||||
sstream << Align(titleIDLType, GetMaxIDLType(m_signals, titleIDLType)) << "\t";
|
||||
sstream << Align(titleCType, GetMaxCTypeFromIDLType(m_signals, titleCType)) << "\t";
|
||||
sstream << Align(titleVSS, GetMaxVSSDefinition(m_signals, titleVSS)) << "\t";
|
||||
sstream << "\n\n";
|
||||
}
|
||||
for (const auto& func : signal.vecFunctions)
|
||||
{
|
||||
sstream << Align(signal.className, GetMaxClassName(m_signals, titleClassName)) << "\t";
|
||||
sstream << Align(func.signalName, GetMaxSignalName(m_signals, titleSignalName)) << "\t";
|
||||
sstream << Align(func.canSignalName, GetMaxCANSignalName(m_signals, titleCANSignalName)) << "\t";
|
||||
sstream << Align(func.functionName, GetMaxFunctionName(m_signals, titleFunctionname)) << "\t";
|
||||
if (signal.signalDirection == sdv::core::ESignalDirection::sigdir_rx)
|
||||
sstream << "'RX' " << "\t";
|
||||
else
|
||||
sstream << "'TX' " << "\t";
|
||||
sstream << Align(func.idlType, GetMaxIDLType(m_signals, titleIDLType)) << "\t";
|
||||
sstream << Align(GetCTypeFromIDLType(func.idlType), GetMaxCTypeFromIDLType(m_signals, titleCType)) << "\t";
|
||||
sstream << Align(signal.vssDefinition, GetMaxVSSDefinition(m_signals, titleVSS)) << "\t\n";
|
||||
}
|
||||
}
|
||||
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
std::string CVSSVDGenerator::AppendExtension(const std::string& prefix, const std::string& filename,
|
||||
const std::string& extension) const
|
||||
{
|
||||
return prefix + filename + extension;
|
||||
}
|
||||
|
||||
void CVSSVDGenerator::CreateFiles(const std::string& ssVersion)
|
||||
{
|
||||
for (const SSignalVDDefinition& signal : m_signals)
|
||||
{
|
||||
if (signal.signalDirection == sdv::core::ESignalDirection::sigdir_rx)
|
||||
m_RXsignals.push_back(signal);
|
||||
else
|
||||
m_TXsignals.push_back(signal);
|
||||
}
|
||||
CreateRXFiles(ssVersion);
|
||||
CreateTXFiles(ssVersion);
|
||||
}
|
||||
|
||||
void CVSSVDGenerator::CreateRXFiles(const std::string& ssVersion) const
|
||||
{
|
||||
for (const auto& rxSignal : m_RXsignals)
|
||||
{
|
||||
if (m_enableComponentCreation)
|
||||
{
|
||||
CreateVehicleDeviceFilesForRXSignal(rxSignal, ssVersion);
|
||||
}
|
||||
CreateIDLVehicleDeviceFileForRXSignal(rxSignal, ssVersion);
|
||||
}
|
||||
}
|
||||
|
||||
void CVSSVDGenerator::CreateVehicleDeviceFilesForRXSignal(const SSignalVDDefinition& signal, const std::string& ssVersion) const
|
||||
{
|
||||
std::string folderName = "VD_";
|
||||
folderName.append(signal.className);
|
||||
std::transform(folderName.begin(), folderName.end(), folderName.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
if (!CreateFolder(m_pathProject, folderName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::filesystem::path pathVDHeader = m_pathProject / folderName / AppendExtension("VD_", signal.className, ".h");
|
||||
std::filesystem::path pathVDClass = m_pathProject / folderName / AppendExtension("VD_", signal.className, ".cpp");
|
||||
std::filesystem::path pathCMakeLists = m_pathProject / folderName / "CMakeLists.txt";
|
||||
std::ofstream fstreamVDHeader;
|
||||
std::ofstream fstreamVDClass;
|
||||
auto pathLowerCaseHeader = MakeLowercaseFilename(pathVDHeader);
|
||||
auto pathLowerCaseClass = MakeLowercaseFilename(pathVDClass);
|
||||
fstreamVDHeader.open(pathLowerCaseHeader, std::ios::out | std::ios::trunc);
|
||||
fstreamVDClass.open(pathLowerCaseClass, std::ios::out | std::ios::trunc);
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
CVSSCodingCommon coding(m_ssPrefix);
|
||||
coding.GetCommonKeyWordMap(signal, mapKeywords, ssVersion);
|
||||
mapKeywords["vd_safeguard"] = coding.Code_SafeGuard(pathVDHeader.filename().generic_u8string());
|
||||
|
||||
mapKeywords["abstract_device_h"] = pathLowerCaseHeader.filename().generic_u8string();
|
||||
mapKeywords["abstract_device_cpp"] = pathLowerCaseClass.filename().generic_u8string();
|
||||
|
||||
CVSSVDCodingRX codingRX(m_ssPrefix);
|
||||
codingRX.GetKeyWordMap(signal, mapKeywords);
|
||||
|
||||
fstreamVDHeader << ReplaceKeywords(szRXVehicleDeviceHeaderTemplate, mapKeywords);
|
||||
fstreamVDClass << ReplaceKeywords(szRXVehicleDeviceClassTemplate, mapKeywords);
|
||||
fstreamVDHeader.close();
|
||||
fstreamVDClass.close();
|
||||
|
||||
// create/write CMakeLists.txt only if content has changed
|
||||
std::string libaryName = m_ssPrefix;
|
||||
libaryName.append("_vd_");
|
||||
|
||||
std::string classNameLowerCase = signal.className;
|
||||
std::transform(classNameLowerCase.begin(), classNameLowerCase.end(), classNameLowerCase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
libaryName.append(classNameLowerCase);
|
||||
libaryName.append("_rx");
|
||||
auto cmakeContent = coding.Code_CMakeProject(libaryName, folderName);
|
||||
CreateCMakeFile(pathCMakeLists, cmakeContent);
|
||||
}
|
||||
|
||||
void CVSSVDGenerator::CreateIDLVehicleDeviceFileForRXSignal(const SSignalVDDefinition& signal, const std::string& ssVersion) const
|
||||
{
|
||||
std::stringstream ss(signal.vssDefinition);
|
||||
std::string item;
|
||||
std::string filenameVD = "VSS_";
|
||||
std::vector<std::string> parts;
|
||||
while (std::getline(ss, item, '.'))
|
||||
{
|
||||
parts.push_back(item);
|
||||
filenameVD.append(item);
|
||||
}
|
||||
filenameVD.append("_vd_rx");
|
||||
DeleteHeaderFile(m_pathProject, filenameVD);
|
||||
filenameVD.append(".idl");
|
||||
|
||||
std::filesystem::path pathVDRXIDL = m_pathProject / filenameVD;
|
||||
std::ofstream fstreamVDRXIDL;
|
||||
auto pathLowerCase = MakeLowercaseFilename(pathVDRXIDL);
|
||||
fstreamVDRXIDL.open(pathLowerCase, std::ios::out | std::ios::trunc);
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
CVSSCodingCommon coding(m_ssPrefix);
|
||||
coding.GetCommonKeyWordMap(signal, mapKeywords, ssVersion);
|
||||
mapKeywords["_vd_idl_h"] = pathLowerCase.filename().generic_u8string();
|
||||
|
||||
CVSSVDCodingRX codingRX(m_ssPrefix);
|
||||
mapKeywords["vss_device"] = codingRX.Code_RXIDLDeviceList(parts, signal.vecFunctions);
|
||||
mapKeywords["vss_service"] = codingRX.Code_RXIDLServiceList(parts, signal.vecFunctions);
|
||||
|
||||
fstreamVDRXIDL << ReplaceKeywords(szVDRXIDLTemplate, mapKeywords);
|
||||
fstreamVDRXIDL.close();
|
||||
}
|
||||
|
||||
void CVSSVDGenerator::CreateTXFiles(const std::string& ssVersion) const
|
||||
{
|
||||
for (const auto& txSignal : m_TXsignals)
|
||||
{
|
||||
if (m_enableComponentCreation)
|
||||
{
|
||||
CreateVehicleDeviceFilesForTXSignal(txSignal, ssVersion);
|
||||
}
|
||||
CreateIDLVehicleDeviceFileForTXSignal(txSignal, ssVersion);
|
||||
}
|
||||
}
|
||||
|
||||
void CVSSVDGenerator::CreateVehicleDeviceFilesForTXSignal(const SSignalVDDefinition& signal, const std::string& ssVersion) const
|
||||
{
|
||||
std::string folderName = "VD_";
|
||||
folderName.append(signal.className);
|
||||
std::transform(folderName.begin(), folderName.end(), folderName.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
if (!CreateFolder(m_pathProject, folderName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
std::filesystem::path pathVDHeader = m_pathProject / folderName / AppendExtension("VD_", signal.className, ".h");
|
||||
std::filesystem::path pathVDClass = m_pathProject / folderName / AppendExtension("VD_", signal.className, ".cpp");
|
||||
std::filesystem::path pathCMakeLists = m_pathProject / folderName / "CMakeLists.txt";
|
||||
std::ofstream fstreamVDHeader;
|
||||
std::ofstream fstreamVDClass;
|
||||
auto pathLowerCaseHeader = MakeLowercaseFilename(pathVDHeader);
|
||||
auto pathLowerCaseClass = MakeLowercaseFilename(pathVDClass);
|
||||
fstreamVDHeader.open(pathLowerCaseHeader, std::ios::out | std::ios::trunc);
|
||||
fstreamVDClass.open(pathLowerCaseClass, std::ios::out | std::ios::trunc);
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
CVSSCodingCommon coding(m_ssPrefix);
|
||||
coding.GetCommonKeyWordMap(signal, mapKeywords, ssVersion);
|
||||
mapKeywords["vd_safeguard"] = coding.Code_SafeGuard(pathVDHeader.filename().generic_u8string());
|
||||
|
||||
mapKeywords["abstract_device_h"] = pathLowerCaseHeader.filename().generic_u8string();
|
||||
mapKeywords["abstract_device_cpp"] = pathLowerCaseClass.filename().generic_u8string();
|
||||
|
||||
CVSSVDCodingTX codingTX(m_ssPrefix);
|
||||
codingTX.GetKeyWordMap(signal, mapKeywords);
|
||||
|
||||
mapKeywords["abstract_device_h"] = pathVDHeader.filename().generic_u8string();
|
||||
mapKeywords["abstract_device_cpp"] = pathVDClass.filename().generic_u8string();
|
||||
|
||||
fstreamVDHeader << ReplaceKeywords(szTXVehicleDeviceHeaderTemplate, mapKeywords);
|
||||
fstreamVDClass << ReplaceKeywords(szTXVehicleDeviceClassTemplate, mapKeywords);
|
||||
fstreamVDHeader.close();
|
||||
fstreamVDClass.close();
|
||||
|
||||
std::string classNameLowerCase = signal.className;
|
||||
std::transform(classNameLowerCase.begin(), classNameLowerCase.end(), classNameLowerCase.begin(),
|
||||
[](unsigned char c) { return static_cast<char>(std::tolower(c)); });
|
||||
|
||||
std::string libaryName = m_ssPrefix + "_vd_" + classNameLowerCase + "_tx";
|
||||
auto cmakeContent = coding.Code_CMakeProject(libaryName, folderName);
|
||||
CreateCMakeFile(pathCMakeLists, cmakeContent);
|
||||
}
|
||||
|
||||
void CVSSVDGenerator::CreateIDLVehicleDeviceFileForTXSignal(const SSignalVDDefinition& signal, const std::string& ssVersion) const
|
||||
{
|
||||
std::stringstream ss(signal.vssDefinition);
|
||||
std::string item;
|
||||
std::string filenameVD = "VSS_";
|
||||
std::vector<std::string> parts;
|
||||
while (std::getline(ss, item, '.'))
|
||||
{
|
||||
parts.push_back(item);
|
||||
filenameVD.append(item);
|
||||
}
|
||||
filenameVD.append("_vd_tx");
|
||||
DeleteHeaderFile(m_pathProject, filenameVD);
|
||||
filenameVD.append(".idl");
|
||||
|
||||
std::filesystem::path pathVDTXIDL = m_pathProject / filenameVD;
|
||||
std::ofstream fstreamVDTXIDL;
|
||||
auto pathLowerCase = MakeLowercaseFilename(pathVDTXIDL);
|
||||
fstreamVDTXIDL.open(pathLowerCase, std::ios::out | std::ios::trunc);
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
CVSSCodingCommon coding(m_ssPrefix);
|
||||
coding.GetCommonKeyWordMap(signal, mapKeywords, ssVersion);
|
||||
mapKeywords["_vd_idl_h"] = pathLowerCase.filename().generic_u8string();
|
||||
|
||||
CVSSVDCodingTX codingTX(m_ssPrefix);
|
||||
mapKeywords["vss_device"] = codingTX.Code_VD_TXIDLList(parts, signal.vecFunctions);
|
||||
|
||||
fstreamVDTXIDL << ReplaceKeywords(szVDTXIDLTemplate, mapKeywords);
|
||||
fstreamVDTXIDL.close();
|
||||
}
|
||||
109
sdv_executables/sdv_vss_util/vss_vd_generator.h
Normal file
109
sdv_executables/sdv_vss_util/vss_vd_generator.h
Normal file
@@ -0,0 +1,109 @@
|
||||
#ifndef VSS_VD_GENERATOR_H
|
||||
#define VSS_VD_GENERATOR_H
|
||||
|
||||
#include <fstream>
|
||||
#include "codegen_base.h"
|
||||
#include "vss_helper.h"
|
||||
|
||||
/**
|
||||
* @brief Basic Service generator.
|
||||
*/
|
||||
class CVSSVDGenerator : public CCodeGeneratorBase, CVSSHelper
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] signals Reference to a vector containing all signals
|
||||
* @param[in] rpathOutputDir Reference to the outpur directory.
|
||||
* @param[in] rsPrefix used by cmake library and signal definition in signal_identifier.h file
|
||||
* @param[in] rsVersion optional version tag, will be wriiten in header of the files
|
||||
* @param[in] enableComponentCreation optional version tag, will be wriiten in header of the files
|
||||
*/
|
||||
CVSSVDGenerator(const std::vector<SSignalVDDefinition>& signals, const std::filesystem::path& rpathOutputDir, const std::string& rsPrefix, const std::string& rsVersion, const bool enableComponentCreation) :
|
||||
m_enableComponentCreation(enableComponentCreation),
|
||||
m_ssPrefix(rsPrefix),
|
||||
m_ssVersion(rsVersion),
|
||||
m_pathProject(rpathOutputDir),
|
||||
m_signals(signals)
|
||||
{}
|
||||
|
||||
/**
|
||||
* @brief Auto generate the Files
|
||||
* @return true on success, otherwise false
|
||||
*/
|
||||
bool GeneratedCode();
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* @brief create content of the summary tect file
|
||||
* @return string containing the complete content of the summary text file;
|
||||
*/
|
||||
std::string SummaryTextFile() const;
|
||||
|
||||
/**
|
||||
* @brief create a file name including prefix and extension
|
||||
* @param[in] prefix
|
||||
* @param[in] filename
|
||||
* @param[in] extension
|
||||
* @return combined file name
|
||||
*/
|
||||
std::string AppendExtension(const std::string& prefix, const std::string& filename, const std::string& extension) const;
|
||||
|
||||
/**
|
||||
* @brief create vehicle device and basic service .h an .cpp files
|
||||
* create IDL files
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateFiles(const std::string& ssVersion);
|
||||
|
||||
/**
|
||||
* @brief create IDL files and vehicle device and basic service files of RX signals
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateRXFiles(const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief create vehicle device files of a single RX signal
|
||||
* @param[in] signal single signal definition
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateVehicleDeviceFilesForRXSignal(const SSignalVDDefinition& signal, const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief create IDL file of a single RX signal (vehicle device)
|
||||
* @param[in] signal single signal definition
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateIDLVehicleDeviceFileForRXSignal(const SSignalVDDefinition& signal, const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief create IDL files and vehicle device and basic service files of TX signals
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateTXFiles(const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief create vehicle device files of a single TX signal
|
||||
* @param[in] signal single signal definition
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateVehicleDeviceFilesForTXSignal(const SSignalVDDefinition& signal, const std::string& ssVersion) const;
|
||||
|
||||
/**
|
||||
* @brief create IDL file for a single TX signal (vehicle device)
|
||||
* @param[in] signal single signal definition
|
||||
* @param[in] ssVersion optional information will be placed in the header of the files
|
||||
*/
|
||||
void CreateIDLVehicleDeviceFileForTXSignal(const SSignalVDDefinition& signal, const std::string& ssVersion) const;
|
||||
|
||||
bool m_enableComponentCreation; ///< if set, the code for the components are created, otherwise only idl files
|
||||
std::string m_ssPrefix; ///< prefix, used by cmake library and signal definition in signal_identifier.h file.
|
||||
std::string m_ssVersion; ///< optional version tag, will be wriiten in header of the files
|
||||
std::filesystem::path m_pathProject; ///< Project file path
|
||||
std::vector <SSignalVDDefinition> m_signals; ///< all signals
|
||||
std::vector <SSignalVDDefinition> m_TXsignals; ///< vector containing the RX signals
|
||||
std::vector <SSignalVDDefinition> m_RXsignals; ///< vector containing the TX signals
|
||||
};
|
||||
|
||||
#endif // !defined VSS_VD_GENERATOR_H
|
||||
Reference in New Issue
Block a user