cabana(DBCFile): handle escaped quotes (#31889)

* cabana(DBCFile): VAL_ allow empty description

Even though this doesn't make much sense, we should still be able to
parse it.

* cabana(DBCFile): allow escaped quotemarks in signal comment

* also message comments

* escape/unescape quotes

* test empty val desc

* test generating DBC with escaped quotes in comment

* seperate test case

* fix trailing space

* remove empty val

* trailing whitespace again
pull/31896/head
Cameron Clough 1 year ago committed by GitHub
parent 3f81ea2e0e
commit d09e77d1af
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 12
      tools/cabana/dbc/dbcfile.cc
  2. 21
      tools/cabana/tests/test_cabana.cc

@ -80,8 +80,8 @@ void DBCFile::parse(const QString &content) {
static QRegularExpression bo_regexp(R"(^BO_ (\w+) (\w+) *: (\w+) (\w+))"); static QRegularExpression bo_regexp(R"(^BO_ (\w+) (\w+) *: (\w+) (\w+))");
static QRegularExpression sg_regexp(R"(^SG_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*))"); static QRegularExpression sg_regexp(R"(^SG_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*))");
static QRegularExpression sgm_regexp(R"(^SG_ (\w+) (\w+) *: (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*))"); static QRegularExpression sgm_regexp(R"(^SG_ (\w+) (\w+) *: (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*))");
static QRegularExpression msg_comment_regexp(R"(^CM_ BO_ *(\w+) *\"([^"]*)\"\s*;)"); static QRegularExpression msg_comment_regexp(R"(^CM_ BO_ *(\w+) *\"((?:[^"\\]|\\.)*)\"\s*;)");
static QRegularExpression sg_comment_regexp(R"(^CM_ SG_ *(\w+) *(\w+) *\"([^"]*)\"\s*;)"); static QRegularExpression sg_comment_regexp(R"(^CM_ SG_ *(\w+) *(\w+) *\"((?:[^"\\]|\\.)*)\"\s*;)");
static QRegularExpression val_regexp(R"(VAL_ (\w+) (\w+) (\s*[-+]?[0-9]+\s+\".+?\"[^;]*))"); static QRegularExpression val_regexp(R"(VAL_ (\w+) (\w+) (\s*[-+]?[0-9]+\s+\".+?\"[^;]*))");
int line_num = 0; int line_num = 0;
@ -173,7 +173,7 @@ void DBCFile::parse(const QString &content) {
auto match = msg_comment_regexp.match(line); auto match = msg_comment_regexp.match(line);
dbc_assert(match.hasMatch()); dbc_assert(match.hasMatch());
if (auto m = (cabana::Msg *)msg(match.captured(1).toUInt())) { if (auto m = (cabana::Msg *)msg(match.captured(1).toUInt())) {
m->comment = match.captured(2).trimmed(); m->comment = match.captured(2).trimmed().replace("\\\"", "\"");
} }
} else if (line.startsWith("CM_ SG_ ")) { } else if (line.startsWith("CM_ SG_ ")) {
if (!line.endsWith("\";")) { if (!line.endsWith("\";")) {
@ -183,7 +183,7 @@ void DBCFile::parse(const QString &content) {
auto match = sg_comment_regexp.match(line); auto match = sg_comment_regexp.match(line);
dbc_assert(match.hasMatch()); dbc_assert(match.hasMatch());
if (auto s = get_sig(match.captured(1).toUInt(), match.captured(2))) { if (auto s = get_sig(match.captured(1).toUInt(), match.captured(2))) {
s->comment = match.captured(3).trimmed(); s->comment = match.captured(3).trimmed().replace("\\\"", "\"");
} }
} else { } else {
seen = false; seen = false;
@ -207,7 +207,7 @@ QString DBCFile::generateDBC() {
const QString transmitter = m.transmitter.isEmpty() ? DEFAULT_NODE_NAME : m.transmitter; const QString transmitter = m.transmitter.isEmpty() ? DEFAULT_NODE_NAME : m.transmitter;
dbc_string += QString("BO_ %1 %2: %3 %4\n").arg(address).arg(m.name).arg(m.size).arg(transmitter); dbc_string += QString("BO_ %1 %2: %3 %4\n").arg(address).arg(m.name).arg(m.size).arg(transmitter);
if (!m.comment.isEmpty()) { if (!m.comment.isEmpty()) {
comment += QString("CM_ BO_ %1 \"%2\";\n").arg(address).arg(m.comment); comment += QString("CM_ BO_ %1 \"%2\";\n").arg(address).arg(QString(m.comment).replace("\"", "\\\""));
} }
for (auto sig : m.getSignals()) { for (auto sig : m.getSignals()) {
QString multiplexer_indicator; QString multiplexer_indicator;
@ -230,7 +230,7 @@ QString DBCFile::generateDBC() {
.arg(sig->unit) .arg(sig->unit)
.arg(sig->receiver_name.isEmpty() ? DEFAULT_NODE_NAME : sig->receiver_name); .arg(sig->receiver_name.isEmpty() ? DEFAULT_NODE_NAME : sig->receiver_name);
if (!sig->comment.isEmpty()) { if (!sig->comment.isEmpty()) {
comment += QString("CM_ SG_ %1 %2 \"%3\";\n").arg(address).arg(sig->name).arg(sig->comment); comment += QString("CM_ SG_ %1 %2 \"%3\";\n").arg(address).arg(sig->name).arg(QString(sig->comment).replace("\"", "\\\""));
} }
if (!sig->val_desc.empty()) { if (!sig->val_desc.empty()) {
QStringList text; QStringList text;

@ -65,6 +65,17 @@ CM_ SG_ 160 signal_1 "signal comment";
REQUIRE(dbc.generateDBC() == content); REQUIRE(dbc.generateDBC() == content);
} }
TEST_CASE("DBCFile::generateDBC - escaped quotes") {
QString content = R"(BO_ 160 message_1: 8 EON
SG_ signal_1 : 0|12@1+ (1,0) [0|4095] "unit" XXX
CM_ BO_ 160 "message comment with \"escaped quotes\"";
CM_ SG_ 160 signal_1 "signal comment with \"escaped quotes\"";
)";
DBCFile dbc("", content);
REQUIRE(dbc.generateDBC() == content);
}
TEST_CASE("parse_dbc") { TEST_CASE("parse_dbc") {
QString content = R"( QString content = R"(
BO_ 160 message_1: 8 EON BO_ 160 message_1: 8 EON
@ -82,7 +93,11 @@ CM_ SG_ 160 signal_1 "signal comment";
CM_ SG_ 160 signal_2 "multiple line comment CM_ SG_ 160 signal_2 "multiple line comment
1 1
2 2
";)"; ";
CM_ BO_ 162 "message comment with \"escaped quotes\"";
CM_ SG_ 162 signal_1 "signal comment with \"escaped quotes\"";
)";
DBCFile file("", content); DBCFile file("", content);
auto msg = file.msg(160); auto msg = file.msg(160);
@ -121,6 +136,10 @@ CM_ SG_ 160 signal_2 "multiple line comment
REQUIRE(msg->sigs[1]->start_bit == 12); REQUIRE(msg->sigs[1]->start_bit == 12);
REQUIRE(msg->sigs[1]->size == 1); REQUIRE(msg->sigs[1]->size == 1);
REQUIRE(msg->sigs[1]->receiver_name == "XXX"); REQUIRE(msg->sigs[1]->receiver_name == "XXX");
// escaped quotes
REQUIRE(msg->comment == "message comment with \"escaped quotes\"");
REQUIRE(msg->sigs[0]->comment == "signal comment with \"escaped quotes\"");
} }
TEST_CASE("parse_opendbc") { TEST_CASE("parse_opendbc") {

Loading…
Cancel
Save