From d5fd6a83d89ab0d7f4edf25ab8db0b8dae42645c Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Thu, 30 Jan 2020 17:07:48 +0300 Subject: Debugger: Improve parsing of SVD file The previous implementation was done in a hurry and a bit overcomplicated for maintenance. Now it is simplified and a common code moved to a separate functions. Change-Id: I86e9131e08154ec24bb7778c3a7d4c3d6b042751 Reviewed-by: hjk --- src/plugins/debugger/peripheralregisterhandler.cpp | 255 +++++++++++---------- 1 file changed, 131 insertions(+), 124 deletions(-) diff --git a/src/plugins/debugger/peripheralregisterhandler.cpp b/src/plugins/debugger/peripheralregisterhandler.cpp index 1603faf3dc..57f69338db 100644 --- a/src/plugins/debugger/peripheralregisterhandler.cpp +++ b/src/plugins/debugger/peripheralregisterhandler.cpp @@ -52,6 +52,8 @@ constexpr char kBitRange[] = "bitRange"; constexpr char kBitWidth[] = "bitWidth"; constexpr char kDerivedFrom[] = "derivedFrom"; constexpr char kDescription[] = "description"; +constexpr char kDevice[] = "device"; +constexpr char kDisplayName[] = "displayName"; constexpr char kField[] = "field"; constexpr char kFields[] = "fields"; constexpr char kGroupName[] = "groupName"; @@ -559,135 +561,141 @@ PeripheralRegisterHandler::PeripheralRegisterHandler(DebuggerEngine *engine) setHeader({tr("Name"), tr("Value"), tr("Access")}); } -static PeripheralRegisterGroups availablePeripheralRegisterGroups( - const QString &filePath) -{ - QFile f(filePath); - if (!f.open(QIODevice::ReadOnly)) - return {}; +static void handleField(QXmlStreamReader &in, PeripheralRegister ®) +{ + PeripheralRegisterField fld; + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kName) { + fld.name = in.readElementText(); + } else if (elementName == kDescription) { + fld.description = in.readElementText(); + } else if (elementName == kAccess) { + fld.access = decodeAccess(in.readElementText()); + } else if (elementName == kBitRange) { + const QString elementText = in.readElementText(); + const int startBracket = elementText.indexOf('['); + const int endBracket = elementText.indexOf(']'); + if (startBracket == -1 || endBracket == -1 || (endBracket - startBracket) <= 0) + continue; + const QString range = elementText.mid(startBracket + 1, endBracket - 1); + const QStringList items = range.split(':'); + enum { MaxBit, MinBit, BitsCount }; + if (items.count() != BitsCount) + continue; + const int from = int(decodeNumeric(items.at(MinBit))); + const int to = int(decodeNumeric(items.at(MaxBit))); + fld.bitOffset = from; + fld.bitWidth = to - from + 1; + } else if (elementName == kBitOffset) { + fld.bitOffset = int(decodeNumeric(in.readElementText())); + } else if (elementName == kBitWidth) { + fld.bitWidth = int(decodeNumeric(in.readElementText())); + } else { + in.skipCurrentElement(); + } + } + reg.fields.push_back(fld); +} + +static void handleRegister(QXmlStreamReader &in, PeripheralRegisterGroup &group) +{ + PeripheralRegister reg; + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kName) { + reg.name = in.readElementText(); + } else if (elementName == kDisplayName) { + reg.displayName = in.readElementText(); + } else if (elementName == kDescription) { + reg.description = in.readElementText(); + } else if (elementName == kAddressOffset) { + reg.addressOffset = decodeNumeric(in.readElementText()); + } else if (elementName == kSize) { + reg.size = int(decodeNumeric(in.readElementText())); + } else if (elementName == kAccess) { + reg.access = decodeAccess(in.readElementText()); + } else if (elementName == kResetvalue) { + reg.resetValue = decodeNumeric(in.readElementText()); + } else if (elementName == kFields) { + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kField) + handleField(in, reg); + else + in.skipCurrentElement(); + } + } else { + in.skipCurrentElement(); + } + } + group.registers.push_back(reg); +} - QXmlStreamReader in(&f); +static void handleGroup(QXmlStreamReader &in, PeripheralRegisterGroups &groups) +{ + PeripheralRegisterGroup group; - PeripheralRegisterGroups foundGroups; + const auto fromGroupName = in.attributes().value(kDerivedFrom); + if (!fromGroupName.isEmpty()) { + const auto groupEnd = groups.cend(); + const auto groupIt = std::find_if(groups.cbegin(), groupEnd, + [fromGroupName](const PeripheralRegisterGroup &group) { + return fromGroupName == group.name; + }); + if (groupIt != groupEnd) + group = *groupIt; + } - while (!in.atEnd()) { - const auto token = in.readNext(); - if (token == QXmlStreamReader::EndElement - && in.name() == QLatin1String(kPeripherals)) { - break; - } else if (token != QXmlStreamReader::StartElement - || in.name() != QLatin1String(kPeripheral)) { - continue; + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kName) { + group.name = in.readElementText(); + } else if (elementName == kDescription) { + group.description = in.readElementText(); + } else if (elementName == kGroupName) { + group.displayName = in.readElementText(); + } else if (elementName == kBaseAddress) { + group.baseAddress = decodeNumeric(in.readElementText()); + } else if (elementName == kSize) { + group.size = int(decodeNumeric(in.readElementText())); + } else if (elementName == kAccess) { + group.access = decodeAccess(in.readElementText()); + } else if (elementName == kRegisters) { + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kRegister) + handleRegister(in, group); + else + in.skipCurrentElement(); + } + } else { + in.skipCurrentElement(); } + } + groups.push_back(group); +} - PeripheralRegisterGroup group; +static PeripheralRegisterGroups availablePeripheralRegisterGroups(const QString &filePath) +{ + QFile f(filePath); + if (!f.open(QIODevice::ReadOnly)) + return {}; - const auto fromGroupName = in.attributes().value( - QLatin1String(kDerivedFrom)); - const auto foundGroupEnd = foundGroups.cend(); - const auto foundGroupIt = std::find_if( - foundGroups.cbegin(), foundGroupEnd, - [fromGroupName](const PeripheralRegisterGroup &foundGroup) { - return fromGroupName == foundGroup.name; - }); - if (foundGroupIt != foundGroupEnd) - group = *foundGroupIt; - - while (!in.atEnd()) { - const auto token = in.readNext(); - if (token == QXmlStreamReader::EndElement - && in.name() == QLatin1String(kPeripheral)) { - foundGroups.push_back(group); - break; - } else if (token == QXmlStreamReader::StartElement) { + QXmlStreamReader in(&f); + PeripheralRegisterGroups groups; + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kDevice) { + while (in.readNextStartElement()) { const auto elementName = in.name(); - if (elementName == QLatin1String(kName)) { - group.name = in.readElementText(); - } else if (elementName == QLatin1String(kDescription)) { - group.description = in.readElementText(); - } else if (elementName == QLatin1String(kGroupName)) { - group.displayName = in.readElementText(); - } else if (elementName == QLatin1String(kBaseAddress)) { - group.baseAddress = decodeNumeric(in.readElementText()); - } else if (elementName == QLatin1String(kSize)) { - group.size = int(decodeNumeric(in.readElementText())); - } else if (elementName == QLatin1String(kAccess)) { - group.access = decodeAccess(in.readElementText()); - } else if (elementName == QLatin1String(kRegisters) - || elementName == QLatin1String(kRegister)) { - PeripheralRegister reg; - while (!in.atEnd()) { - const auto token = in.readNext(); - if (token == QXmlStreamReader::EndElement - && in.name() == QLatin1String(kRegister)) { - group.registers.push_back(reg); - break; - } else if (token == QXmlStreamReader::StartElement) { - const auto elementName = in.name(); - if (elementName == QLatin1String(kRegister)) { - continue; - } else if (elementName == QLatin1String(kName)) { - reg.name = in.readElementText(); - } else if (elementName == QLatin1String(kDescription)) { - reg.description = in.readElementText(); - } else if (elementName == QLatin1String(kAddressOffset)) { - reg.addressOffset = decodeNumeric(in.readElementText()); - } else if (elementName == QLatin1String(kSize)) { - reg.size = int(decodeNumeric(in.readElementText())); - } else if (elementName == QLatin1String(kAccess)) { - reg.access = decodeAccess(in.readElementText()); - } else if (elementName == QLatin1String(kResetvalue)) { - reg.resetValue = decodeNumeric(in.readElementText()); - } else if (elementName == QLatin1String(kFields) - || elementName == QLatin1String(kField)) { - PeripheralRegisterField fld; - while (!in.atEnd()) { - const auto token = in.readNext(); - if (token == QXmlStreamReader::EndElement - && in.name() == QLatin1String(kField)) { - reg.fields.push_back(fld); - break; - } else if (token == QXmlStreamReader::StartElement) { - const auto elementName = in.name(); - if (elementName == QLatin1String(kField)) { - continue; - } else if (elementName == QLatin1String(kName)) { - fld.name = in.readElementText(); - } else if (elementName == QLatin1String(kDescription)) { - fld.description = in.readElementText(); - } else if (elementName == QLatin1String(kAccess)) { - fld.access = decodeAccess(in.readElementText()); - } else if (elementName == QLatin1String(kBitRange)) { - const QString elementText = in.readElementText(); - const int startBracket = elementText.indexOf('['); - const int endBracket = elementText.indexOf(']'); - if (startBracket == -1 || endBracket == -1 - || (endBracket - startBracket) <= 0) { - continue; - } - const QString range = elementText.mid( - startBracket + 1, endBracket - 1); - const QStringList items = range.split(':'); - enum { MaxBit, MinBit, BitsCount }; - if (items.count() != BitsCount) - continue; - const int from = int(decodeNumeric(items.at(MinBit))); - const int to = int(decodeNumeric(items.at(MaxBit))); - fld.bitOffset = from; - fld.bitWidth = to - from + 1; - } else if (elementName == QLatin1String(kBitOffset)) { - fld.bitOffset = int(decodeNumeric(in.readElementText())); - } else if (elementName == QLatin1String(kBitWidth)) { - fld.bitWidth = int(decodeNumeric(in.readElementText())); - } else { - in.skipCurrentElement(); - } - } - } - } else { - in.skipCurrentElement(); - } - } + if (elementName == kPeripherals) { + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kPeripheral) + handleGroup(in, groups); + else + in.skipCurrentElement(); } } else { in.skipCurrentElement(); @@ -695,8 +703,7 @@ static PeripheralRegisterGroups availablePeripheralRegisterGroups( } } } - - return foundGroups; + return groups; } void PeripheralRegisterHandler::updateRegisterGroups() -- cgit v1.2.1