Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ project(parseagle

# If Qt version is not explicitly specified, automatically determine it
if(NOT PARSEAGLE_QT_MAJOR_VERSION)
find_package(Qt NAMES Qt5 Qt6 REQUIRED COMPONENTS Core Xml)
find_package(Qt NAMES Qt5 Qt6 REQUIRED COMPONENTS Core)
set(PARSEAGLE_QT_MAJOR_VERSION ${Qt_VERSION_MAJOR})
endif()
set(PARSEAGLE_QT "Qt${PARSEAGLE_QT_MAJOR_VERSION}")
Expand All @@ -26,7 +26,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Find required Qt packages
find_package(${PARSEAGLE_QT} REQUIRED COMPONENTS Core Xml)
find_package(${PARSEAGLE_QT} REQUIRED COMPONENTS Core)
message(STATUS "Building parseagle with Qt ${${PARSEAGLE_QT}_VERSION}")

# Export library
Expand Down Expand Up @@ -119,11 +119,7 @@ add_library(parseagle STATIC
parseagle/symbol/pin.h
parseagle/symbol/symbol.h
)
target_link_libraries(parseagle
# Qt
${PARSEAGLE_QT}::Core
${PARSEAGLE_QT}::Xml
)
target_link_libraries(parseagle ${PARSEAGLE_QT}::Core)
target_include_directories(parseagle INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")

# Alias to namespaced variant
Expand Down
11 changes: 2 additions & 9 deletions parseagle/board/board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,8 @@ Board::~Board() noexcept

void Board::load(const QByteArray& content, QStringList* errors)
{
QDomDocument doc;
doc.implementation().setInvalidDataPolicy(QDomImplementation::ReturnNullNode);
QString errMsg;
if (!doc.setContent(content, &errMsg)) {
throw std::runtime_error(
"Error while parsing EAGLE board: " + errMsg.toStdString());
}
DomElement root(doc.documentElement());
DomElement drawing = root.getFirstChild("drawing");
const DomElement root = DomElement::parse(content);
const DomElement drawing = root.getFirstChild("drawing");

if (drawing.hasChild("grid")) {
mGrid = Grid(drawing.getFirstChild("grid"));
Expand Down
64 changes: 52 additions & 12 deletions parseagle/common/domelement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,68 @@

namespace parseagle {

DomElement::DomElement(const QDomElement& root)
DomElement::DomElement(QXmlStreamReader& reader)
{
if (root.isNull()) {
throw std::runtime_error("Invalid XML node!");
mName = reader.name().toString();
for (const QXmlStreamAttribute& attr : reader.attributes()) {
mAttributes.insert(attr.name().toString(), attr.value().toString());
}

mName = root.tagName();
mText = root.text();

QDomNamedNodeMap map = root.attributes();
for (int i = 0; i < map.count(); i++) {
mAttributes.insert(map.item(i).nodeName(), map.item(i).nodeValue());
while (!reader.atEnd()) {
reader.readNext();
if (reader.isCharacters()) {
mText.append(reader.text().toString());
} else if (reader.isStartElement()) {
mChilds.append(DomElement(reader));
} else if (reader.isEndElement()) {
break;
}
}

for (QDomElement c = root.firstChildElement(); !c.isNull(); c = c.nextSiblingElement()) {
mChilds.append(DomElement(c));
if (reader.hasError()) {
const QString err = "Failed to parse XML: " + reader.errorString();
throw std::runtime_error(err.toStdString());
}
}

DomElement::~DomElement() noexcept
{
}

DomElement DomElement::parse(QXmlStreamReader& reader)
{
while (!reader.atEnd()) {
reader.readNext();
if (reader.isStartElement()) {
break;
}
}
if (reader.hasError() || (!reader.isStartElement())) {
const QString err = "Failed to find XML root element: " + reader.errorString();
throw std::runtime_error(err.toStdString());
}
const DomElement root(reader);
if (reader.hasError() || (!reader.isEndElement())) {
const QString err = "XML file seems incomplete: " + reader.errorString();
throw std::runtime_error(err.toStdString());
}
return root;
}

DomElement DomElement::parse(const QString& data)
{
QXmlStreamReader reader;
reader.addData(data);
return parse(reader);
}

DomElement DomElement::parse(const QByteArray& data)
{
QXmlStreamReader reader;
reader.addData(data);
return parse(reader);
}

QString DomElement::getAttributeAsString(const QString& name) const
{
if (mAttributes.contains(name)) {
Expand All @@ -37,7 +76,8 @@ QString DomElement::getAttributeAsString(const QString& name) const
}
}

bool DomElement::getAttributeAsBool(const QString& name) const {
bool DomElement::getAttributeAsBool(const QString& name) const
{
const QString value = getAttributeAsString(name);
if (value == "yes") {
return true;
Expand Down
9 changes: 7 additions & 2 deletions parseagle/common/domelement.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include <memory>
#include <QtCore>
#include <QtXml/QtXml>

namespace parseagle {

Expand All @@ -13,9 +12,13 @@ class DomElement final

// Constructors / Destructor
DomElement() = delete;
explicit DomElement(const QDomElement& root);
~DomElement() noexcept;

// Parsers
static DomElement parse(QXmlStreamReader& reader);
static DomElement parse(const QString& data);
static DomElement parse(const QByteArray& data);

// Getters
const QString& getTagName() const noexcept {return mName;}
const QString& getText() const noexcept {return mText;}
Expand All @@ -30,6 +33,8 @@ class DomElement final


private:
explicit DomElement(QXmlStreamReader& reader);

QString mName;
QString mText;
QHash<QString, QString> mAttributes;
Expand Down
13 changes: 3 additions & 10 deletions parseagle/library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,9 @@ Library::~Library() noexcept

void Library::load(const QByteArray& content, QStringList* errors)
{
QDomDocument doc;
doc.implementation().setInvalidDataPolicy(QDomImplementation::ReturnNullNode);
QString errMsg;
if (!doc.setContent(content, &errMsg)) {
throw std::runtime_error(
"Error while parsing EAGLE library: " + errMsg.toStdString());
}
DomElement root(doc.documentElement());
DomElement drawing = root.getFirstChild("drawing");
DomElement library = drawing.getFirstChild("library");
const DomElement root = DomElement::parse(content);
const DomElement drawing = root.getFirstChild("drawing");
const DomElement library = drawing.getFirstChild("library");
load(library, errors);
}

Expand Down
13 changes: 3 additions & 10 deletions parseagle/schematic/schematic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,14 @@ Schematic::~Schematic() noexcept
}

void Schematic::load(const QByteArray& content, QStringList* errors) {
QDomDocument doc;
doc.implementation().setInvalidDataPolicy(QDomImplementation::ReturnNullNode);
QString errMsg;
if (!doc.setContent(content, &errMsg)) {
throw std::runtime_error(
"Error while parsing EAGLE schematic: " + errMsg.toStdString());
}
DomElement root(doc.documentElement());
DomElement drawing = root.getFirstChild("drawing");
const DomElement root = DomElement::parse(content);
const DomElement drawing = root.getFirstChild("drawing");

if (drawing.hasChild("grid")) {
mGrid = Grid(drawing.getFirstChild("grid"));
}

DomElement schematic = drawing.getFirstChild("schematic");
const DomElement schematic = drawing.getFirstChild("schematic");
if (schematic.hasChild("description")) {
mDescription = schematic.getFirstChild("description").getText();
}
Expand Down