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)
|
||||
|
||||
add_library(ClassBuilder Src/ClassBuilder.cpp)
|
||||
add_library(Builders Src/Builders.cpp)
|
||||
add_library(XmlParser Src/XmlParser.cpp)
|
||||
add_library(tinyxml2 tinyxml2/tinyxml2.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>
|
||||
|
||||
ClassBuilder::ClassBuilder(const cxxopts::ParseResult& results,
|
||||
const DeviceInfo& deviceInfo,
|
||||
const std::vector<Peripheral>& peripherals) :
|
||||
results(results),
|
||||
deviceInfo(deviceInfo),
|
||||
peripherals(peripherals){
|
||||
}
|
||||
#include <ClassBuilder.hpp>
|
||||
#include <Builders.hpp>
|
||||
|
||||
|
||||
ClassBuilder::ClassBuilder(const cxxopts::ParseResult& results,
|
||||
const DeviceInfo& deviceInfo,
|
||||
const std::vector<Peripheral>& 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
|
||||
#define CLASS_PRINTER
|
||||
|
||||
#include <cxxopts.hpp>
|
||||
#include <DeviceInfo.hpp>
|
||||
#include <Peripheral.hpp>
|
||||
#include <vector>
|
||||
|
||||
struct ClassBuilder
|
||||
{
|
||||
ClassBuilder(const cxxopts::ParseResult& results,
|
||||
const DeviceInfo& deviceInfo,
|
||||
const std::vector<Peripheral>& peripherals);
|
||||
|
||||
private:
|
||||
const cxxopts::ParseResult& results;
|
||||
const DeviceInfo& deviceInfo;
|
||||
const std::vector<Peripheral>& peripherals;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#ifndef CLASS_PRINTER
|
||||
#define CLASS_PRINTER
|
||||
|
||||
#include <cxxopts.hpp>
|
||||
#include <DeviceInfo.hpp>
|
||||
#include <Peripheral.hpp>
|
||||
#include <vector>
|
||||
#include <IBuilder.hpp>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
struct ClassBuilder
|
||||
{
|
||||
ClassBuilder(const cxxopts::ParseResult& results,
|
||||
const DeviceInfo& deviceInfo,
|
||||
const std::vector<Peripheral>& peripherals);
|
||||
void setupBuilders();
|
||||
void build();
|
||||
|
||||
private:
|
||||
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 <vector>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
enum class EAccess{
|
||||
Read_Only,
|
||||
|
|
|
@ -21,7 +21,7 @@ void XmlParser::parseXml(){
|
|||
setDeviceInfoAttrib(deviceRoot, "version", deviceInfo.version);
|
||||
setDeviceInfoAttrib(deviceRoot, "resetValue", deviceInfo.resetValue);
|
||||
|
||||
deviceInfo.printDeviceInfo();
|
||||
// deviceInfo.printDeviceInfo();
|
||||
|
||||
//Iterate over all peripherals and append them to 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;
|
||||
}
|
||||
}
|
||||
unsigned int peripheralCount = 0; //Debug
|
||||
Peripheral XmlParser::parsePeripheral(tinyxml2::XMLElement* peripheralRoot) const{
|
||||
std::cout << "Peripheral: " << peripheralCount++ << std::endl; //Debug
|
||||
//Check if peripheral is derived from previous one
|
||||
const char* attribute = peripheralRoot->Attribute("derivedFrom");
|
||||
const bool isDerived = attribute != nullptr;
|
||||
|
@ -78,7 +76,6 @@ Peripheral XmlParser::parsePeripheral(tinyxml2::XMLElement* peripheralRoot) cons
|
|||
|
||||
Peripheral peripheral;
|
||||
if(isDerived == true){
|
||||
std::cout << "Derived from " << derivedFrom << std::endl;
|
||||
//Find the base peripheral and copy it to the new one
|
||||
auto crit = [&](auto &periph) { return periph.name == derivedFrom; };
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,12 @@ struct XmlParser{
|
|||
XmlParser(const std::string& inputFile);
|
||||
std::optional<std::string> isError() const;
|
||||
void parseXml();
|
||||
inline const DeviceInfo getDeviceInfo() const{
|
||||
return deviceInfo;
|
||||
}
|
||||
inline const std::vector<Peripheral> getPeripherals() const{
|
||||
return peripherals;
|
||||
}
|
||||
|
||||
private:
|
||||
// tinyxml2::XMLElement* getDevice
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include <iostream>
|
||||
#include <cxxopts.hpp>
|
||||
#include <XmlParser.hpp>
|
||||
#include <ClassBuilder.hpp>
|
||||
|
||||
|
||||
int main(int argc, char** argv){
|
||||
// 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>())
|
||||
("o, output", "OutputFile", cxxopts::value<std::string>());
|
||||
std::string inputFile, outputFile;
|
||||
auto result = options.parse(argc, argv);
|
||||
try
|
||||
{
|
||||
auto result = options.parse(argc, argv);
|
||||
if(result.count("input") != 1){
|
||||
std::cout << "Missing input file!" << std::endl;
|
||||
return 1;
|
||||
|
@ -35,4 +37,7 @@ int main(int argc, char** argv){
|
|||
return 3;
|
||||
}
|
||||
xmlParser.parseXml();
|
||||
ClassBuilder classBuilder(result, xmlParser.getDeviceInfo(), xmlParser.getPeripherals());
|
||||
classBuilder.setupBuilders();
|
||||
classBuilder.build();
|
||||
}
|
Loading…
Reference in a new issue