From b4de4dfdf0a0adf28db3ceef000919c448ff8494 Mon Sep 17 00:00:00 2001 From: Michele Tesser Date: Mon, 13 Apr 2026 18:49:18 +0200 Subject: [PATCH] VAL_TABLE_ support --- dbc/dbc_classes.h | 8 ++- dbc/dbchandler.cpp | 136 +++++++++++++++++++++++++++++++++++++++------ dbc/dbchandler.h | 3 + 3 files changed, 128 insertions(+), 19 deletions(-) diff --git a/dbc/dbc_classes.h b/dbc/dbc_classes.h index 96f0839..1109451 100644 --- a/dbc/dbc_classes.h +++ b/dbc/dbc_classes.h @@ -66,6 +66,13 @@ public: QString descript; }; +class DBC_VAL_TABLE +{ +public: + QString name; + QList valList; +}; + class DBC_NODE { public: @@ -176,4 +183,3 @@ public: #endif // DBC_CLASSES_H - diff --git a/dbc/dbchandler.cpp b/dbc/dbchandler.cpp index 6b2796b..f80dabd 100644 --- a/dbc/dbchandler.cpp +++ b/dbc/dbchandler.cpp @@ -16,6 +16,28 @@ DBCHandler* DBCHandler::instance = nullptr; +static bool parseValueDescriptions(QString tokenString, QList &values) +{ + QRegularExpression regex; + QRegularExpressionMatch match; + DBC_VAL_ENUM_ENTRY val; + + values.clear(); + tokenString = tokenString.trimmed(); + while (tokenString.length() > 2) + { + regex.setPattern("^([+-]?\\d+) \\\"(.*?)\\\"(.*)"); + match = regex.match(tokenString); + if (!match.hasMatch()) return false; + + val.value = match.captured(1).toInt(); + val.descript = match.captured(2); + values.append(val); + tokenString = match.captured(3).trimmed(); + } + return values.count() > 0; +} + DBC_SIGNAL* DBCSignalHandler::findSignalByIdx(int idx) { if (sigs.count() == 0) return nullptr; @@ -316,6 +338,8 @@ DBCFile::DBCFile(const DBCFile& cpy) : QObject() assocBuses = cpy.assocBuses; dbc_nodes.clear(); dbc_nodes.append(cpy.dbc_nodes); + dbc_value_tables.clear(); + dbc_value_tables.append(cpy.dbc_value_tables); dbc_attributes.clear(); dbc_attributes.append(cpy.dbc_attributes); isDirty = cpy.isDirty; @@ -331,6 +355,8 @@ DBCFile& DBCFile::operator=(const DBCFile& cpy) assocBuses = cpy.assocBuses; dbc_nodes.clear(); dbc_nodes.append(cpy.dbc_nodes); + dbc_value_tables.clear(); + dbc_value_tables.append(cpy.dbc_value_tables); dbc_attributes.clear(); dbc_attributes.append(cpy.dbc_attributes); } @@ -382,6 +408,19 @@ DBC_NODE* DBCFile::findNodeByNameAndComment(QString fullname) return nullptr; } +DBC_VAL_TABLE* DBCFile::findValueTableByName(QString name) +{ + if (dbc_value_tables.length() == 0) return nullptr; + for (int i = 0; i < dbc_value_tables.length(); i++) + { + if (name.compare(dbc_value_tables[i].name, Qt::CaseInsensitive) == 0) + { + return &dbc_value_tables[i]; + } + } + return nullptr; +} + QString DBCFile::getFullFilename() { return filePath + fileName; @@ -712,6 +751,29 @@ bool DBCFile::parseSignalValueTypeLine(QString line) } +bool DBCFile::parseValueTableLine(QString line) +{ + QRegularExpression regex; + QRegularExpressionMatch match; + + regex.setPattern("^VAL\\_TABLE\\_ ([-\\w]+) (.*);"); + match = regex.match(line); + //captured 1 is the table name + //captured 2 is a series of values in the form (number "text") + if (match.hasMatch()) + { + DBC_VAL_TABLE table; + table.name = match.captured(1); + if (!parseValueDescriptions(match.captured(2), table.valList)) return false; + + DBC_VAL_TABLE *existingTable = findValueTableByName(table.name); + if (existingTable) existingTable->valList = table.valList; + else dbc_value_tables.append(table); + return true; + } + return false; +} + bool DBCFile::parseValueLine(QString line) { QRegularExpression regex; @@ -733,25 +795,18 @@ bool DBCFile::parseValueLine(QString line) if (sig != nullptr) { QString tokenString = match.captured(3); - DBC_VAL_ENUM_ENTRY val; - while (tokenString.length() > 2) + QList values; + DBC_VAL_TABLE *valueTable = findValueTableByName(tokenString.trimmed()); + if (valueTable) { - regex.setPattern("(\\d+) \\\"(.*?)\\\"(.*)"); - match = regex.match(tokenString); - if (match.hasMatch()) - { - val.value = match.captured(1).toULong() & 0x1FFFFFFFul; - val.descript = match.captured(2); - //qDebug() << "sig val " << val.value << " desc " <valList.append(val); - int rightSize = tokenString.length() - match.captured(1).length() - match.captured(2).length() - 4; - if (rightSize > 0) tokenString = tokenString.right(rightSize); - else tokenString = ""; - //qDebug() << "New token string: " << tokenString; - } - else tokenString = ""; + sig->valList = valueTable->valList; + return true; + } + if (parseValueDescriptions(tokenString, values)) + { + sig->valList.append(values); + return true; } - return true; } } } @@ -919,6 +974,8 @@ bool DBCFile::loadFile(QString fileName) QString fileBaseName = QFileInfo(fileName).baseName(); bool inMultilineBU = false; + bool inMultilineValTable = false; + QString multilineValTable; qDebug() << "DBC File: " << fileName; @@ -931,6 +988,7 @@ bool DBCFile::loadFile(QString fileName) qDebug() << "Starting DBC load"; dbc_nodes.clear(); + dbc_value_tables.clear(); messageHandler->removeAllMessages(); messageHandler->setMatchingCriteria(EXACT); messageHandler->setFilterLabeling(false); @@ -962,6 +1020,18 @@ bool DBCFile::loadFile(QString fileName) else inMultilineBU = false; } + if (inMultilineValTable) + { + multilineValTable.append(" " + line); + if (line.endsWith(";")) + { + parseValueTableLine(multilineValTable); + multilineValTable.clear(); + inMultilineValTable = false; + } + continue; + } + if (!inMultilineBU) { if (line.startsWith("BO_ ")) //defines a message @@ -1064,6 +1134,19 @@ bool DBCFile::loadFile(QString fileName) } } } + if (line.startsWith("VAL_TABLE_ ")) + { + if (line.endsWith(";")) + { + parseValueTableLine(line); + } + else + { + multilineValTable = line; + inMultilineValTable = true; + } + } + //VAL_ (1090) (VCUPresentParkLightOC) (1 "Error present" 0 "Error not present") ; if (line.startsWith("VAL_ ")) { @@ -1347,7 +1430,7 @@ bool DBCFile::saveFile(QString fileName) int msgNumber = 1; int sigNumber = 1; QFile *outFile = new QFile(fileName); - QString nodesOutput, msgOutput, commentsOutput, valuesOutput, extMultiplexOutput; + QString nodesOutput, msgOutput, commentsOutput, valuesOutput, valueTableOutput, extMultiplexOutput; QString defaultsOutput, attrValOutput, sigValTypeOutput; bool hasExtendedMultiplexing = false; @@ -1433,6 +1516,23 @@ bool DBCFile::saveFile(QString fileName) nodesOutput.append("\n"); outFile->write(nodesOutput.toUtf8()); + for (int x = 0; x < dbc_value_tables.count(); x++) + { + DBC_VAL_TABLE table = dbc_value_tables[x]; + valueTableOutput.append("VAL_TABLE_ " + table.name); + for (int v = 0; v < table.valList.count(); v++) + { + DBC_VAL_ENUM_ENTRY val = table.valList[v]; + valueTableOutput.append(" " + QString::number(val.value) + " \"" + val.descript + "\""); + } + valueTableOutput.append(";\n"); + } + if (!valueTableOutput.isEmpty()) + { + outFile->write(valueTableOutput.toUtf8()); + valueTableOutput.clear(); + } + //Go through all messages one at at time issuing the message line then all signals in there too. for (int x = 0; x < messageHandler->getCount(); x++) { diff --git a/dbc/dbchandler.h b/dbc/dbchandler.h index 14f19f8..66f9b53 100644 --- a/dbc/dbchandler.h +++ b/dbc/dbchandler.h @@ -75,6 +75,7 @@ public: DBC_NODE *findNodeByName(QString name); DBC_NODE *findNodeByNameAndComment(QString fullname); DBC_NODE *findNodeByIdx(int idx); + DBC_VAL_TABLE *findValueTableByName(QString name); DBC_ATTRIBUTE *findAttributeByName(QString name, DBC_ATTRIBUTE_TYPE type = ATTR_TYPE_ANY); DBC_ATTRIBUTE *findAttributeByIdx(int idx); void findAttributesByType(DBC_ATTRIBUTE_TYPE typ, QList *list); @@ -93,6 +94,7 @@ public: DBCMessageHandler *messageHandler; QList dbc_nodes; + QList dbc_value_tables; QList dbc_attributes; private: QString fileName; @@ -105,6 +107,7 @@ private: DBC_SIGNAL* parseSignalLine(QString line, DBC_MESSAGE *msg); bool parseSignalMultiplexValueLine(QString line); DBC_MESSAGE* parseMessageLine(QString line); + bool parseValueTableLine(QString line); bool parseValueLine(QString line); bool parseSignalValueTypeLine(QString line); bool parseAttributeLine(QString line);