mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-04-15 17:48:16 +00:00
Update sdv_packager (#6)
This commit is contained in:
@@ -1,3 +1,16 @@
|
||||
/********************************************************************************
|
||||
* Copyright (c) 2025-2026 ZF Friedrichshafen AG
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Apache License Version 2.0 which is available at
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Thomas Pfleiderer - initial API and implementation
|
||||
********************************************************************************/
|
||||
|
||||
#include "vss_vd_generator.h"
|
||||
#include "vss_coding.h"
|
||||
#include "vss_vd_codingrx.h"
|
||||
@@ -99,7 +112,7 @@ void CVSSVDGenerator::CreateFiles(const std::string& ssVersion)
|
||||
CreateTXFiles(ssVersion);
|
||||
}
|
||||
|
||||
void CVSSVDGenerator::CreateRXFiles(const std::string& ssVersion) const
|
||||
void CVSSVDGenerator::CreateRXFiles(const std::string& ssVersion)
|
||||
{
|
||||
for (const auto& rxSignal : m_RXsignals)
|
||||
{
|
||||
@@ -111,7 +124,7 @@ void CVSSVDGenerator::CreateRXFiles(const std::string& ssVersion) const
|
||||
}
|
||||
}
|
||||
|
||||
void CVSSVDGenerator::CreateVehicleDeviceFilesForRXSignal(const SSignalVDDefinition& signal, const std::string& ssVersion) const
|
||||
void CVSSVDGenerator::CreateVehicleDeviceFilesForRXSignal(const SSignalVDDefinition& signal, const std::string& ssVersion)
|
||||
{
|
||||
std::string folderName = "VD_";
|
||||
folderName.append(signal.className);
|
||||
@@ -127,7 +140,10 @@ void CVSSVDGenerator::CreateVehicleDeviceFilesForRXSignal(const SSignalVDDefinit
|
||||
std::ofstream fstreamVDHeader;
|
||||
std::ofstream fstreamVDClass;
|
||||
auto pathLowerCaseHeader = MakeLowercaseFilename(pathVDHeader);
|
||||
auto pathLowerCaseClass = MakeLowercaseFilename(pathVDClass);
|
||||
auto pathLowerCaseClass = MakeLowercaseFilename(pathVDClass);
|
||||
m_createdFiles.push_back(pathLowerCaseHeader);
|
||||
m_createdFiles.push_back(pathLowerCaseClass);
|
||||
|
||||
fstreamVDHeader.open(pathLowerCaseHeader, std::ios::out | std::ios::trunc);
|
||||
fstreamVDClass.open(pathLowerCaseClass, std::ios::out | std::ios::trunc);
|
||||
|
||||
@@ -211,18 +227,27 @@ void CVSSVDGenerator::CreateVehicleDeviceFilesForTXSignal(const SSignalVDDefinit
|
||||
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)); });
|
||||
[](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);
|
||||
auto pathLowerCaseClass = MakeLowercaseFilename(pathVDClass);
|
||||
|
||||
auto headerExists = std::find(m_createdFiles.begin(), m_createdFiles.end(), pathLowerCaseHeader) != m_createdFiles.end();
|
||||
auto classExists = std::find(m_createdFiles.begin(), m_createdFiles.end(), pathLowerCaseClass) != m_createdFiles.end();
|
||||
if (headerExists || classExists)
|
||||
{
|
||||
UpdateExistingFiles(m_pathProject, folderName, signal);
|
||||
return;
|
||||
}
|
||||
fstreamVDHeader.open(pathLowerCaseHeader, std::ios::out | std::ios::trunc);
|
||||
fstreamVDClass.open(pathLowerCaseClass, std::ios::out | std::ios::trunc);
|
||||
|
||||
@@ -282,3 +307,172 @@ void CVSSVDGenerator::CreateIDLVehicleDeviceFileForTXSignal(const SSignalVDDefin
|
||||
fstreamVDTXIDL << ReplaceKeywords(szVDTXIDLTemplate, mapKeywords);
|
||||
fstreamVDTXIDL.close();
|
||||
}
|
||||
|
||||
|
||||
bool CVSSVDGenerator::UpdateExistingFiles(const std::filesystem::path& rootPath, const std::string& subfolder, const SSignalVDDefinition& signal) const
|
||||
{
|
||||
std::filesystem::path path = rootPath / subfolder;
|
||||
|
||||
CKeywordMap mapKeywords;
|
||||
CVSSVDCodingTX codingTX(m_ssPrefix);
|
||||
codingTX.GetKeyWordMap(signal, mapKeywords);
|
||||
|
||||
auto initializeList = mapKeywords["tx_variable_init_list"];
|
||||
auto functionImplementation = mapKeywords["tx_function_implementations"];
|
||||
if (UpdateCppFile(path, signal, initializeList, functionImplementation))
|
||||
{
|
||||
|
||||
auto includeList = mapKeywords["tx_vd_includes_list"];
|
||||
auto interfaceList = mapKeywords["tx_vd_interface_list"];
|
||||
auto interfaceEntryList = mapKeywords["tx_vd_interface_entry_list"];
|
||||
auto functionList = mapKeywords["tx_vd_function_list"];
|
||||
auto variablePointerList = mapKeywords["tx_variable_list"];
|
||||
|
||||
if (UpdateHeaderFile(path, signal, includeList, interfaceList, interfaceEntryList, functionList, variablePointerList))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CVSSVDGenerator::UpdateCppFile(const std::filesystem::path& rootFolder, const SSignalVDDefinition& signal, const std::string& initializeList, const std::string& implementation) const
|
||||
{
|
||||
std::filesystem::path pathVDCpp = rootFolder / AppendExtension("VD_", signal.className, ".cpp");
|
||||
auto pathLowerCaseCpp = MakeLowercaseFilename(pathVDCpp);
|
||||
|
||||
std::ifstream in(pathLowerCaseCpp);
|
||||
if (!in)
|
||||
{
|
||||
std::cerr << "Failed to read file '" << pathLowerCaseCpp << ")\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string s;
|
||||
std::vector<std::string> lines; // write new file into memory
|
||||
while (std::getline(in, s))
|
||||
{
|
||||
lines.push_back(s);
|
||||
if (s.find("sdv::core::CDispatchService dispatch;") != std::string::npos)
|
||||
{
|
||||
lines.push_back(initializeList);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (std::getline(in, s))
|
||||
{
|
||||
lines.push_back(s);
|
||||
}
|
||||
|
||||
lines.push_back(implementation); // implementation at end of file
|
||||
in.close();
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::remove(pathLowerCaseCpp, ec); // delete file
|
||||
if (ec)
|
||||
{
|
||||
std::cerr << "Failed to delete file '" << pathLowerCaseCpp << "': " << ec.message() << " (error code: " << ec.value() << ")\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ofstream out(pathLowerCaseCpp, std::ios::trunc);
|
||||
if (!out)
|
||||
{
|
||||
std::cerr << "Failed to write file '" << pathLowerCaseCpp << ")\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& line : lines)
|
||||
out << line << "\n";
|
||||
|
||||
out.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CVSSVDGenerator::UpdateHeaderFile(const std::filesystem::path& rootFolder, const SSignalVDDefinition& signal, const std::string& includeList,
|
||||
const std::string& interfaceList, const std::string& interfaceEntryList, const std::string& functionList, const std::string& variablePointerList) const
|
||||
{
|
||||
std::filesystem::path pathVDHeader = rootFolder / AppendExtension("VD_", signal.className, ".h");
|
||||
auto pathLowerCaseHeader = MakeLowercaseFilename(pathVDHeader);
|
||||
|
||||
std::ifstream in(pathLowerCaseHeader);
|
||||
if (!in)
|
||||
{
|
||||
std::cerr << "Failed to read file '" << pathLowerCaseHeader << ")\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string s;
|
||||
std::vector<std::string> lines; // write new file into memory
|
||||
while (std::getline(in, s))
|
||||
{
|
||||
lines.push_back(s);
|
||||
if (s.find("<support/signal_support.h>") != std::string::npos)
|
||||
{
|
||||
lines.push_back(includeList);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (std::getline(in, s))
|
||||
{
|
||||
lines.push_back(s);
|
||||
if (s.find(", public") != std::string::npos)
|
||||
{
|
||||
lines.push_back(interfaceList);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (std::getline(in, s))
|
||||
{
|
||||
lines.push_back(s);
|
||||
if (s.find("BEGIN_SDV_INTERFACE_MAP()") != std::string::npos)
|
||||
{
|
||||
lines.push_back(interfaceEntryList);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (std::getline(in, s))
|
||||
{
|
||||
if (s.find("private:") != std::string::npos)
|
||||
{
|
||||
lines.push_back(functionList); // we need to add entries before and after
|
||||
lines.push_back(s);
|
||||
lines.push_back(variablePointerList);
|
||||
break;
|
||||
}
|
||||
lines.push_back(s);
|
||||
}
|
||||
|
||||
while (std::getline(in, s))
|
||||
{
|
||||
lines.push_back(s);
|
||||
}
|
||||
in.close();
|
||||
|
||||
|
||||
std::error_code ec;
|
||||
std::filesystem::remove(pathLowerCaseHeader, ec); // delete file
|
||||
if (ec)
|
||||
{
|
||||
std::cerr << "Failed to delete file '" << pathLowerCaseHeader << "': " << ec.message() << " (error code: " << ec.value() << ")\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ofstream out(pathLowerCaseHeader, std::ios::trunc);
|
||||
if (!out)
|
||||
{
|
||||
std::cerr << "Failed to write file '" << pathLowerCaseHeader << ")\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& line : lines) // write new file to disc
|
||||
out << line << "\n";
|
||||
out.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user