Refactored DBC loading code a bit to get some of the complication out of the main loop. Fixed loading DBC files where the nodes are on separate lines. Updated version num.

This commit is contained in:
Collin Kidder
2018-01-15 22:45:20 -05:00
parent 82b92e55b7
commit 80d7b8a993
3 changed files with 455 additions and 381 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef CONFIG
#define CONFIG
#define VERSION 182
#define VERSION 183
//try to keep this in sync.
//SavvyCAN will complain if you connect a GVRET board with a revision
+260 -191
View File
@@ -326,38 +326,13 @@ void DBCFile::findAttributesByType(DBC_ATTRIBUTE_TYPE typ, QList<DBC_ATTRIBUTE>
}
}
void DBCFile::loadFile(QString fileName)
DBC_MESSAGE* DBCFile::parseMessageLine(QString line)
{
QFile *inFile = new QFile(fileName);
QString line;
QRegularExpression regex;
QRegularExpressionMatch match;
DBC_MESSAGE *currentMessage = NULL;
DBC_ATTRIBUTE attr;
int numSigFaults = 0, numMsgFaults = 0;
qDebug() << "DBC File: " << fileName;
DBC_MESSAGE *msgPtr;
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
{
delete inFile;
return;
}
qDebug() << "Starting DBC load";
dbc_nodes.clear();
messageHandler->removeAllMessages();
messageHandler->setJ1939(false);
DBC_NODE falseNode;
falseNode.name = "Vector__XXX";
falseNode.comment = "Default node if none specified";
dbc_nodes.append(falseNode);
while (!inFile->atEnd()) {
line = QString(inFile->readLine().simplified());
if (line.startsWith("BO_ ")) //defines a message
{
qDebug() << "Found a BO line";
regex.setPattern("^BO\\_ (\\w+) (\\w+) *: (\\w+) (\\w+)");
match = regex.match(line);
@@ -373,12 +348,17 @@ void DBCFile::loadFile(QString fileName)
msg.len = match.captured(3).toInt();
msg.sender = findNodeByName(match.captured(4));
messageHandler->addMessage(msg);
currentMessage = messageHandler->findMsgByID(msg.ID);
msgPtr = messageHandler->findMsgByID(msg.ID);
}
else numMsgFaults++;
else msgPtr = nullptr;
return msgPtr;
}
if (line.startsWith("SG_ ")) //defines a signal
DBC_SIGNAL* DBCFile::parseSignalLine(QString line, DBC_MESSAGE *msg)
{
QRegularExpression regex;
QRegularExpressionMatch match;
int offset = 0;
bool isMultiplexor = false;
//bool isMultiplexed = false;
@@ -473,93 +453,20 @@ void DBCFile::loadFile(QString fileName)
sig.receiver = findNodeByName(tmp);
}
else sig.receiver = findNodeByName(match.captured(11 + offset));
sig.parentMessage = currentMessage;
currentMessage->sigHandler->addSignal(sig);
if (isMultiplexor) currentMessage->multiplexorSignal = currentMessage->sigHandler->findSignalByName(sig.name);
sig.parentMessage = msg;
msg->sigHandler->addSignal(sig);
if (isMultiplexor) msg->multiplexorSignal = msg->sigHandler->findSignalByName(sig.name);
return msg->sigHandler->findSignalByName(sig.name);
}
else numSigFaults++;
return nullptr;
}
if (line.startsWith("BU_:")) //line specifies the nodes on this canbus
{
qDebug() << "Found a BU line";
regex.setPattern("^BU\\_\\:(.*)");
match = regex.match(line);
//captured 1 = a list of node names separated by spaces. No idea how many yet
if (match.hasMatch())
{
QStringList nodeStrings = match.captured(1).split(' ');
qDebug() << "Found " << nodeStrings.count() << " node names";
for (int i = 0; i < nodeStrings.count(); i++)
{
//qDebug() << nodeStrings[i];
if (nodeStrings[i].length() > 1)
{
DBC_NODE node;
node.name = nodeStrings[i];
dbc_nodes.append(node);
}
}
}
}
if (line.startsWith("CM_ SG_ "))
{
qDebug() << "Found an SG comment line";
regex.setPattern("^CM\\_ SG\\_ *(\\w+) *(\\w+) *\\\"(.*)\\\";");
match = regex.match(line);
//captured 1 is the ID to match against to get to the message
//captured 2 is the signal name from that message
//captured 3 is the comment itself
if (match.hasMatch())
{
//qDebug() << "Comment was: " << match.captured(3);
DBC_MESSAGE *msg = messageHandler->findMsgByID(match.captured(1).toInt());
if (msg != NULL)
{
DBC_SIGNAL *sig = msg->sigHandler->findSignalByName(match.captured(2));
if (sig != NULL)
{
sig->comment = match.captured(3);
}
}
}
}
if (line.startsWith("CM_ BO_ "))
{
qDebug() << "Found a BO comment line";
regex.setPattern("^CM\\_ BO\\_ *(\\w+) *\\\"(.*)\\\";");
match = regex.match(line);
//captured 1 is the ID to match against to get to the message
//captured 2 is the comment itself
if (match.hasMatch())
{
//qDebug() << "Comment was: " << match.captured(2);
DBC_MESSAGE *msg = messageHandler->findMsgByID(match.captured(1).toInt());
if (msg != NULL)
{
msg->comment = match.captured(2);
}
}
}
if (line.startsWith("CM_ BU_ "))
{
qDebug() << "Found a BU comment line";
regex.setPattern("^CM\\_ BU\\_ *(\\w+) *\\\"(.*)\\\";");
match = regex.match(line);
//captured 1 is the Node name
//captured 2 is the comment itself
if (match.hasMatch())
{
//qDebug() << "Comment was: " << match.captured(2);
DBC_NODE *node = findNodeByName(match.captured(1));
if (node != NULL)
{
node->comment = match.captured(2);
}
}
}
//VAL_ (1090) (VCUPresentParkLightOC) (1 "Error present" 0 "Error not present") ;
if (line.startsWith("VAL_ "))
bool DBCFile::parseValueLine(QString line)
{
QRegularExpression regex;
QRegularExpressionMatch match;
qDebug() << "Found a value definition line";
regex.setPattern("^VAL\\_ (\\w+) (\\w+) (.*);");
match = regex.match(line);
@@ -594,88 +501,18 @@ void DBCFile::loadFile(QString fileName)
}
else tokenString = "";
}
return true;
}
}
}
return false;
}
if (line.startsWith("BA_DEF_ SG_ "))
bool DBCFile::parseAttributeLine(QString line)
{
qDebug() << "Found a SG attribute line";
QRegularExpression regex;
QRegularExpressionMatch match;
if (parseAttribute(line.right(line.length() - 12), attr))
{
qDebug() << "Success";
attr.attrType = SIG;
dbc_attributes.append(attr);
}
}
if (line.startsWith("BA_DEF_ BO_ ")) //definition of a message attribute
{
qDebug() << "Found a BO attribute line";
if (parseAttribute(line.right(line.length() - 12), attr))
{
qDebug() << "Success";
attr.attrType = MESSAGE;
dbc_attributes.append(attr);
}
}
if (line.startsWith("BA_DEF_ BU_ ")) //definition of a node attribute
{
qDebug() << "Found a BU attribute line";
if (parseAttribute(line.right(line.length() - 12), attr))
{
qDebug() << "Success";
attr.attrType = NODE;
dbc_attributes.append(attr);
}
}
if (line.startsWith("BA_DEF_DEF_ ")) //definition of default value for an attribute
{
regex.setPattern("^BA\\_DEF\\_DEF\\_ \\\"*(\\w+)\\\"* \\\"*([#\\w]*)\\\"*");
match = regex.match(line);
//captured 1 is the name of the attribute
//captured 2 is the default value for that attribute
if (match.hasMatch())
{
qDebug() << "Found an attribute default value line, searching for an attribute named " << match.captured(1) << "with data " << match.captured(2);
DBC_ATTRIBUTE *found = findAttributeByName(match.captured(1));
if (found)
{
switch (found->valType)
{
case QSTRING:
found->defaultValue = match.captured(2);
break;
case QFLOAT:
found->defaultValue = match.captured(2).toFloat();
break;
case QINT:
found->defaultValue = match.captured(2).toInt();
break;
case ENUM:
QString temp = match.captured(2);
found->defaultValue = 0;
for (int x = 0; x < found->enumVals.count(); x++)
{
if (!found->enumVals[x].compare(temp, Qt::CaseInsensitive))
{
found->defaultValue = x;
break;
}
}
}
qDebug() << "Matched an attribute. Setting default value to " << found->defaultValue;
}
}
}
//BA_ "GenMsgCycleTime" BO_ 101 100;
if (line.startsWith("BA_ ")) //set value of attribute
{
regex.setPattern("^BA\\_ \\\"*(\\w+)\\\"* BO\\_ (\\d+) \\\"*([#\\w]+)\\\"*");
match = regex.match(line);
//captured 1 is the attribute name
@@ -767,8 +604,242 @@ void DBCFile::loadFile(QString fileName)
foundNode->attributes.append(val);
}
}
return true;
}
}
return false;
}
bool DBCFile::parseDefaultAttrLine(QString line)
{
QRegularExpression regex;
QRegularExpressionMatch match;
regex.setPattern("^BA\\_DEF\\_DEF\\_ \\\"*(\\w+)\\\"* \\\"*([#\\w]*)\\\"*");
match = regex.match(line);
//captured 1 is the name of the attribute
//captured 2 is the default value for that attribute
if (match.hasMatch())
{
qDebug() << "Found an attribute default value line, searching for an attribute named " << match.captured(1) << "with data " << match.captured(2);
DBC_ATTRIBUTE *found = findAttributeByName(match.captured(1));
if (found)
{
switch (found->valType)
{
case QSTRING:
found->defaultValue = match.captured(2);
break;
case QFLOAT:
found->defaultValue = match.captured(2).toFloat();
break;
case QINT:
found->defaultValue = match.captured(2).toInt();
break;
case ENUM:
QString temp = match.captured(2);
found->defaultValue = 0;
for (int x = 0; x < found->enumVals.count(); x++)
{
if (!found->enumVals[x].compare(temp, Qt::CaseInsensitive))
{
found->defaultValue = x;
break;
}
}
}
qDebug() << "Matched an attribute. Setting default value to " << found->defaultValue;
return true;
}
}
return false;
}
void DBCFile::loadFile(QString fileName)
{
QFile *inFile = new QFile(fileName);
QString line, rawLine;
QRegularExpression regex;
QRegularExpressionMatch match;
DBC_MESSAGE *currentMessage = NULL;
DBC_ATTRIBUTE attr;
int numSigFaults = 0, numMsgFaults = 0;
bool inMultilineBU = false;
qDebug() << "DBC File: " << fileName;
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
{
delete inFile;
return;
}
qDebug() << "Starting DBC load";
dbc_nodes.clear();
messageHandler->removeAllMessages();
messageHandler->setJ1939(false);
DBC_NODE falseNode;
falseNode.name = "Vector__XXX";
falseNode.comment = "Default node if none specified";
dbc_nodes.append(falseNode);
while (!inFile->atEnd()) {
rawLine = QString(inFile->readLine());
line = rawLine.simplified();
if (inMultilineBU)
{
if (rawLine.startsWith("\t") || rawLine.startsWith(" "))
{
DBC_NODE node;
node.name = line;
dbc_nodes.append(node);
}
else inMultilineBU = false;
}
if (!inMultilineBU)
{
if (line.startsWith("BO_ ")) //defines a message
{
currentMessage = parseMessageLine(line);
if (currentMessage == nullptr) numMsgFaults++;
}
if (line.startsWith("SG_ ")) //defines a signal
{
if (!parseSignalLine(line, currentMessage)) numSigFaults++;
}
if (line.startsWith("BU_:")) //line specifies the nodes on this canbus
{
qDebug() << "Found a BU line";
regex.setPattern("^BU\\_\\:(.*)");
match = regex.match(line);
//captured 1 = a list of node names separated by spaces. No idea how many yet
if (match.hasMatch())
{
QStringList nodeStrings = match.captured(1).split(' ');
qDebug() << "Found " << nodeStrings.count() << " node names";
for (int i = 0; i < nodeStrings.count(); i++)
{
//qDebug() << nodeStrings[i];
if (nodeStrings[i].length() > 1)
{
DBC_NODE node;
node.name = nodeStrings[i];
dbc_nodes.append(node);
}
}
inMultilineBU = true; //we might be... Need to check next line.
}
}
if (line.startsWith("CM_ SG_ "))
{
qDebug() << "Found an SG comment line";
regex.setPattern("^CM\\_ SG\\_ *(\\w+) *(\\w+) *\\\"(.*)\\\";");
match = regex.match(line);
//captured 1 is the ID to match against to get to the message
//captured 2 is the signal name from that message
//captured 3 is the comment itself
if (match.hasMatch())
{
//qDebug() << "Comment was: " << match.captured(3);
DBC_MESSAGE *msg = messageHandler->findMsgByID(match.captured(1).toInt());
if (msg != NULL)
{
DBC_SIGNAL *sig = msg->sigHandler->findSignalByName(match.captured(2));
if (sig != NULL)
{
sig->comment = match.captured(3);
}
}
}
}
if (line.startsWith("CM_ BO_ "))
{
qDebug() << "Found a BO comment line";
regex.setPattern("^CM\\_ BO\\_ *(\\w+) *\\\"(.*)\\\";");
match = regex.match(line);
//captured 1 is the ID to match against to get to the message
//captured 2 is the comment itself
if (match.hasMatch())
{
//qDebug() << "Comment was: " << match.captured(2);
DBC_MESSAGE *msg = messageHandler->findMsgByID(match.captured(1).toInt());
if (msg != NULL)
{
msg->comment = match.captured(2);
}
}
}
if (line.startsWith("CM_ BU_ "))
{
qDebug() << "Found a BU comment line";
regex.setPattern("^CM\\_ BU\\_ *(\\w+) *\\\"(.*)\\\";");
match = regex.match(line);
//captured 1 is the Node name
//captured 2 is the comment itself
if (match.hasMatch())
{
//qDebug() << "Comment was: " << match.captured(2);
DBC_NODE *node = findNodeByName(match.captured(1));
if (node != NULL)
{
node->comment = match.captured(2);
}
}
}
//VAL_ (1090) (VCUPresentParkLightOC) (1 "Error present" 0 "Error not present") ;
if (line.startsWith("VAL_ "))
{
parseValueLine(line);
}
if (line.startsWith("BA_DEF_ SG_ "))
{
qDebug() << "Found a SG attribute line";
if (parseAttribute(line.right(line.length() - 12), attr))
{
qDebug() << "Success";
attr.attrType = SIG;
dbc_attributes.append(attr);
}
}
if (line.startsWith("BA_DEF_ BO_ ")) //definition of a message attribute
{
qDebug() << "Found a BO attribute line";
if (parseAttribute(line.right(line.length() - 12), attr))
{
qDebug() << "Success";
attr.attrType = MESSAGE;
dbc_attributes.append(attr);
}
}
if (line.startsWith("BA_DEF_ BU_ ")) //definition of a node attribute
{
qDebug() << "Found a BU attribute line";
if (parseAttribute(line.right(line.length() - 12), attr))
{
qDebug() << "Success";
attr.attrType = NODE;
dbc_attributes.append(attr);
}
}
if (line.startsWith("BA_DEF_DEF_ ")) //definition of default value for an attribute
{
parseDefaultAttrLine(line);
}
//BA_ "GenMsgCycleTime" BO_ 101 100;
if (line.startsWith("BA_ ")) //set value of attribute
{
parseAttributeLine(line);
}
}
}
@@ -818,8 +889,6 @@ void DBCFile::loadFile(QString fileName)
DBC_ATTRIBUTE_VALUE *thisBG;
DBC_ATTRIBUTE_VALUE *thisFG;
for (int x = 0; x < messageHandler->getCount(); x++)
{
DBC_MESSAGE *msg = messageHandler->findMsgByIdx(x);
+5
View File
@@ -79,6 +79,11 @@ private:
bool parseAttribute(QString inpString, DBC_ATTRIBUTE &attr);
QVariant processAttributeVal(QString input, DBC_ATTRIBUTE_VAL_TYPE typ);
DBC_SIGNAL* parseSignalLine(QString line, DBC_MESSAGE *msg);
DBC_MESSAGE* parseMessageLine(QString line);
bool parseValueLine(QString line);
bool parseAttributeLine(QString line);
bool parseDefaultAttrLine(QString line);
};
class DBCHandler: public QObject