mirror of
https://github.com/supleed2/svd2cpp.git
synced 2024-12-22 13:45:50 +00:00
Added builders
This commit is contained in:
parent
57a9cfc168
commit
04a24f9bbf
|
@ -8,8 +8,9 @@ include_directories(cxxopts/include)
|
||||||
include_directories(tinyxml2)
|
include_directories(tinyxml2)
|
||||||
|
|
||||||
add_library(ClassBuilder Src/ClassBuilder.cpp)
|
add_library(ClassBuilder Src/ClassBuilder.cpp)
|
||||||
|
add_library(Builders Src/Builders.cpp)
|
||||||
add_library(XmlParser Src/XmlParser.cpp)
|
add_library(XmlParser Src/XmlParser.cpp)
|
||||||
add_library(tinyxml2 tinyxml2/tinyxml2.cpp)
|
add_library(tinyxml2 tinyxml2/tinyxml2.cpp)
|
||||||
|
|
||||||
add_executable(svd2cpp Src/main.cpp)
|
add_executable(svd2cpp Src/main.cpp)
|
||||||
target_link_libraries(svd2cpp ClassBuilder XmlParser tinyxml2)
|
target_link_libraries(svd2cpp ClassBuilder Builders XmlParser tinyxml2)
|
39
Src/Builders.cpp
Normal file
39
Src/Builders.cpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include <Builders.hpp>
|
||||||
|
|
||||||
|
void ZeroPointerBuilder::build(std::stringstream& ss){
|
||||||
|
ss << "template <unsigned int zero = 0>\n"
|
||||||
|
"constexpr unsigned int *zeroVal = reinterpret_cast<unsigned int *>(zero);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void PeripheralBuilder::build(std::stringstream& ss){
|
||||||
|
ss << "namespace " << peripheral.name.c_str() << "{\n";
|
||||||
|
for(auto& registe : peripheral.registers){
|
||||||
|
RegisterBuilder(registe).build(ss);
|
||||||
|
}
|
||||||
|
ss << "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterBuilder::build(std::stringstream& ss){
|
||||||
|
//TODO: fix INVALID: some derived names are not copied
|
||||||
|
ss << " "
|
||||||
|
<< "namespace " << (registe.name.length() > 100 ? "INVALID" : registe.name) << "{\n";
|
||||||
|
for(auto& field : registe.fields){
|
||||||
|
FieldBuilder(field).build(ss);
|
||||||
|
}
|
||||||
|
ss << " " << "}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void FieldBuilder::build(std::stringstream& ss){
|
||||||
|
ss << " " << "struct " << (field.name.length() > 100 ? "INVALID" : field.name) << "{\n";
|
||||||
|
|
||||||
|
//TODO: fix INVALID: some derived items are not copied
|
||||||
|
ss << " " << " " << "constexpr static inline unsigned int bitOffset(){"
|
||||||
|
<< "return " << field.bitOffset << "}\n";
|
||||||
|
|
||||||
|
ss << " " << " " << "constexpr static inline unsigned int bitMask(){"
|
||||||
|
<< "return " << field.bitWidth << "}\n";
|
||||||
|
|
||||||
|
ss << " " << " " << "constexpr static inline unsigned int address(){"
|
||||||
|
<< "return " << "TODO" << "}\n";
|
||||||
|
ss << " }\n";
|
||||||
|
}
|
36
Src/Builders.hpp
Normal file
36
Src/Builders.hpp
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef BUILDERS
|
||||||
|
#define BUILDERS
|
||||||
|
|
||||||
|
#include <IBuilder.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
#include <Peripheral.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
struct ZeroPointerBuilder : public IBuilder{
|
||||||
|
void build(std::stringstream& ss) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PeripheralBuilder : public IBuilder{
|
||||||
|
PeripheralBuilder(const Peripheral& peripheral_) : peripheral(peripheral_){}
|
||||||
|
void build(std::stringstream& ss) final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Peripheral& peripheral;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RegisterBuilder : public IBuilder{
|
||||||
|
RegisterBuilder(const Register& register_) : registe(register_){}
|
||||||
|
void build(std::stringstream& ss) final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Register& registe;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FieldBuilder : public IBuilder{
|
||||||
|
FieldBuilder(const Field& field_) : field(field_){}
|
||||||
|
void build(std::stringstream& ss) final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Field& field;
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -1,9 +1,25 @@
|
||||||
#include <ClassBuilder.hpp>
|
#include <ClassBuilder.hpp>
|
||||||
|
#include <Builders.hpp>
|
||||||
ClassBuilder::ClassBuilder(const cxxopts::ParseResult& results,
|
|
||||||
const DeviceInfo& deviceInfo,
|
|
||||||
const std::vector<Peripheral>& peripherals) :
|
ClassBuilder::ClassBuilder(const cxxopts::ParseResult& results,
|
||||||
results(results),
|
const DeviceInfo& deviceInfo,
|
||||||
deviceInfo(deviceInfo),
|
const std::vector<Peripheral>& peripherals) :
|
||||||
peripherals(peripherals){
|
results(results),
|
||||||
}
|
deviceInfo(deviceInfo),
|
||||||
|
peripherals(peripherals){
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassBuilder::setupBuilders(){
|
||||||
|
builders.push_back(std::make_unique<ZeroPointerBuilder>());
|
||||||
|
for(auto& peripheral : peripherals){
|
||||||
|
builders.push_back(std::make_unique<PeripheralBuilder>(peripheral));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassBuilder::build(){
|
||||||
|
for(auto& builder : builders){
|
||||||
|
builder->build(outputStream);
|
||||||
|
}
|
||||||
|
std::cout << outputStream.str();
|
||||||
|
}
|
||||||
|
|
|
@ -1,22 +1,29 @@
|
||||||
#ifndef CLASS_PRINTER
|
#ifndef CLASS_PRINTER
|
||||||
#define CLASS_PRINTER
|
#define CLASS_PRINTER
|
||||||
|
|
||||||
#include <cxxopts.hpp>
|
#include <cxxopts.hpp>
|
||||||
#include <DeviceInfo.hpp>
|
#include <DeviceInfo.hpp>
|
||||||
#include <Peripheral.hpp>
|
#include <Peripheral.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <IBuilder.hpp>
|
||||||
struct ClassBuilder
|
#include <memory>
|
||||||
{
|
#include <sstream>
|
||||||
ClassBuilder(const cxxopts::ParseResult& results,
|
|
||||||
const DeviceInfo& deviceInfo,
|
|
||||||
const std::vector<Peripheral>& peripherals);
|
struct ClassBuilder
|
||||||
|
{
|
||||||
private:
|
ClassBuilder(const cxxopts::ParseResult& results,
|
||||||
const cxxopts::ParseResult& results;
|
const DeviceInfo& deviceInfo,
|
||||||
const DeviceInfo& deviceInfo;
|
const std::vector<Peripheral>& peripherals);
|
||||||
const std::vector<Peripheral>& peripherals;
|
void setupBuilders();
|
||||||
};
|
void build();
|
||||||
|
|
||||||
|
private:
|
||||||
#endif
|
const cxxopts::ParseResult& results;
|
||||||
|
const DeviceInfo& deviceInfo;
|
||||||
|
const std::vector<Peripheral>& peripherals;
|
||||||
|
std::vector<std::unique_ptr<IBuilder>> builders;
|
||||||
|
std::stringstream outputStream;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
12
Src/IBuilder.hpp
Normal file
12
Src/IBuilder.hpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef I_BUILDER
|
||||||
|
#define I_BUILDER
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
|
struct IBuilder{
|
||||||
|
virtual void build(std::stringstream&) = 0;
|
||||||
|
virtual ~IBuilder() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
enum class EAccess{
|
enum class EAccess{
|
||||||
Read_Only,
|
Read_Only,
|
||||||
|
|
|
@ -21,7 +21,7 @@ void XmlParser::parseXml(){
|
||||||
setDeviceInfoAttrib(deviceRoot, "version", deviceInfo.version);
|
setDeviceInfoAttrib(deviceRoot, "version", deviceInfo.version);
|
||||||
setDeviceInfoAttrib(deviceRoot, "resetValue", deviceInfo.resetValue);
|
setDeviceInfoAttrib(deviceRoot, "resetValue", deviceInfo.resetValue);
|
||||||
|
|
||||||
deviceInfo.printDeviceInfo();
|
// deviceInfo.printDeviceInfo();
|
||||||
|
|
||||||
//Iterate over all peripherals and append them to peripherals
|
//Iterate over all peripherals and append them to peripherals
|
||||||
tinyxml2::XMLElement *peripheralsRoot = deviceRoot->FirstChildElement("peripherals");
|
tinyxml2::XMLElement *peripheralsRoot = deviceRoot->FirstChildElement("peripherals");
|
||||||
|
@ -68,9 +68,7 @@ void XmlParser::setDeviceInfoAttrib(tinyxml2::XMLElement* deviceRoot, const char
|
||||||
std::cout << "Wrong field for access: " << text << std::endl;
|
std::cout << "Wrong field for access: " << text << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unsigned int peripheralCount = 0; //Debug
|
|
||||||
Peripheral XmlParser::parsePeripheral(tinyxml2::XMLElement* peripheralRoot) const{
|
Peripheral XmlParser::parsePeripheral(tinyxml2::XMLElement* peripheralRoot) const{
|
||||||
std::cout << "Peripheral: " << peripheralCount++ << std::endl; //Debug
|
|
||||||
//Check if peripheral is derived from previous one
|
//Check if peripheral is derived from previous one
|
||||||
const char* attribute = peripheralRoot->Attribute("derivedFrom");
|
const char* attribute = peripheralRoot->Attribute("derivedFrom");
|
||||||
const bool isDerived = attribute != nullptr;
|
const bool isDerived = attribute != nullptr;
|
||||||
|
@ -78,7 +76,6 @@ Peripheral XmlParser::parsePeripheral(tinyxml2::XMLElement* peripheralRoot) cons
|
||||||
|
|
||||||
Peripheral peripheral;
|
Peripheral peripheral;
|
||||||
if(isDerived == true){
|
if(isDerived == true){
|
||||||
std::cout << "Derived from " << derivedFrom << std::endl;
|
|
||||||
//Find the base peripheral and copy it to the new one
|
//Find the base peripheral and copy it to the new one
|
||||||
auto crit = [&](auto &periph) { return periph.name == derivedFrom; };
|
auto crit = [&](auto &periph) { return periph.name == derivedFrom; };
|
||||||
auto resultIt = std::find_if(peripherals.begin(), peripherals.end(), crit);
|
auto resultIt = std::find_if(peripherals.begin(), peripherals.end(), crit);
|
||||||
|
@ -111,7 +108,7 @@ Peripheral XmlParser::parsePeripheral(tinyxml2::XMLElement* peripheralRoot) cons
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
peripheral.display();
|
// peripheral.display();
|
||||||
return peripheral;
|
return peripheral;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,12 @@ struct XmlParser{
|
||||||
XmlParser(const std::string& inputFile);
|
XmlParser(const std::string& inputFile);
|
||||||
std::optional<std::string> isError() const;
|
std::optional<std::string> isError() const;
|
||||||
void parseXml();
|
void parseXml();
|
||||||
|
inline const DeviceInfo getDeviceInfo() const{
|
||||||
|
return deviceInfo;
|
||||||
|
}
|
||||||
|
inline const std::vector<Peripheral> getPeripherals() const{
|
||||||
|
return peripherals;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// tinyxml2::XMLElement* getDevice
|
// tinyxml2::XMLElement* getDevice
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cxxopts.hpp>
|
#include <cxxopts.hpp>
|
||||||
#include <XmlParser.hpp>
|
#include <XmlParser.hpp>
|
||||||
|
#include <ClassBuilder.hpp>
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv){
|
int main(int argc, char** argv){
|
||||||
// Create and configure options for the program
|
// Create and configure options for the program
|
||||||
|
@ -9,9 +11,9 @@ int main(int argc, char** argv){
|
||||||
("i, input", "File to be parsed", cxxopts::value<std::string>())
|
("i, input", "File to be parsed", cxxopts::value<std::string>())
|
||||||
("o, output", "OutputFile", cxxopts::value<std::string>());
|
("o, output", "OutputFile", cxxopts::value<std::string>());
|
||||||
std::string inputFile, outputFile;
|
std::string inputFile, outputFile;
|
||||||
|
auto result = options.parse(argc, argv);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto result = options.parse(argc, argv);
|
|
||||||
if(result.count("input") != 1){
|
if(result.count("input") != 1){
|
||||||
std::cout << "Missing input file!" << std::endl;
|
std::cout << "Missing input file!" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -35,4 +37,7 @@ int main(int argc, char** argv){
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
xmlParser.parseXml();
|
xmlParser.parseXml();
|
||||||
|
ClassBuilder classBuilder(result, xmlParser.getDeviceInfo(), xmlParser.getPeripherals());
|
||||||
|
classBuilder.setupBuilders();
|
||||||
|
classBuilder.build();
|
||||||
}
|
}
|
Loading…
Reference in a new issue