Commit 02a6776e authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Added support for subreferences following valueof (artf577127)


Fixed ASN.1 named bits with length restrictions (bug 521410)

Change-Id: I53743e878e8840d0c9bafdc5ca51f85da08e5f6e
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent d0f6e30d
......@@ -4393,6 +4393,12 @@ void Type::chk_this_value_namedbits(Value *value)
if(bstring->size() < bitnum + 1) bstring->resize(bitnum + 1, '0');
(*bstring)[bitnum] = '1';
}
if (sub_type != NULL) {
size_t min_length = sub_type->get_min_length();
if (bstring->size() < min_length) {
bstring->resize(min_length, '0');
}
}
value->set_valuetype(Value::V_BSTR, bstring);
}
......
......@@ -291,9 +291,11 @@ namespace Common {
u.expr.v3 = p.u.expr.v3->clone();
u.expr.ti4 = p.u.expr.ti4->clone();
break;
case OPTYPE_VALUEOF: // ti1 [subrefs2]
u.expr.subrefs2 = p.u.expr.subrefs2 != NULL ? u.expr.subrefs2->clone() : NULL;
// fall through
case OPTYPE_LENGTHOF: // ti1
case OPTYPE_SIZEOF: // ti1
case OPTYPE_VALUEOF: // ti1
case OPTYPE_ISPRESENT:
case OPTYPE_TTCN2STRING:
case OPTYPE_ISVALUE:
......@@ -637,9 +639,11 @@ namespace Common {
delete u.expr.v3;
delete u.expr.ti4;
break;
case OPTYPE_VALUEOF: // ti1 [subrefs2]
delete u.expr.subrefs2;
// fall through
case OPTYPE_LENGTHOF: // ti1
case OPTYPE_SIZEOF: // ti1
case OPTYPE_VALUEOF: // ti1
case OPTYPE_ISVALUE:
case OPTYPE_ISBOUND:
case OPTYPE_ISPRESENT:
......@@ -1030,6 +1034,29 @@ namespace Common {
case OPTYPE_TTCN2STRING:
if(!p_ti1) FATAL_ERROR("Value::Value()");
u.expr.ti1=p_ti1;
if (p_optype == OPTYPE_VALUEOF) {
u.expr.subrefs2 = NULL;
}
break;
default:
FATAL_ERROR("Value::Value()");
} // switch
}
// ti1 subrefs2
Value::Value(operationtype_t p_optype, TemplateInstance* p_ti1,
Ttcn::FieldOrArrayRefs* p_subrefs2)
: GovernedSimple(S_V), valuetype(V_EXPR), my_governor(0), in_brackets(false)
{
u.expr.v_optype = p_optype;
u.expr.state = EXPR_NOT_CHECKED;
switch (p_optype) {
case OPTYPE_VALUEOF:
if (p_ti1 == NULL || p_subrefs2 == NULL) {
FATAL_ERROR("Value::Value()");
}
u.expr.ti1 = p_ti1;
u.expr.subrefs2 = p_subrefs2;
break;
default:
FATAL_ERROR("Value::Value()");
......@@ -1841,9 +1868,13 @@ namespace Common {
u.expr.v3->set_fullname(p_fullname+".<operand3>");
u.expr.ti4->set_fullname(p_fullname+".<operand4>");
break;
case OPTYPE_VALUEOF: // ti1 [subrefs2]
if (u.expr.subrefs2 != NULL) {
u.expr.subrefs2->set_fullname(p_fullname + ".<subrefs>");
}
// fall through
case OPTYPE_LENGTHOF: // ti1
case OPTYPE_SIZEOF: // ti1
case OPTYPE_VALUEOF: // ti1
case OPTYPE_ISVALUE:
case OPTYPE_ISBOUND:
case OPTYPE_ISPRESENT:
......@@ -2097,9 +2128,13 @@ namespace Common {
u.expr.v3->set_my_scope(p_scope);
u.expr.ti4->set_my_scope(p_scope);
break;
case OPTYPE_VALUEOF: // ti1 [subrefs2]
if (u.expr.subrefs2 != NULL) {
u.expr.subrefs2->set_my_scope(p_scope);
}
// fall through
case OPTYPE_LENGTHOF: // ti1
case OPTYPE_SIZEOF: // ti1
case OPTYPE_VALUEOF: // ti1
case OPTYPE_ISVALUE:
case OPTYPE_ISBOUND:
case OPTYPE_ISPRESENT:
......@@ -2470,7 +2505,7 @@ namespace Common {
break;
case OPTYPE_LENGTHOF: // ti1
case OPTYPE_SIZEOF: // ti1
case OPTYPE_VALUEOF: // ti1
case OPTYPE_VALUEOF: // ti1 [subrefs2]
case OPTYPE_ISVALUE:
case OPTYPE_ISBOUND:
case OPTYPE_ISPRESENT:
......@@ -3312,7 +3347,17 @@ namespace Common {
case OPTYPE_VALUEOF: {
Error_Context cntxt(this, "In the operand of operation `%s'",
get_opname());
return u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);}
if (u.expr.subrefs2 != NULL) {
Type* t = u.expr.ti1->get_expr_governor(Type::EXPECTED_TEMPLATE);
if (t != NULL) {
t = t->get_type_refd_last()->get_field_type(u.expr.subrefs2, exp_val);
return t->get_type_refd_last()->get_typetype();
}
return Type::T_UNDEF;
}
else {
return u.expr.ti1->get_expr_returntype(Type::EXPECTED_TEMPLATE);
} }
case OPTYPE_TMR_READ:
case OPTYPE_INT2FLOAT:
case OPTYPE_STR2FLOAT:
......@@ -3718,9 +3763,13 @@ namespace Common {
case OPTYPE_REPLACE:{
Type *tmp_type = u.expr.ti1->get_expr_governor(exp_val ==
Type::EXPECTED_DYNAMIC_VALUE ? Type::EXPECTED_TEMPLATE : exp_val);
if(tmp_type) tmp_type = tmp_type->get_type_refd_last();
return tmp_type;
}
if (u.expr.v_optype == OPTYPE_VALUEOF && tmp_type != NULL) {
tmp_type = tmp_type->get_type_refd_last()->
get_field_type(u.expr.subrefs2, exp_val);
}
if(tmp_type) tmp_type = tmp_type->get_type_refd_last();
return tmp_type;
}
case OPTYPE_ROTL:
case OPTYPE_ROTR:
return u.expr.v1->get_expr_governor(exp_val);
......@@ -3986,7 +4035,7 @@ namespace Common {
return "decomp()";
case OPTYPE_REPLACE:
return "replace()";
case OPTYPE_VALUEOF: // t1
case OPTYPE_VALUEOF: // t1 [subrefs2]
return "valueof()";
case OPTYPE_UNDEF_RUNNING:
return "<timer or component> running";
......@@ -7649,16 +7698,17 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_ISCHOSEN_T: // t1 i2
chk_expr_operands_ischosen(refch, exp_val);
break;
case OPTYPE_VALUEOF: { // ti1
case OPTYPE_VALUEOF: { // ti1 [subrefs2]
if (exp_val == Type::EXPECTED_DYNAMIC_VALUE)
exp_val = Type::EXPECTED_TEMPLATE;
Error_Context cntxt(this, "In the operand of operation `%s'", opname);
Type *governor = my_governor;
Type *governor = (u.expr.subrefs2 == NULL) ? my_governor : NULL;
if (!governor) governor = chk_expr_operands_ti(u.expr.ti1, exp_val);
if (!governor) return;
chk_expr_eval_ti(u.expr.ti1, governor, refch, exp_val);
if (valuetype == V_ERROR) return;
u.expr.ti1->get_Template()->chk_specific_value(false);
// the subreferences have already been checked by get_expr_returntype
break; }
case OPTYPE_ISPRESENT: // TODO: rename UsedInIsbound to better name
case OPTYPE_ISBOUND: {
......@@ -8751,17 +8801,20 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
valuetype = V_BOOL;
u.val_bool = b;
break; }
case OPTYPE_VALUEOF: // ti1
case OPTYPE_VALUEOF: // ti1 [subrefs2]
if (!u.expr.ti1->get_DerivedRef() &&
u.expr.ti1->get_Template()->is_Value() &&
!u.expr.ti1->get_Type()) {
// FIXME actually if the template instance has a type
// it might still be foldable.
// the argument is a single specific value
v1 = u.expr.ti1->get_Template()->get_Value();
v1 = u.expr.ti1->get_Template()->get_Value()->
get_refd_sub_value(u.expr.subrefs2, 0, false, refch);
Type *governor = my_governor;
if (governor == NULL) {
governor = u.expr.ti1->get_expr_governor(exp_val);
if (governor != NULL) governor = governor->get_type_refd_last()->
get_field_type(u.expr.subrefs2, exp_val);
if (governor != NULL) governor = governor->get_type_refd_last();
}
if (governor == NULL) governor = v1->get_my_governor()->get_type_refd_last();
......@@ -9360,7 +9413,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
|| u.expr.v3->is_unfoldable(refch, exp_val)
|| u.expr.ti4->get_specific_value()->is_unfoldable(refch, exp_val);
}
case OPTYPE_VALUEOF: // ti1
case OPTYPE_VALUEOF: // ti1 [subrefs2]
/* \todo if you have motivation to implement the eval function
for valueof()... */
return true;
......@@ -10627,9 +10680,20 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
u.expr.ti4->chk_recursions(refch);
refch.prev_state();
break;
case OPTYPE_VALUEOF: // ti1 [subrefs2]
if (u.expr.subrefs2 != NULL) {
for (size_t i = 0; i < u.expr.subrefs2->get_nof_refs(); ++i) {
Ttcn::FieldOrArrayRef* subref = u.expr.subrefs2->get_ref(i);
if (subref->get_type() == Ttcn::FieldOrArrayRef::ARRAY_REF) {
refch.mark_state();
subref->get_val()->chk_recursions(refch);
refch.prev_state();
}
}
}
// fall through
case OPTYPE_LENGTHOF: // ti1
case OPTYPE_SIZEOF: // ti1
case OPTYPE_VALUEOF: // ti1
case OPTYPE_ISPRESENT:
case OPTYPE_TTCN2STRING:
refch.mark_state();
......@@ -10985,10 +11049,19 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_REGEXP: // ti1 t2 v3
self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
self_ref |= chk_expr_self_ref_templ(u.expr.t2 ->get_Template(), lhs);
// no break
break;
case OPTYPE_VALUEOF: // ti1 [subrefs2]
if (u.expr.subrefs2 != NULL) {
for (size_t i = 0; i < u.expr.subrefs2->get_nof_refs(); ++i) {
Ttcn::FieldOrArrayRef* subref = u.expr.subrefs2->get_ref(i);
if (subref->get_type() == Ttcn::FieldOrArrayRef::ARRAY_REF) {
self_ref |= chk_expr_self_ref_val(subref->get_val(), lhs);
}
}
}
// fall through
case OPTYPE_LENGTHOF: // ti1
case OPTYPE_SIZEOF: // ti1
case OPTYPE_VALUEOF: // ti1
case OPTYPE_TTCN2STRING:
self_ref |= chk_expr_self_ref_templ(u.expr.ti1->get_Template(), lhs);
break;
......@@ -11575,6 +11648,9 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
string ret_val("valueof(");
u.expr.ti1->append_stringRepr(ret_val);
ret_val += ')';
if (u.expr.subrefs2 != NULL) {
u.expr.subrefs2->append_stringRepr(ret_val);
}
return ret_val; }
case OPTYPE_LOG2STR:
return string("log2str(...)");
......@@ -12445,9 +12521,18 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
str = u.expr.ti1->rearrange_init_code(str, usage_mod);
str = u.expr.v2->rearrange_init_code(str, usage_mod);
break;
case OPTYPE_VALUEOF:
if (u.expr.subrefs2 != NULL) {
for (size_t i = 0; i < u.expr.subrefs2->get_nof_refs(); ++i) {
Ttcn::FieldOrArrayRef* subref = u.expr.subrefs2->get_ref(i);
if (subref->get_type() == Ttcn::FieldOrArrayRef::ARRAY_REF) {
str = subref->get_val()->rearrange_init_code(str, usage_mod);
}
}
}
// fall through
case OPTYPE_LENGTHOF:
case OPTYPE_SIZEOF:
case OPTYPE_VALUEOF:
case OPTYPE_ISPRESENT:
case OPTYPE_TTCN2STRING:
str = u.expr.ti1->rearrange_init_code(str, usage_mod);
......@@ -12980,9 +13065,13 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
FATAL_ERROR("Value::generate_code_expr_expr()");
}
break; }
case OPTYPE_VALUEOF: // ti1
case OPTYPE_VALUEOF: // ti1 [subrefs2]
u.expr.ti1->generate_code(expr);
expr->expr = mputstr(expr->expr, ".valueof()");
if (u.expr.subrefs2 != NULL) {
u.expr.subrefs2->generate_code(expr,
u.expr.ti1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE));
}
break;
case OPTYPE_ISTEMPLATEKIND: // ti1 v2
u.expr.ti1->generate_code(expr);
......@@ -14904,10 +14993,20 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
return u.expr.ti1->has_single_expr() &&
u.expr.v2->has_single_expr() && u.expr.v3->has_single_expr() &&
u.expr.ti4->has_single_expr();
case OPTYPE_VALUEOF: // ti1 [subrefs2]
if (u.expr.subrefs2 != NULL) {
for (size_t i = 0; i < u.expr.subrefs2->get_nof_refs(); ++i) {
Ttcn::FieldOrArrayRef* subref = u.expr.subrefs2->get_ref(i);
if (subref->get_type() == Ttcn::FieldOrArrayRef::ARRAY_REF &&
!subref->get_val()->has_single_expr()) {
return false;
}
}
}
// fall through
case OPTYPE_ISVALUE: // ti1
case OPTYPE_LENGTHOF: // ti1
case OPTYPE_SIZEOF: // ti1
case OPTYPE_VALUEOF: // ti1
return u.expr.ti1->has_single_expr();
case OPTYPE_LOG2STR:
case OPTYPE_ANY2UNISTR:
......
......@@ -51,6 +51,7 @@ namespace Ttcn {
class LogArguments;
class JsonOmitCombination;
class LengthRestriction;
class FieldOrArrayRefs;
}
namespace Common {
......@@ -350,6 +351,7 @@ namespace Common {
Ttcn::ParsedActualParameters *t_list2;
Ttcn::ActualParList *ap_list2;
Ttcn::Ref_base *r2;
Ttcn::FieldOrArrayRefs* subrefs2;
};
Value *v3;
union {
......@@ -419,6 +421,9 @@ namespace Common {
Value(operationtype_t p_optype, Value* p_v1, Ttcn::Ref_base* p_r2, bool p_b4);
/** Constructor used by V_EXPR "ti1": LENGTHOF, SIZEOF, VALUEOF, TTCN2STRING */
Value(operationtype_t p_optype, TemplateInstance *p_ti1);
/** Constructor used by V_EXPR "ti1 subrefs2": VALUEOF */
Value(operationtype_t p_optype, TemplateInstance *p_ti1,
Ttcn::FieldOrArrayRefs* p_subrefs2);
/** Constructor used by V_EXPR "r1": TMR_READ, ACTIVATE */
Value(operationtype_t p_optype, Ttcn::Ref_base *p_r1);
/** Constructor used by V_EXPR "r1 [r2] b4": UNDEF_RUNNING */
......
......@@ -1285,6 +1285,14 @@ bool SubtypeConstraint::is_lower_limit_infinity() const
return false;
}
size_t SubtypeConstraint::get_min_length() const
{
if (subtype != ST_BITSTRING) {
FATAL_ERROR("SubtypeConstraint::get_min_length()");
}
return bitstring_st != NULL ? bitstring_st->get_min_length() : 0;
}
void SubtypeConstraint::except(const SubtypeConstraint* other)
{
......
......@@ -237,6 +237,7 @@ public:
universal_charstring_st->get_size_limit(false, sl) == TTRUE &&
universal_charstring_st->get_size_limit(true, sl) == TTRUE);
}
size_t get_min_length() const;
};
/**
......
......@@ -751,6 +751,8 @@ public:
tribool get_size_limit(bool is_upper, size_limit_t& limit) const;
string to_string() const;
size_t get_min_length() const;
};
template<unsigned char BITCNT, unsigned short ELEMSIZE>
......@@ -1028,6 +1030,15 @@ string StringSizeAndValueListConstraint<BITCNT,ELEMSIZE>::to_string() const
return ret_val;
}
template <unsigned char BITCNT, unsigned short ELEMSIZE>
size_t StringSizeAndValueListConstraint<BITCNT, ELEMSIZE>::get_min_length() const
{
if (size_constraint.is_empty() == TTRUE) {
return 0;
}
return size_constraint.get_minimal().get_size();
}
typedef StringSizeAndValueListConstraint<1,1> BitstringConstraint;
typedef StringSizeAndValueListConstraint<4,1> HexstringConstraint;
typedef StringSizeAndValueListConstraint<8,2> OctetstringConstraint; // one char is half octet
......
......@@ -1896,7 +1896,7 @@ optDecodedModifier
%left '*' '/' ModKeyword RemKeyword
%left UnarySign
%expect 66
%expect 67
%start GrammarRoot
......@@ -1909,7 +1909,7 @@ For 9 tokens the parser cannot decide whether the token is a part of
the return expression (shift) or it is the beginning of the next statement
(reduce).
2.) 10 distinct states, each with one conflict caused by token '['
2.) 11 distinct states, each with one conflict caused by token '['
The local definitions in altsteps can be followed immediately by the guard
expression. When the parser sees the '[' token it cannot decide whether it
belongs to the local definition as array dimension or array subreference
......@@ -1925,6 +1925,7 @@ The situations are the following:
- var template t v <here> [
- var t v := function(...)<subrefs> <here> [
- var template t v := decmatch (...) ref <here> [
- var t v := valueof(...)<subrefs> <here> [
3.) 1 conflict
The sequence identifier.objid can be either the beginning of a module name
......@@ -4177,8 +4178,19 @@ MatchOp: // 160
ValueofOp: // 162
ValueofKeyword '(' optError TemplateInstance optError ')'
optExtendedFieldReference
{
$$ = new Value(Value::OPTYPE_VALUEOF, $4);
if ($7.nElements == 0) {
$$ = new Value(Value::OPTYPE_VALUEOF, $4);
}
else {
FieldOrArrayRefs* subrefs = new FieldOrArrayRefs;
for (size_t i = 0; i < $7.nElements; ++i) {
subrefs->add($7.elements[i]);
}
Free($7.elements);
$$ = new Value(Value::OPTYPE_VALUEOF, $4, subrefs);
}
$$->set_location(infile, @$);
}
| ValueofKeyword '(' error ')'
......
......@@ -18,7 +18,7 @@
TOPDIR := ..
include $(TOPDIR)/Makefile.regression
ADIRS = parse errorMessages errorMessages2 transformations keyword hyphen enum1 enum2 codeGeneration2 Test38 Test303 Test307 Test308 Test309 Test310 Test338 Test340 Test342 Test344 Test346 Test348 Test350 Test352 Test354 Test356 Test358 Test360
ADIRS = parse errorMessages errorMessages2 transformations keyword hyphen enum1 enum2 codeGeneration2 Test38 Test303 Test307 Test308 Test309 Test310 Test338 Test340 Test342 Test344 Test346 Test348 Test350 Test352 Test354 Test356 Test358 Test360 namedBits
#still not OK: Test330 Test332
......
namedBits
namedBits.exe
NamedBits*.cc
NamedBits*.hh
Tests*.cc
Tests*.hh
namedBits*.log
##############################################################################
# Copyright (c) 2000-2017 Ericsson Telecom AB
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
# http://www.eclipse.org/legal/epl-v10.html
#
# Contributors:
# Baranyi, Botond – initial implementation
#
##############################################################################
TOPDIR := ../..
include $(TOPDIR)/Makefile.regression
.SUFFIXES: .ttcn .asn .hh
.PHONY: all clean dep run
TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX)
TTCN3_MODULES = Tests.ttcn
ASN1_MODULES = NamedBits.asn
GENERATED_SOURCES = $(ASN1_MODULES:.asn=.cc) $(TTCN3_MODULES:.ttcn=.cc)
GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
ifdef CODE_SPLIT
GENERATED_SOURCES := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), .cc _seq.cc _set.cc _seqof.cc _setof.cc _union.cc))
else ifdef SPLIT_TO_SLICES
POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_))
POSTFIXES := $(foreach file, $(POSTFIXES), $(addprefix $(file), .cc))
GENERATED_SOURCES2 := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), $(POSTFIXES)))
GENERATED_SOURCES += $(GENERATED_SOURCES2)
endif
OBJECTS = $(GENERATED_SOURCES:.cc=.o)
TARGET = namedBits$(EXESUFFIX)
all: $(TARGET)
$(TARGET): $(GENERATED_SOURCES) $(USER_SOURCES)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS)
$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile
compile: $(TTCN3_MODULES) $(ASN1_MODULES)
$(TTCN3_COMPILER) $(COMPILER_FLAGS) $^
clean distclean:
$(RM) $(TARGET) $(GENERATED_HEADERS) $(GENERATED_SOURCES) $(OBJECTS) *.log Makefile.bak
dep: $(GENERATED_SOURCES)
makedepend $(CPPFLAGS) $(GENERATED_SOURCES)
run: $(TARGET) config.cfg
./$^
--/////////////////////////////////////////////////////////////////////////////
-- Copyright (c) 2000-2017 Ericsson Telecom AB
-- All rights reserved. This program and the accompanying materials
-- are made available under the terms of the Eclipse Public License v1.0
-- which accompanies this distribution, and is available at
-- http://www.eclipse.org/legal/epl-v10.html
--
-- Contributors:
-- Baranyi, Botond
--
--/////////////////////////////////////////////////////////////////////////////
NamedBits
DEFINITIONS
AUTOMATIC TAGS
::=
BEGIN
IMPORTS ; -- nothing
Workdays1 ::=
BIT STRING { monday(0), tuesday(1), wednesday(3), thursday(4), friday(5) }
Workdays2 ::=
BIT STRING { monday(0), tuesday(1), wednesday(3), thursday(4), friday(5) } (SIZE(7))
Workdays3 ::=
BIT STRING { monday(0), tuesday(1), wednesday(3), thursday(4), friday(5) } (SIZE(0..7))
Workdays4 ::=
BIT STRING { monday(0), tuesday(1), wednesday(3), thursday(4), friday(5) } (SIZE(7..10))
myWorkdays11 Workdays1 ::= { monday }
myWorkdays12 Workdays1 ::= { monday, wednesday, friday }
myWorkdays13 Workdays1 ::= { tuesday, thursday }
myWorkdays21 Workdays2 ::= { monday }
myWorkdays22 Workdays2 ::= { monday, wednesday, friday }
myWorkdays23 Workdays2 ::= { tuesday, thursday }
myWorkdays31 Workdays3 ::= { monday }
myWorkdays32 Workdays3 ::= { monday, wednesday, friday }
myWorkdays33 Workdays3 ::= { tuesday, thursday }
myWorkdays41 Workdays4 ::= { monday }
myWorkdays42 Workdays4 ::= { monday, wednesday, friday }
myWorkdays43 Workdays4 ::= { tuesday, thursday }
END
/******************************************************************************
* Copyright (c) 2000-2017 Ericsson Telecom AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Baranyi, Botond
*
******************************************************************************/
module Tests {
import from NamedBits all;
type component CT {}
testcase tc_named_bits_no_restriction() runs on CT {
if (myWorkdays11 != '1'B) {
setverdict(fail, "myWorkdays11 := ", myWorkdays11);
}
else if (myWorkdays12 != '100101'B) {
setverdict(fail, "myWorkdays12 := ", myWorkdays12);
}
else if (myWorkdays13 != '01001'B) {
setverdict(fail, "myWorkdays13 := ", myWorkdays13);
}
else {
setverdict(pass);
}
}
testcase tc_named_bits_fixed_length() runs on CT {
if (myWorkdays21 != '1000000'B) {
setverdict(fail, "myWorkdays21 := ", myWorkdays21);
}
else if (myWorkdays22 != '1001010'B) {
setverdict(fail, "myWorkdays22 := ", myWorkdays22);
}
else if (myWorkdays23 != '0100100'B) {
setverdict(fail, "myWorkdays23 := ", myWorkdays23);
}
else {
setverdict(pass);
}
}
testcase tc_named_bits_low_length_range() runs on CT {
if (myWorkdays31 != '1'B) {
setverdict(fail, "myWorkdays31 := ", myWorkdays31);
}
else if (myWorkdays32 != '100101'B) {
setverdict(fail, "myWorkdays32 := ", myWorkdays32);
}
else if (myWorkdays33 != '01001'B) {
setverdict(fail, "myWorkdays33 := ", myWorkdays33);
}
else {
setverdict(pass);
}
}
testcase tc_named_bits_high_length_range() runs on CT {
if (myWorkdays41 != '1000000'B) {
setverdict(fail, "myWorkdays41 := ", myWorkdays41);
}
else if (myWorkdays42 != '1001010'B) {
setverdict(fail, "myWorkdays42 := ", myWorkdays42);
}
else if (myWorkdays43 != '0100100'B) {
setverdict(fail, "myWorkdays43 := ", myWorkdays43);
}
else {
setverdict(pass);
}
}