From 02e5cc471b8fd2d07cece8d8539033fdf5479393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Babski?= <rbabski@n7space.com> Date: Tue, 11 Jun 2024 22:05:10 +0100 Subject: [PATCH 1/3] Asn1ToPromelaTranslator: added support for string literals for constants --- .../visitors/valueassignmentvisitor.cpp | 78 +++++++++++++++++-- .../visitors/valueassignmentvisitor.h | 3 + 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp b/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp index 3b45931cd2..a9ba1b09d6 100644 --- a/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp +++ b/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp @@ -22,12 +22,15 @@ #include "sequencecomponentvaluevisitor.h" #include "sizeconstraintvisitor.h" +#include <QDebug> #include <asn1library/asn1/choicevalue.h> #include <asn1library/asn1/multiplevalue.h> #include <asn1library/asn1/namedvalue.h> #include <asn1library/asn1/singlevalue.h> #include <asn1library/asn1/types/choice.h> +#include <asn1library/asn1/types/ia5string.h> #include <asn1library/asn1/types/integer.h> +#include <asn1library/asn1/types/octetstring.h> #include <asn1library/asn1/types/sequence.h> #include <asn1library/asn1/types/sequenceof.h> #include <asn1library/asn1/types/userdefinedtype.h> @@ -41,7 +44,9 @@ using Asn1Acn::ChoiceValue; using Asn1Acn::IntegerValue; using Asn1Acn::MultipleValue; using Asn1Acn::NamedValue; +using Asn1Acn::OctetStringValue; using Asn1Acn::SingleValue; +using Asn1Acn::StringValue; using Asn1Acn::Value; using Asn1Acn::ValuePtr; using Asn1Acn::Types::BitString; @@ -99,31 +104,70 @@ void ValueAssignmentVisitor::visit(const Boolean &type) void ValueAssignmentVisitor::visit(const Null &type) { Q_UNUSED(type); - throw ConverterException("Value generation is not implemented for NULL datatype"); + throw ConverterException(QString("Value assignment is not implemented for %1, NULL datatype").arg(m_typeName)); } void ValueAssignmentVisitor::visit(const BitString &type) { Q_UNUSED(type); - throw ConverterException("Value generation is not implemented for BIT STRING datatype"); + throw ConverterException( + QString("Value assignment is not implemented for %1, BIT STRING datatype").arg(m_typeName)); } void ValueAssignmentVisitor::visit(const OctetString &type) { - Q_UNUSED(type); - throw ConverterException("Value generation is not implemented for OCTET STRING datatype"); + if (m_value->typeEnum() != Value::SINGLE_VALUE) { + throw ConverterException("Invalid value for OCTET STRING datatype"); + } + + SizeConstraintVisitor<OctetStringValue> sizeConstraintVisitor; + type.constraints().accept(sizeConstraintVisitor); } void ValueAssignmentVisitor::visit(const IA5String &type) { - Q_UNUSED(type); - throw ConverterException("Value generation is not implemented for IA5String datatype"); + if (m_value->typeEnum() != Value::SINGLE_VALUE) { + throw ConverterException("Invalid value for OCTET STRING datatype"); + } + + SizeConstraintVisitor<StringValue> sizeConstraintVisitor; + type.constraints().accept(sizeConstraintVisitor); + + const SingleValue *singleValue = dynamic_cast<const SingleValue *>(m_value); + QString value = singleValue->value(); + // remove first and last character, it is quotation mark + value.remove(0, 1); + value.remove(value.length() - 1, 1); + QVector<QChar> bytes = getBytesFromString(value); + + size_t index = 0; + + for (const QChar b : bytes) { + VariableRef target = m_target; + target.appendElement("data", std::make_unique<Expression>(promela::model::Constant(index))); + m_sequence.appendElement(Assignment(target, Expression(promela::model::Constant(b.unicode())))); + ++index; + } + while (index < sizeConstraintVisitor.getMaxSize()) { + VariableRef target = m_target; + target.appendElement("data", std::make_unique<Expression>(promela::model::Constant(index))); + m_sequence.appendElement(Assignment(target, Expression(promela::model::Constant(0)))); + ++index; + } + + if (sizeConstraintVisitor.getMinSize() != sizeConstraintVisitor.getMaxSize()) { + VariableRef target = m_target; + target.appendElement("length"); + int stringSize = bytes.size(); + m_sequence.appendElement(Assignment(target, Expression(promela::model::Constant(stringSize)))); + } } void ValueAssignmentVisitor::visit(const NumericString &type) { Q_UNUSED(type); - throw ConverterException("Value generation is not implemented for NUMERIC STRING datatype"); + throw ConverterException( + QString("Value generation is not implemented for %1, NUMERIC STRING datatype").arg(m_typeName)); } void ValueAssignmentVisitor::visit(const Enumerated &type) @@ -264,4 +308,24 @@ void ValueAssignmentVisitor::visit(const UserdefinedType &type) type.type()->accept(visitor); } + +QVector<QChar> ValueAssignmentVisitor::getBytesFromString(const QString &str) +{ + QVector<QChar> result; + + bool escape = false; + for (const QChar c : str) { + if (c == '\\') { + if (escape) { + result.append(c); + escape = false; + } else { + escape = true; + } + } else { + result.append(c); + } + } + return result; +} } diff --git a/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.h b/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.h index fedab1e97e..d72933f33a 100644 --- a/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.h +++ b/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.h @@ -128,6 +128,9 @@ public: */ void visit(const Asn1Acn::Types::UserdefinedType &type) override; +private: + QVector<QChar> getBytesFromString(const QString &str); + private: Asn1Acn::Value *m_value; model::Sequence &m_sequence; -- GitLab From f3db0ac3a0bce9a3ae38fbd720eacc81ec311a25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Babski?= <rbabski@n7space.com> Date: Wed, 12 Jun 2024 09:28:50 +0100 Subject: [PATCH 2/3] Asn1ToPromelaTranslator, ASN.1 constants for OCTET STRING, IA5String --- .../visitors/valueassignmentvisitor.cpp | 43 ++++++++++++------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp b/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp index a9ba1b09d6..78d0a763aa 100644 --- a/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp +++ b/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp @@ -104,14 +104,13 @@ void ValueAssignmentVisitor::visit(const Boolean &type) void ValueAssignmentVisitor::visit(const Null &type) { Q_UNUSED(type); - throw ConverterException(QString("Value assignment is not implemented for %1, NULL datatype").arg(m_typeName)); + throw ConverterException(QString("ASN.1 constants not supported for %1, NULL datatype").arg(m_typeName)); } void ValueAssignmentVisitor::visit(const BitString &type) { Q_UNUSED(type); - throw ConverterException( - QString("Value assignment is not implemented for %1, BIT STRING datatype").arg(m_typeName)); + throw ConverterException(QString("ASN.1 constants not supported for %1, BIT STRING datatype").arg(m_typeName)); } void ValueAssignmentVisitor::visit(const OctetString &type) @@ -122,12 +121,32 @@ void ValueAssignmentVisitor::visit(const OctetString &type) SizeConstraintVisitor<OctetStringValue> sizeConstraintVisitor; type.constraints().accept(sizeConstraintVisitor); + + const SingleValue *singleValue = dynamic_cast<const SingleValue *>(m_value); + QString value = singleValue->value(); + QVector<QChar> bytes = getBytesFromString(value); + + size_t index = 0; + + for (const QChar b : bytes) { + VariableRef target = m_target; + target.appendElement("data", std::make_unique<Expression>(promela::model::Constant(index))); + m_sequence.appendElement(Assignment(target, Expression(promela::model::Constant(b.unicode())))); + ++index; + } + + if (sizeConstraintVisitor.getMinSize() != sizeConstraintVisitor.getMaxSize()) { + VariableRef target = m_target; + target.appendElement("length"); + int stringSize = bytes.size(); + m_sequence.appendElement(Assignment(target, Expression(promela::model::Constant(stringSize)))); + } } void ValueAssignmentVisitor::visit(const IA5String &type) { if (m_value->typeEnum() != Value::SINGLE_VALUE) { - throw ConverterException("Invalid value for OCTET STRING datatype"); + throw ConverterException("Invalid value for IA5String datatype"); } SizeConstraintVisitor<StringValue> sizeConstraintVisitor; @@ -135,25 +154,18 @@ void ValueAssignmentVisitor::visit(const IA5String &type) const SingleValue *singleValue = dynamic_cast<const SingleValue *>(m_value); QString value = singleValue->value(); - // remove first and last character, it is quotation mark - value.remove(0, 1); - value.remove(value.length() - 1, 1); QVector<QChar> bytes = getBytesFromString(value); size_t index = 0; for (const QChar b : bytes) { VariableRef target = m_target; + // the character is converted to numeric value + // promela has character literal, but it is not supported in promela model target.appendElement("data", std::make_unique<Expression>(promela::model::Constant(index))); m_sequence.appendElement(Assignment(target, Expression(promela::model::Constant(b.unicode())))); ++index; } - while (index < sizeConstraintVisitor.getMaxSize()) { - VariableRef target = m_target; - target.appendElement("data", std::make_unique<Expression>(promela::model::Constant(index))); - m_sequence.appendElement(Assignment(target, Expression(promela::model::Constant(0)))); - ++index; - } if (sizeConstraintVisitor.getMinSize() != sizeConstraintVisitor.getMaxSize()) { VariableRef target = m_target; @@ -166,8 +178,7 @@ void ValueAssignmentVisitor::visit(const IA5String &type) void ValueAssignmentVisitor::visit(const NumericString &type) { Q_UNUSED(type); - throw ConverterException( - QString("Value generation is not implemented for %1, NUMERIC STRING datatype").arg(m_typeName)); + throw ConverterException(QString("ASN.1 constants not supported for %1, NUMERIC STRING datatype").arg(m_typeName)); } void ValueAssignmentVisitor::visit(const Enumerated &type) @@ -282,7 +293,7 @@ void ValueAssignmentVisitor::visit(const Real &type) void ValueAssignmentVisitor::visit(const LabelType &type) { Q_UNUSED(type); - throw ConverterException("Value generation is not implemented for LabelType"); + throw ConverterException(QString("ASN.1 constants not supported for %1, LabelType datatype").arg(m_typeName)); } void ValueAssignmentVisitor::visit(const Integer &type) -- GitLab From a0d5093fe0f3263e89f26bf1db478d5d5addf20b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Babski?= <rbabski@n7space.com> Date: Wed, 12 Jun 2024 10:38:28 +0100 Subject: [PATCH 3/3] Asn1ToPromelaTranslator: Updated tests and fixes in support for string constants --- .../visitors/valueassignmentvisitor.cpp | 39 ++++- .../visitors/valueassignmentvisitor.h | 2 + .../tst_asn1topromelatranslator_values.cpp | 142 +++++++++++++++++- .../tst_asn1topromelatranslator_values.h | 5 + 4 files changed, 183 insertions(+), 5 deletions(-) diff --git a/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp b/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp index 78d0a763aa..564a65f102 100644 --- a/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp +++ b/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.cpp @@ -124,14 +124,14 @@ void ValueAssignmentVisitor::visit(const OctetString &type) const SingleValue *singleValue = dynamic_cast<const SingleValue *>(m_value); QString value = singleValue->value(); - QVector<QChar> bytes = getBytesFromString(value); + QVector<unsigned char> bytes = getBytesFromOctetString(value); size_t index = 0; - for (const QChar b : bytes) { + for (const unsigned char b : bytes) { VariableRef target = m_target; target.appendElement("data", std::make_unique<Expression>(promela::model::Constant(index))); - m_sequence.appendElement(Assignment(target, Expression(promela::model::Constant(b.unicode())))); + m_sequence.appendElement(Assignment(target, Expression(promela::model::Constant(b)))); ++index; } @@ -339,4 +339,37 @@ QVector<QChar> ValueAssignmentVisitor::getBytesFromString(const QString &str) } return result; } + +QVector<unsigned char> ValueAssignmentVisitor::getBytesFromOctetString(const QString &str) +{ + QVector<unsigned char> result; + + int high_nibble = 0; + int low_nibble = 0; + + auto iter = str.begin(); + while (iter != str.end()) { + high_nibble = hexdigit(iter->unicode()); + ++iter; + low_nibble = hexdigit(iter->unicode()); + ++iter; + + result.append((high_nibble << 4) | low_nibble); + } + return result; +} + +int ValueAssignmentVisitor::hexdigit(int c) +{ + if (isdigit(c)) { + return c - '0'; + } + if (c >= 'A' && c <= 'F') { + return 10 + c - 'A'; + } + if (c >= 'a' && c <= 'f') { + return 10 + c - 'a'; + } + return 0; +} } diff --git a/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.h b/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.h index d72933f33a..4abc3ca1cd 100644 --- a/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.h +++ b/src/libs/promela/Asn1ToPromelaTranslator/visitors/valueassignmentvisitor.h @@ -130,6 +130,8 @@ public: private: QVector<QChar> getBytesFromString(const QString &str); + QVector<unsigned char> getBytesFromOctetString(const QString &str); + int hexdigit(int c); private: Asn1Acn::Value *m_value; diff --git a/tests/unittests/promela/asn1topromelatranslator/tst_asn1topromelatranslator_values.cpp b/tests/unittests/promela/asn1topromelatranslator/tst_asn1topromelatranslator_values.cpp index e4ea0bd270..2e3d8924a1 100644 --- a/tests/unittests/promela/asn1topromelatranslator/tst_asn1topromelatranslator_values.cpp +++ b/tests/unittests/promela/asn1topromelatranslator/tst_asn1topromelatranslator_values.cpp @@ -30,7 +30,9 @@ #include <asn1library/asn1/types/boolean.h> #include <asn1library/asn1/types/choice.h> #include <asn1library/asn1/types/enumerated.h> +#include <asn1library/asn1/types/ia5string.h> #include <asn1library/asn1/types/integer.h> +#include <asn1library/asn1/types/octetstring.h> #include <asn1library/asn1/types/real.h> #include <asn1library/asn1/types/sequence.h> #include <asn1library/asn1/types/sequenceof.h> @@ -58,7 +60,9 @@ using Asn1Acn::Types::Choice; using Asn1Acn::Types::ChoiceAlternative; using Asn1Acn::Types::Enumerated; using Asn1Acn::Types::EnumeratedItem; +using Asn1Acn::Types::IA5String; using Asn1Acn::Types::Integer; +using Asn1Acn::Types::OctetString; using Asn1Acn::Types::Real; using Asn1Acn::Types::Sequence; using Asn1Acn::Types::SequenceOf; @@ -74,9 +78,9 @@ using promela::model::VariableRef; using promela::translator::Asn1NodeVisitor; namespace tmc::test { -void tst_Asn1ToPromelaTranslator_Values::initTestCase() {} +void tst_Asn1ToPromelaTranslator_Values::initTestCase() { } -void tst_Asn1ToPromelaTranslator_Values::cleanupTestCase() {} +void tst_Asn1ToPromelaTranslator_Values::cleanupTestCase() { } void tst_Asn1ToPromelaTranslator_Values::testSequence() const { @@ -575,6 +579,124 @@ void tst_Asn1ToPromelaTranslator_Values::testChoice() const QCOMPARE(std::get<Constant>(inlineCall->getArguments().last()).getValue(), 3); } +void tst_Asn1ToPromelaTranslator_Values::testOctetString() const +{ + auto asn1Model = createModel(); + + { + auto stringType = std::make_unique<OctetString>(); + Asn1Acn::Range<int64_t> range(0, 4); + auto rangeConstraint = std::make_unique<Asn1Acn::Constraints::RangeConstraint<Asn1Acn::IntegerValue>>(range); + auto sizeConstraint = std::make_unique<Asn1Acn::Constraints::SizeConstraint<Asn1Acn::OctetStringValue>>( + std::move(rangeConstraint)); + stringType->constraints().append(std::move(sizeConstraint)); + + auto myIntegerAssignment = std::make_unique<TypeAssignment>( + QStringLiteral("MyString"), QStringLiteral("MyString"), SourceLocation(), stringType->clone()); + + asn1Model->addType(std::move(myIntegerAssignment)); + + auto stringReference = std::make_unique<UserdefinedType>("MyString", "myModule"); + stringReference->setType(stringType->clone()); + + auto myValueAssignment = std::make_unique<ValueAssignment>(QStringLiteral("myValue"), SourceLocation(), + std::move(stringReference), std::make_unique<SingleValue>("0011aabb")); + asn1Model->addValue(std::move(myValueAssignment)); + } + + PromelaModel promelaModel; + Asn1NodeVisitor visitor(promelaModel, true); + visitor.visit(*asn1Model); + + QCOMPARE(promelaModel.getDeclarations().size(), 1); + + QCOMPARE(promelaModel.getDeclarations().at(0).getName(), "myValue"); + QVERIFY(promelaModel.getDeclarations().at(0).getType().isUtypeReference()); + QCOMPARE(promelaModel.getDeclarations().at(0).getType().getUtypeReference().getName(), "MyString"); + + QCOMPARE(promelaModel.getInlineDefs().size(), 3); + { + const InlineDef *inlineDef = findInline(promelaModel.getInlineDefs(), "myValue_init"); + QVERIFY(inlineDef != nullptr); + QCOMPARE(inlineDef->getArguments().size(), 0); + QCOMPARE(inlineDef->getSequence().getContent().size(), 5); + + verifyArrayAssignment(findProctypeElement<Assignment>(inlineDef->getSequence(), 0), "myValue", 0, 0x0); + verifyArrayAssignment(findProctypeElement<Assignment>(inlineDef->getSequence(), 1), "myValue", 1, 0x11); + verifyArrayAssignment(findProctypeElement<Assignment>(inlineDef->getSequence(), 2), "myValue", 2, 0xaa); + verifyArrayAssignment(findProctypeElement<Assignment>(inlineDef->getSequence(), 3), "myValue", 3, 0xbb); + + const Assignment *lengthAssignment = findProctypeElement<Assignment>(inlineDef->getSequence(), 4); + QVERIFY(lengthAssignment); + QCOMPARE(lengthAssignment->getVariableRef().getElements().size(), 2); + QCOMPARE(lengthAssignment->getVariableRef().getElements().front().m_name, "myValue"); + QVERIFY(!lengthAssignment->getVariableRef().getElements().front().m_index); + QCOMPARE(lengthAssignment->getVariableRef().getElements().back().m_name, "length"); + QVERIFY(!lengthAssignment->getVariableRef().getElements().back().m_index); + QVERIFY(std::holds_alternative<Constant>(lengthAssignment->getExpression().getContent())); + QCOMPARE(std::get<Constant>(lengthAssignment->getExpression().getContent()).getValue(), 4); + } +} + +void tst_Asn1ToPromelaTranslator_Values::testIA5String() const +{ + auto asn1Model = createModel(); + + { + auto stringType = std::make_unique<IA5String>(); + Asn1Acn::Range<int64_t> range(0, 4); + auto rangeConstraint = std::make_unique<Asn1Acn::Constraints::RangeConstraint<Asn1Acn::IntegerValue>>(range); + auto sizeConstraint = std::make_unique<Asn1Acn::Constraints::SizeConstraint<Asn1Acn::StringValue>>( + std::move(rangeConstraint)); + stringType->constraints().append(std::move(sizeConstraint)); + + auto myIntegerAssignment = std::make_unique<TypeAssignment>( + QStringLiteral("MyString"), QStringLiteral("MyString"), SourceLocation(), stringType->clone()); + + asn1Model->addType(std::move(myIntegerAssignment)); + + auto stringReference = std::make_unique<UserdefinedType>("MyString", "myModule"); + stringReference->setType(stringType->clone()); + + auto myValueAssignment = std::make_unique<ValueAssignment>(QStringLiteral("myValue"), SourceLocation(), + std::move(stringReference), std::make_unique<SingleValue>("test")); + asn1Model->addValue(std::move(myValueAssignment)); + } + + PromelaModel promelaModel; + Asn1NodeVisitor visitor(promelaModel, true); + visitor.visit(*asn1Model); + + QCOMPARE(promelaModel.getDeclarations().size(), 1); + + QCOMPARE(promelaModel.getDeclarations().at(0).getName(), "myValue"); + QVERIFY(promelaModel.getDeclarations().at(0).getType().isUtypeReference()); + QCOMPARE(promelaModel.getDeclarations().at(0).getType().getUtypeReference().getName(), "MyString"); + + QCOMPARE(promelaModel.getInlineDefs().size(), 3); + { + const InlineDef *inlineDef = findInline(promelaModel.getInlineDefs(), "myValue_init"); + QVERIFY(inlineDef != nullptr); + QCOMPARE(inlineDef->getArguments().size(), 0); + QCOMPARE(inlineDef->getSequence().getContent().size(), 5); + + verifyArrayAssignment(findProctypeElement<Assignment>(inlineDef->getSequence(), 0), "myValue", 0, 't'); + verifyArrayAssignment(findProctypeElement<Assignment>(inlineDef->getSequence(), 1), "myValue", 1, 'e'); + verifyArrayAssignment(findProctypeElement<Assignment>(inlineDef->getSequence(), 2), "myValue", 2, 's'); + verifyArrayAssignment(findProctypeElement<Assignment>(inlineDef->getSequence(), 3), "myValue", 3, 't'); + + const Assignment *lengthAssignment = findProctypeElement<Assignment>(inlineDef->getSequence(), 4); + QVERIFY(lengthAssignment); + QCOMPARE(lengthAssignment->getVariableRef().getElements().size(), 2); + QCOMPARE(lengthAssignment->getVariableRef().getElements().front().m_name, "myValue"); + QVERIFY(!lengthAssignment->getVariableRef().getElements().front().m_index); + QCOMPARE(lengthAssignment->getVariableRef().getElements().back().m_name, "length"); + QVERIFY(!lengthAssignment->getVariableRef().getElements().back().m_index); + QVERIFY(std::holds_alternative<Constant>(lengthAssignment->getExpression().getContent())); + QCOMPARE(std::get<Constant>(lengthAssignment->getExpression().getContent()).getValue(), 4); + } +} + std::unique_ptr<Definitions> tst_Asn1ToPromelaTranslator_Values::createModel() const { return std::make_unique<Definitions>("myModule", SourceLocation()); @@ -607,4 +729,20 @@ const T *tst_Asn1ToPromelaTranslator_Values::findProctypeElement( return nullptr; } +void tst_Asn1ToPromelaTranslator_Values::verifyArrayAssignment(const ::promela::model::Assignment *assignment, + const QString &target, int32_t index, int32_t expectedValue) const +{ + QVERIFY(assignment); + QCOMPARE(assignment->getVariableRef().getElements().size(), 2); + QCOMPARE(assignment->getVariableRef().getElements().front().m_name, target); + QVERIFY(!assignment->getVariableRef().getElements().front().m_index); + QCOMPARE(assignment->getVariableRef().getElements().back().m_name, "data"); + QVERIFY(assignment->getVariableRef().getElements().back().m_index); + QVERIFY(std::holds_alternative<Constant>(assignment->getVariableRef().getElements().back().m_index->getContent())); + QCOMPARE(std::get<Constant>(assignment->getVariableRef().getElements().back().m_index->getContent()).getValue(), + index); + QVERIFY(std::holds_alternative<Constant>(assignment->getExpression().getContent())); + QCOMPARE(std::get<Constant>(assignment->getExpression().getContent()).getValue(), expectedValue); +} + } diff --git a/tests/unittests/promela/asn1topromelatranslator/tst_asn1topromelatranslator_values.h b/tests/unittests/promela/asn1topromelatranslator/tst_asn1topromelatranslator_values.h index cb54c893e9..651b14c155 100644 --- a/tests/unittests/promela/asn1topromelatranslator/tst_asn1topromelatranslator_values.h +++ b/tests/unittests/promela/asn1topromelatranslator/tst_asn1topromelatranslator_values.h @@ -45,6 +45,8 @@ private Q_SLOTS: void testBoolean() const; void testSequenceOf() const; void testChoice() const; + void testOctetString() const; + void testIA5String() const; private: std::unique_ptr<Definitions> createModel() const; @@ -53,5 +55,8 @@ private: template<typename T> const T *findProctypeElement(const ::promela::model::Sequence &sequence, size_t index) const; + + void verifyArrayAssignment(const ::promela::model::Assignment *assignment, const QString &target, int32_t index, + int32_t expectedValue) const; }; } -- GitLab