diff --git a/compiler2/Type.hh b/compiler2/Type.hh index 01106fdc90833a75739b66a155856de8fb9d759b..d3ebf42447db8540b004ef19bcf0c93ee67bc22c 100644 --- a/compiler2/Type.hh +++ b/compiler2/Type.hh @@ -702,6 +702,10 @@ namespace Common { * Only used with new codec handling. */ bool can_have_coding(MessageEncodingType_t coding); + /** Checks whether the type itself or one of its fields/elements is a + * component or default type. Recursive. */ + void chk_map_param(Location* usage); + /** Return whether the two typetypes are compatible. Sometimes, this is * just a question of \p p_tt1 == \p p_tt2. When there are multiple * typetypes for a type (e.g. T_ENUM_A and T_ENUM_T) then all diff --git a/compiler2/Type_chk.cc b/compiler2/Type_chk.cc index d680f9a5de76002d76d2b823542df21e054e8ec0..5ab6baaa7eadf7ed7e9eb2911eec81904bc6e0a3 100644 --- a/compiler2/Type_chk.cc +++ b/compiler2/Type_chk.cc @@ -163,10 +163,18 @@ void Type::chk() case T_ARRAY: chk_Array(); break; - case T_PORT: + case T_PORT: { u.port->chk(); + Ttcn::FormalParList* map_params = u.port->get_map_parameters(true); + if (map_params != NULL) { + map_params->set_genname(get_genname_own()); + } + Ttcn::FormalParList* unmap_params = u.port->get_map_parameters(false); + if (unmap_params != NULL) { + unmap_params->set_genname(get_genname_own()); + } if (w_attrib_path) u.port->chk_attributes(w_attrib_path); - break; + break; } case T_SIGNATURE: chk_Signature(); break; @@ -7730,4 +7738,43 @@ void Type::chk_this_template_Signature(Template *t, namedbool incomplete_allowed "signature `%s'", get_typename().c_str()); } +void Type::chk_map_param(Location* usage) +{ + Type* t = get_type_refd_last(); + if (RecursionTracker::is_happening(t)) { + return; + } + RecursionTracker tracker(t); + + switch (t->typetype) { + case T_COMPONENT: + case T_DEFAULT: + usage->error("The `map'/`unmap' parameters of a port type cannot be or " + "contain a field/element of %s type", + t->typetype == T_COMPONENT ? "component" : "default"); + note("Prohibited type is here"); + break; + case T_SEQ_T: + case T_SET_T: + case T_CHOICE_T: + case T_CHOICE_A: + case T_SEQ_A: + case T_SET_A: + case T_OPENTYPE: + case T_ANYTYPE: + for (size_t i = 0; i < t->u.secho.cfm->get_nof_comps(); ++i) { + t->u.secho.cfm->get_comp_byIndex(i)->get_type()->chk_map_param(usage); + } + break; + case T_SEQOF: + case T_SETOF: + case T_ARRAY: + t->get_ofType()->chk_map_param(usage); + break; + default: + // everything else is allowed + break; + } +} + } // namespace Common diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc index deb45168d7695b51ff0576d05622bb41def21e67..dac7ed53a792cfd309a9b6e1d88b5fb397bbe358 100644 --- a/compiler2/ttcn3/AST_ttcn3.cc +++ b/compiler2/ttcn3/AST_ttcn3.cc @@ -9583,6 +9583,22 @@ namespace Ttcn { default: break; } + break; + case Definition::A_PORT: + switch (par->get_asstype()) { + case Definition::A_PAR_VAL: + case Definition::A_PAR_VAL_IN: + case Definition::A_PAR_VAL_OUT: + case Definition::A_PAR_VAL_INOUT: + // these are allowed + par->get_Type()->chk_map_param(par); + break; + default: + par->error("The `map'/`unmap' parameters of a port type cannot have %s", + par->get_assname()); + break; + } + break; default: // everything is allowed for functions and altsteps break; diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc index a4469be42e6040216bf0228f2cbec843ffef9ab6..463ce4f5989bdf2215220a200d43204395666d5a 100644 --- a/compiler2/ttcn3/Statement.cc +++ b/compiler2/ttcn3/Statement.cc @@ -697,6 +697,7 @@ namespace Ttcn { delete config_op.portref1; delete config_op.compref2; delete config_op.portref2; + delete config_op.ap_list; break; case S_START_TIMER: delete timer_op.timerref; @@ -1423,7 +1424,8 @@ namespace Ttcn { Statement::Statement(statementtype_t p_st, Value *p_compref1, Reference *p_portref1, - Value *p_compref2, Reference *p_portref2) + Value *p_compref2, Reference *p_portref2, + ParsedActualParameters* p_params) : statementtype(p_st), my_sb(0) { switch(statementtype) { @@ -1438,6 +1440,8 @@ namespace Ttcn { config_op.compref2=p_compref2; config_op.portref2=p_portref2; config_op.translate=false; + config_op.parsed_params=p_params; + config_op.fp_list=NULL; break; default: FATAL_ERROR("Statement::Statement()"); @@ -1989,6 +1993,9 @@ namespace Ttcn { config_op.portref1->set_my_scope(p_scope); config_op.compref2->set_my_scope(p_scope); config_op.portref2->set_my_scope(p_scope); + if (config_op.parsed_params != NULL) { + config_op.parsed_params->set_my_scope(p_scope); + } break; case S_START_TIMER: timer_op.timerref->set_my_scope(p_scope); @@ -2307,6 +2314,9 @@ namespace Ttcn { config_op.portref1->set_fullname(p_fullname+".portref1"); config_op.compref2->set_fullname(p_fullname+".compref2"); config_op.portref2->set_fullname(p_fullname+".portref2"); + if (config_op.parsed_params != NULL) { + config_op.parsed_params->set_fullname(p_fullname+".<parameters>"); + } break; case S_START_TIMER: timer_op.timerref->set_fullname(p_fullname+".timerref"); @@ -5031,6 +5041,12 @@ error: "endpoint is unknown", ptb1 != NULL ? "second" : "first"); } + if (config_op.parsed_params != NULL && + ((cref1_is_system && ptb1 == NULL) || + (cref2_is_system && ptb2 == NULL))) { + error("Cannot determine system component in `%s' operation with " + "`param' clause", get_stmt_name()); + } return; } if (cref1_is_tc || cref2_is_system) { @@ -5100,6 +5116,32 @@ error: } } } + + if (config_op.parsed_params != NULL) { + if (cref1_is_system) { + config_op.fp_list = ptb1->get_map_parameters(statementtype == S_MAP); + } + else if (cref2_is_system) { + config_op.fp_list = ptb2->get_map_parameters(statementtype == S_MAP); + } + else { + error("Cannot determine system component in `%s' operation with " + "`param' clause", get_stmt_name()); + } + if (config_op.fp_list != NULL) { + ActualParList* parlist = new ActualParList; + if (config_op.fp_list->fold_named_and_chk(config_op.parsed_params, parlist)) { + delete parlist; + delete config_op.parsed_params; + config_op.ap_list = NULL; + } else { + delete config_op.parsed_params; + parlist->set_fullname(get_fullname()); + parlist->set_my_scope(my_sb); + config_op.ap_list = parlist; + } + } + } } void Statement::chk_start_timer() @@ -7816,6 +7858,60 @@ error: // a simple string shall be formed from the port name and array indices generate_code_portref(&expr, config_op.portref2); } + if (config_op.ap_list != NULL) { + // handle 'map'/'unmap' parameters + size_t nof_pars = config_op.ap_list->get_nof_pars(); + string tmp_id = my_sb->get_scope_mod_gen()->get_temporary_id(); + expr.preamble = mputprintf(expr.preamble, + "Map_Params %s(%u);\n", tmp_id.c_str(), (unsigned int) nof_pars); + for (size_t i = 0; i < nof_pars; ++i) { + ActualPar* ap = config_op.ap_list->get_par(i); + FormalPar* fp = config_op.fp_list->get_fp_byIndex(i); + bool copy_needed = ap->get_selection() == ActualPar::AP_VALUE; + expression_struct par_expr; + Code::init_expr(&par_expr); + ap->generate_code(&par_expr, copy_needed, fp); + if (fp->get_asstype() != Definition::A_PAR_VAL_OUT) { + // set the values of 'in' and 'inout' parameters before the call + if (par_expr.preamble != NULL) { + expr.preamble = mputstr(expr.preamble, par_expr.preamble); + } + expr.preamble = mputprintf(expr.preamble, + "%s.set_param(%u, ttcn_to_string(%s));\n", + tmp_id.c_str(), (unsigned int) i, par_expr.expr); + } + else { + // set empty strings for 'out' parameters + expr.preamble = mputprintf(expr.preamble, + "%s.set_param(%u, CHARSTRING(\"\"));\n", + tmp_id.c_str(), (unsigned int) i); + } + if (fp->get_asstype() == Definition::A_PAR_VAL_OUT || + fp->get_asstype() == Definition::A_PAR_VAL_INOUT) { + // store the new values of 'out' and 'inout' parameters after the call + // note: this only works in single mode, in parallel mode execution + // will continue after the mapping request, without waiting for a + // reply that could contain the new values of the parameters + expr.postamble = mputprintf(expr.postamble, + "if (%s.get_param(%u).lengthof() > 0) " + "string_to_ttcn(%s.get_param(%u), %s);\n", + tmp_id.c_str(), (unsigned int) i, + tmp_id.c_str(), (unsigned int) i, par_expr.expr); + if (par_expr.postamble != NULL) { + expr.postamble = mputstr(expr.postamble, par_expr.postamble); + } + } + Code::free_expr(&par_expr); + } + expr.expr = mputprintf(expr.expr, ", %s", tmp_id.c_str()); + } + else if (statementtype == S_MAP || statementtype == S_UNMAP) { + // create an empty struct for 'connect' and 'disconnect' + string tmp_id = my_sb->get_scope_mod_gen()->get_temporary_id(); + expr.preamble = mputprintf(expr.preamble, + "Map_Params %s(0);\n", tmp_id.c_str()); + expr.expr = mputprintf(expr.expr, ", %s", tmp_id.c_str()); + } if (config_op.translate == true) { expr.expr = mputstr(expr.expr, ", TRUE"); } diff --git a/compiler2/ttcn3/Statement.hh b/compiler2/ttcn3/Statement.hh index 608012b10391faff58f48fb0be88b034978694cd..680c05a922357afa1bbe101551e89edf8eed4f6b 100644 --- a/compiler2/ttcn3/Statement.hh +++ b/compiler2/ttcn3/Statement.hh @@ -350,6 +350,11 @@ namespace Ttcn { Value *compref2; Reference *portref2; bool translate; // true if a map statement enables translation mode + union { + ParsedActualParameters* parsed_params; + ActualParList* ap_list; + }; + FormalParList* fp_list; // not owned } config_op; ///< used by S_CONNECT, S_MAP, S_DISCONNECT, S_UNMAP struct { @@ -618,7 +623,8 @@ namespace Ttcn { /** Constructor used by S_CONNECT, S_DISCONNECT, S_MAP, S_UNMAP */ Statement(statementtype_t p_st, Value *p_compref1, Reference *p_portref1, - Value *p_compref2, Reference *p_portref2); + Value *p_compref2, Reference *p_portref2, + ParsedActualParameters* p_params); /** Constructor used by S_TESTCASE_INSTANCE */ Statement(statementtype_t p_st, Ref_pard *p_ref, Value *p_val); /** Constructor used by S_ACTIVATE_REFD */ diff --git a/compiler2/ttcn3/Ttcnstuff.cc b/compiler2/ttcn3/Ttcnstuff.cc index 61e544d7f24e2a630e874d3b7ff324f7456fc9e4..9eab7fdcbc0e4182035e48ff903e41248666f924 100644 --- a/compiler2/ttcn3/Ttcnstuff.cc +++ b/compiler2/ttcn3/Ttcnstuff.cc @@ -1036,7 +1036,7 @@ namespace Ttcn { PortTypeBody::PortTypeBody(PortOperationMode_t p_operation_mode, Types *p_in_list, Types *p_out_list, Types *p_inout_list, bool p_in_all, bool p_out_all, bool p_inout_all, Definitions *defs, - bool p_realtime) + bool p_realtime, FormalParList *p_map_params, FormalParList *p_unmap_params) : Node(), Location(), my_type(0), operation_mode(p_operation_mode), in_list(p_in_list), out_list(p_out_list), inout_list(p_inout_list), in_all(p_in_all), out_all(p_out_all), inout_all(p_inout_all), @@ -1044,7 +1044,8 @@ namespace Ttcn { in_msgs(0), out_msgs(0), in_sigs(0), out_sigs(0), testport_type(TP_REGULAR), port_type(PT_REGULAR), provider_refs(), provider_types(), - in_mappings(0), out_mappings(0), vardefs(defs), realtime(p_realtime) + in_mappings(0), out_mappings(0), vardefs(defs), realtime(p_realtime), + map_params(p_map_params), unmap_params(p_unmap_params) { } @@ -1065,6 +1066,8 @@ namespace Ttcn { delete in_mappings; delete out_mappings; delete vardefs; + delete map_params; + delete unmap_params; } PortTypeBody *PortTypeBody::clone() const @@ -1088,6 +1091,12 @@ namespace Ttcn { if (in_mappings) in_mappings->set_fullname(p_fullname + ".<in_mappings>"); if (out_mappings) out_mappings->set_fullname(p_fullname + ".<out_mappings>"); vardefs->set_fullname(p_fullname + ".<port_var>"); + if (map_params != NULL) { + map_params->set_fullname(p_fullname + ".<map_params>"); + } + if (unmap_params != NULL) { + unmap_params->set_fullname(p_fullname + ".<unmap_params>"); + } } void PortTypeBody::set_my_scope(Scope *p_scope) @@ -1101,6 +1110,12 @@ namespace Ttcn { if (in_mappings) in_mappings->set_my_scope(p_scope); if (out_mappings) out_mappings->set_my_scope(p_scope); vardefs->set_parent_scope(p_scope); + if (map_params != NULL) { + map_params->set_my_scope(p_scope); + } + if (unmap_params != NULL) { + unmap_params->set_my_scope(p_scope); + } } void PortTypeBody::set_my_type(Type *p_type) @@ -1186,6 +1201,11 @@ namespace Ttcn { if (!checked) FATAL_ERROR("PortTypeBody::is_internal_port()"); return testport_type == TP_INTERNAL; } + + FormalParList* PortTypeBody::get_map_parameters(bool map) const + { + return map ? map_params : unmap_params; + } Type *PortTypeBody::get_address_type() { @@ -1776,6 +1796,15 @@ namespace Ttcn { if (provider_refs.size() == 0 && vardefs->get_nof_asss() > 0) { error("Port variables can only be used when the port is a translation port."); } + + if (map_params != NULL) { + Error_Context cntxt(map_params, "In `map' parameters"); + map_params->chk(Definition::A_PORT); + } + if (unmap_params != NULL) { + Error_Context cntxt(unmap_params, "In `unmap' parameters"); + unmap_params->chk(Definition::A_PORT); + } } void PortTypeBody::chk_attributes(Ttcn::WithAttribPath *w_attrib_path) @@ -2115,6 +2144,12 @@ namespace Ttcn { void PortTypeBody::generate_code(output_struct *target) { if (!checked || !my_type) FATAL_ERROR("PortTypeBody::generate_code()"); + if (map_params != NULL) { + map_params->generate_code_defval(target); + } + if (unmap_params != NULL) { + unmap_params->generate_code_defval(target); + } stringpool pool; port_def pdef; memset(&pdef, 0, sizeof(pdef)); @@ -2593,6 +2628,14 @@ namespace Ttcn { DEBUG(level, "out mappings:"); out_mappings->dump(level + 1); } + if (map_params != NULL) { + DEBUG(level, "map parameters:"); + map_params->dump(level + 1); + } + if (unmap_params != NULL) { + DEBUG(level, "unmap parameters:"); + unmap_params->dump(level + 1); + } } // ================================= diff --git a/compiler2/ttcn3/Ttcnstuff.hh b/compiler2/ttcn3/Ttcnstuff.hh index 23a2f397b21b5b9885182b57a503e8339d4ac0d7..42b347a5a76bf24959f7febbfe236baa3d4b3591 100644 --- a/compiler2/ttcn3/Ttcnstuff.hh +++ b/compiler2/ttcn3/Ttcnstuff.hh @@ -405,6 +405,7 @@ private: TypeMappings *in_mappings, *out_mappings; ///< mappings for PT_USER Definitions *vardefs; ///< variable definitions inside the port bool realtime; + FormalParList *map_params, *unmap_params; /** Copy constructor not implemented */ PortTypeBody(const PortTypeBody& p); /** Assignment disabled */ @@ -413,7 +414,7 @@ public: PortTypeBody(PortOperationMode_t p_operation_mode, Types *p_in_list, Types *p_out_list, Types *p_inout_list, bool p_in_all, bool p_out_all, bool p_inout_all, Definitions *defs, - bool p_realtime); + bool p_realtime, FormalParList *p_map_params, FormalParList *p_unmap_params); ~PortTypeBody(); virtual PortTypeBody *clone() const; virtual void set_fullname(const string& p_fullname); @@ -430,6 +431,7 @@ public: bool getreply_allowed() const; bool catch_allowed() const; bool is_internal() const; + FormalParList* get_map_parameters(bool map) const; /** Returns the address type that can be used in communication operations * on this port type. NULL is returned if addressing inside SUT is not * supported or the address type does not exist. */ diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y index c38479a54cba7f1585c0f213d695507cc637d681..10fe18cfb73e95c9db09f4e20f9a38b75975efcb 100644 --- a/compiler2/ttcn3/compiler.y +++ b/compiler2/ttcn3/compiler.y @@ -288,6 +288,7 @@ static const string anyname("anytype"); TypeMappings *in_mappings, *out_mappings; size_t varnElements; Ttcn::Definition **varElements; + FormalParList *map_params, *unmap_params; } portdefbody; struct { @@ -978,7 +979,7 @@ static const string anyname("anytype"); TemplateFormalPar FunctionFormalPar TestcaseFormalPar %type <formalparlist> optTemplateFormalParList TemplateFormalParList optFunctionFormalParList FunctionFormalParList optTestcaseFormalParList - TestcaseFormalParList optAltstepFormalParList + TestcaseFormalParList optAltstepFormalParList FormalValueParList %type <group> GroupDef GroupIdentifier %type <friend_list> FriendModuleDef %type <ifclause> ElseIfClause @@ -1038,7 +1039,7 @@ static const string anyname("anytype"); optReceiveParameter %type <parsedpar> FunctionActualParList TestcaseActualParList optFunctionActualParList optTestcaseActualParList - NamedPart UnnamedPart + NamedPart UnnamedPart optParamClause %type <templinsts> optTemplateActualParList seqTemplateActualPar seqTemplateInstance %type <templs> ValueOrAttribList seqValueOrAttrib ValueList Complement @@ -1269,6 +1270,7 @@ ForStatement FormalTemplatePar FormalTimerPar FormalValuePar +FormalValueParList FromClause FullGroupIdentifier FunctionActualPar @@ -1475,6 +1477,7 @@ optFunctionActualParList optFunctionFormalParList optMtcSpec optParDefaultValue +optParamClause optPortCallBody optPortRedirectOutgoing optReceiveParameter @@ -1576,6 +1579,8 @@ StructOfDefBody delete $$.varElements[i]; } delete $$.varElements; + delete $$.map_params; + delete $$.unmap_params; } PortDefList PortDefLists @@ -2886,7 +2891,8 @@ PortDefAttribs: // 60 Free($3.varElements); PortTypeBody *body = new PortTypeBody($1, $3.in_list, $3.out_list, $3.inout_list, - $3.in_all, $3.out_all, $3.inout_all, defs, $2); + $3.in_all, $3.out_all, $3.inout_all, defs, $2, + $3.map_params, $3.unmap_params); body->set_location(infile, @$); $$ = new Type(Type::T_PORT, body); $$->set_location(infile, @$); @@ -2904,7 +2910,8 @@ PortDefAttribs: // 60 Free($6.varElements); PortTypeBody *body = new PortTypeBody($1, $6.in_list, $6.out_list, $6.inout_list, - $6.in_all, $6.out_all, $6.inout_all, defs, $2); + $6.in_all, $6.out_all, $6.inout_all, defs, $2, + $6.map_params, $6.unmap_params); body->set_location(infile, @$); $$ = new Type(Type::T_PORT, body); body->add_user_attribute($5.elements, $5.nElements, $6.in_mappings, $6.out_mappings, false); @@ -2934,6 +2941,8 @@ PortDefLists: $$.out_mappings = 0; $$.varnElements = 0; $$.varElements = 0; + $$.map_params = NULL; + $$.unmap_params = NULL; } ; @@ -3004,6 +3013,26 @@ seqPortDefList: } Free($2.varElements); } + if ($2.map_params != NULL) { + if ($$.map_params != NULL) { + Location loc(infile, @2); + loc.error("Multiple `map' parameter lists in port type definition"); + delete $2.map_params; + } + else { + $$.map_params = $2.map_params; + } + } + if ($2.unmap_params != NULL) { + if ($$.unmap_params != NULL) { + Location loc(infile, @2); + loc.error("Multiple `unmap' parameter lists in port type definition"); + delete $2.unmap_params; + } + else { + $$.unmap_params = $2.unmap_params; + } + } } ; @@ -3031,6 +3060,8 @@ PortDefList: $$.inout_all = false; $$.varnElements = 0; $$.varElements = 0; + $$.map_params = NULL; + $$.unmap_params = NULL; } | OutParKeyword AllOrTypeListWithTo { @@ -3055,6 +3086,8 @@ PortDefList: $$.inout_all = false; $$.varnElements = 0; $$.varElements = 0; + $$.map_params = NULL; + $$.unmap_params = NULL; } | InOutParKeyword AllOrTypeList { @@ -3075,6 +3108,8 @@ PortDefList: $$.out_mappings = 0; $$.varnElements = 0; $$.varElements = 0; + $$.map_params = NULL; + $$.unmap_params = NULL; } | InParKeyword error { @@ -3088,6 +3123,8 @@ PortDefList: $$.out_mappings = 0; $$.varnElements = 0; $$.varElements = 0; + $$.map_params = NULL; + $$.unmap_params = NULL; } | OutParKeyword error { @@ -3101,6 +3138,8 @@ PortDefList: $$.out_mappings = 0; $$.varnElements = 0; $$.varElements = 0; + $$.map_params = NULL; + $$.unmap_params = NULL; } | InOutParKeyword error { @@ -3114,6 +3153,8 @@ PortDefList: $$.out_mappings = 0; $$.varnElements = 0; $$.varElements = 0; + $$.map_params = NULL; + $$.unmap_params = NULL; } | PortElementVarDef optSemiColon { $$.in_list = 0; @@ -3130,7 +3171,54 @@ PortDefList: $$.varElements[i] = $1.elements[i]; } delete $1.elements; -} + $$.map_params = NULL; + $$.unmap_params = NULL; + } +| MapKeyword ParamKeyword '(' FormalValueParList ')' + { + $$.in_list = 0; + $$.out_list = 0; + $$.inout_list = 0; + $$.in_all = false; + $$.out_all = false; + $$.inout_all = false; + $$.in_mappings = 0; + $$.out_mappings = 0; + $$.varnElements = 0; + $$.varElements = 0; + $$.map_params = $4; + $$.map_params->set_location(infile, @4); + $$.unmap_params = NULL; + } +| UnmapKeyword ParamKeyword '(' FormalValueParList ')' + { + $$.in_list = 0; + $$.out_list = 0; + $$.inout_list = 0; + $$.in_all = false; + $$.out_all = false; + $$.inout_all = false; + $$.in_mappings = 0; + $$.out_mappings = 0; + $$.varnElements = 0; + $$.varElements = 0; + $$.map_params = NULL; + $$.unmap_params = $4; + $$.unmap_params->set_location(infile, @4); + } +; + +FormalValueParList: + FormalValuePar + { + $$ = new FormalParList; + $$->add_fp($1); + } +| FormalValueParList ',' FormalValuePar + { + $$ = $1; + $$->add_fp($3); + } ; WithList: @@ -6072,7 +6160,7 @@ ConnectStatement: // 329 ConnectKeyword SingleConnectionSpec { $$=new Statement(Statement::S_CONNECT, - $2.compref1, $2.portref1, $2.compref2, $2.portref2); + $2.compref1, $2.portref1, $2.compref2, $2.portref2, NULL); $$->set_location(infile, @$); } ; @@ -6115,7 +6203,7 @@ DisconnectStatement: // 335 { if ($2.portref1 && $2.portref2 && $2.compref1 && $2.compref2) { $$ = new Statement(Statement::S_DISCONNECT, - $2.compref1, $2.portref1, $2.compref2, $2.portref2); + $2.compref1, $2.portref1, $2.compref2, $2.portref2, NULL); } else { Location loc(infile, @$); loc.error("Disconnect operation on multiple connections is " @@ -6168,15 +6256,20 @@ AllCompsAllPortsSpec: // 339 ; MapStatement: // 341 - MapKeyword SingleConnectionSpec + MapKeyword SingleConnectionSpec optParamClause { $$=new Statement(Statement::S_MAP, $2.compref1, $2.portref1, - $2.compref2, $2.portref2); + $2.compref2, $2.portref2, $3); $$->set_location(infile, @$); } ; +optParamClause: + /* empty */ { $$ = NULL; } +| ParamKeyword '(' FunctionActualParList ')' { $$ = $3; } +; + UnmapStatement: // 343 UnmapKeyword { @@ -6186,11 +6279,11 @@ UnmapStatement: // 343 loc.error("Unmap operation on multiple mappings is " "not currently supported"); } -| UnmapKeyword SingleOrMultiConnectionSpec +| UnmapKeyword SingleOrMultiConnectionSpec optParamClause { if ($2.compref1 && $2.portref1 && $2.compref1 && $2.compref2) { $$ = new Statement(Statement::S_UNMAP, - $2.compref1, $2.portref1, $2.compref2, $2.portref2); + $2.compref1, $2.portref1, $2.compref2, $2.portref2, $3); } else { Location loc(infile, @$); loc.error("Unmap operation on multiple mappings is " @@ -6199,6 +6292,7 @@ UnmapStatement: // 343 delete $2.portref1; delete $2.compref2; delete $2.portref2; + delete $3; $$ = new Statement(Statement::S_ERROR); } $$->set_location(infile, @$); diff --git a/compiler2/ttcn3/port.c b/compiler2/ttcn3/port.c index 35e8318de9055befd190bba9b0dcacbd50bc47b1..9070bb66e38d87837d71827740f0b2d3218b3d77 100644 --- a/compiler2/ttcn3/port.c +++ b/compiler2/ttcn3/port.c @@ -3601,8 +3601,8 @@ void generateTestPortSkeleton(const port_def *pdef) "\tvoid Handle_Fd_Event_Readable(int fd);\n" "\t/* void Handle_Timeout(double time_since_last_call); */\n" "protected:\n" - "\tvoid user_map(const char *system_port);\n" - "\tvoid user_unmap(const char *system_port);\n\n" + "\tvoid user_map(const char *system_port, Map_Params& params);\n" + "\tvoid user_unmap(const char *system_port, Map_Params& params);\n\n" "\tvoid user_start();\n" "\tvoid user_stop();\n\n", class_name, base_class_name, class_name, @@ -3782,10 +3782,12 @@ void generateTestPortSkeleton(const port_def *pdef) "{\n\n" "}\n\n" "/*void %s::Handle_Timeout(double time_since_last_call) {}*/\n\n" - "void %s::user_map(const char * /*system_port*/)\n" + "void %s::user_map(const char * /*system_port*/, " + "Map_Params& /*params*/)\n" "{\n\n" "}\n\n" - "void %s::user_unmap(const char * /*system_port*/)\n" + "void %s::user_unmap(const char * /*system_port*/, " + "Map_Params& /*params*/)\n" "{\n\n" "}\n\n" "void %s::user_start()\n" diff --git a/core/Communication.cc b/core/Communication.cc index f34053853d5c30c91ee2f30be89e338d467a6dfd..4d4cb28c922482d65835932e36860ff203cbdae8 100644 --- a/core/Communication.cc +++ b/core/Communication.cc @@ -1024,7 +1024,8 @@ void TTCN_Communication::send_disconnected(const char *local_port, } void TTCN_Communication::send_map_req(component src_component, - const char *src_port, const char *system_port, boolean translation) + const char *src_port, const char *system_port, Map_Params& params, + boolean translation) { Text_Buf text_buf; text_buf.push_int(MSG_MAP_REQ); @@ -1032,6 +1033,11 @@ void TTCN_Communication::send_map_req(component src_component, text_buf.push_int(translation == FALSE ? 0 : 1); text_buf.push_string(src_port); text_buf.push_string(system_port); + unsigned int nof_params = params.get_nof_params(); + text_buf.push_int(nof_params); + for (unsigned int i = 0; i < nof_params; ++i) { + text_buf.push_string((const char*) params.get_param(i)); + } send_message(text_buf); } @@ -1047,7 +1053,8 @@ void TTCN_Communication::send_mapped(const char *local_port, } void TTCN_Communication::send_unmap_req(component src_component, - const char *src_port, const char *system_port, boolean translation) + const char *src_port, const char *system_port, Map_Params& params, + boolean translation) { Text_Buf text_buf; text_buf.push_int(MSG_UNMAP_REQ); @@ -1055,6 +1062,11 @@ void TTCN_Communication::send_unmap_req(component src_component, text_buf.push_int(translation == FALSE ? 0 : 1); text_buf.push_string(src_port); text_buf.push_string(system_port); + unsigned int nof_params = params.get_nof_params(); + text_buf.push_int(nof_params); + for (unsigned int i = 0; i < nof_params; ++i) { + text_buf.push_string((const char*) params.get_param(i)); + } send_message(text_buf); } @@ -1767,12 +1779,19 @@ void TTCN_Communication::process_map() boolean translation = incoming_buf.pull_int().get_val() == 0 ? FALSE : TRUE; char *local_port = incoming_buf.pull_string(); char *system_port = incoming_buf.pull_string(); + unsigned int nof_params = incoming_buf.pull_int().get_val(); + Map_Params params(nof_params); + for (unsigned int i = 0; i < nof_params; ++i) { + char* par = incoming_buf.pull_string(); + params.set_param(i, CHARSTRING(par)); + delete [] par; + } incoming_buf.cut_message(); try { - PORT::map_port(local_port, system_port, FALSE); + PORT::map_port(local_port, system_port, params, FALSE); if (translation == TRUE) { - PORT::map_port(local_port, system_port, TRUE); + PORT::map_port(local_port, system_port, params, TRUE); } if (!TTCN_Runtime::is_single()) { if (translation == FALSE) { @@ -1813,12 +1832,19 @@ void TTCN_Communication::process_unmap() boolean translation = incoming_buf.pull_int().get_val() == 0 ? FALSE : TRUE; char *local_port = incoming_buf.pull_string(); char *system_port = incoming_buf.pull_string(); + unsigned int nof_params = incoming_buf.pull_int().get_val(); + Map_Params params(nof_params); + for (unsigned int i = 0; i < nof_params; ++i) { + char* par = incoming_buf.pull_string(); + params.set_param(i, CHARSTRING(par)); + delete [] par; + } incoming_buf.cut_message(); try { - PORT::unmap_port(local_port, system_port, FALSE); + PORT::unmap_port(local_port, system_port, params, FALSE); if (translation == TRUE) { - PORT::unmap_port(local_port, system_port, TRUE); + PORT::unmap_port(local_port, system_port, params, TRUE); } if (!TTCN_Runtime::is_single()) { if (translation == FALSE) { diff --git a/core/Communication.hh b/core/Communication.hh index be7d54b3d944c58dd9ef8d61fa87009e59d83436..5397a04bb51f5fa57bf4878dd55f98993b23b6c5 100644 --- a/core/Communication.hh +++ b/core/Communication.hh @@ -34,6 +34,7 @@ struct sockaddr_un; #include "NetworkHandler.hh" class MC_Connection; +class Map_Params; class TTCN_Communication { static int mc_fd; @@ -120,11 +121,11 @@ public: static void send_disconnected(const char *local_port, component remote_component, const char *remote_port); static void send_map_req(component src_component, const char *src_port, - const char *system_port, boolean translation); + const char *system_port, Map_Params& params, boolean translation); static void send_mapped(const char *local_port, const char *system_port, boolean translation); - static void send_unmap_req(component src_component, - const char *src_port, const char *system_port, boolean translation); + static void send_unmap_req(component src_component, const char *src_port, + const char *system_port, Map_Params& params, boolean translation); static void send_unmapped(const char *local_port, const char *system_port, boolean translation); diff --git a/core/Port.cc b/core/Port.cc index 9ba366bd55174650d43715bfca74420e0565ce0c..fcc02a312343229abfd66134357f2b6df052c60e 100644 --- a/core/Port.cc +++ b/core/Port.cc @@ -53,6 +53,35 @@ #include "../common/dbgnew.hh" +Map_Params::Map_Params(unsigned int p_nof_params) +: nof_params(p_nof_params), params(new CHARSTRING[nof_params]) { } + +Map_Params::~Map_Params() +{ + delete[] params; +} + +void Map_Params::set_param(unsigned int p_index, const CHARSTRING& p_param) +{ + if (p_index >= nof_params) { + TTCN_error("Map/unmap parameter index out of bounds"); + } + params[p_index] = p_param; +} + +unsigned int Map_Params::get_nof_params() const +{ + return nof_params; +} + +const CHARSTRING& Map_Params::get_param(unsigned int p_index) const +{ + if (p_index >= nof_params) { + TTCN_error("Map/unmap parameter index out of bounds"); + } + return params[p_index]; +} + PORT *PORT::list_head = NULL, *PORT::list_tail = NULL; PORT *PORT::system_list_head = NULL, *PORT::system_list_tail = NULL; @@ -357,7 +386,8 @@ void PORT::deactivate_port(boolean system) TitanLoggerApi::Port__Misc_reason::removing__unterminated__mapping, port_name, NULL_COMPREF, system_port); try { - unmap(system_port, system); + Map_Params params(0); + unmap(system_port, params, system); } catch (const TC_Error&) { } if (is_parallel) { try { @@ -1146,12 +1176,28 @@ void PORT::Uninstall_Handler() Fd_And_Timeout_User::set_timer(this, 0.0); } -void PORT::user_map(const char *) +void PORT::user_map(const char *system_port) { + // call the new user_map function if the legacy version is not overridden in + // the port implementation + Map_Params dummy(0); + user_map(system_port, dummy); +} +void PORT::user_unmap(const char *system_port) +{ + // call the new user_unmap function if the legacy version is not overridden in + // the port implementation + Map_Params dummy(0); + user_unmap(system_port, dummy); } -void PORT::user_unmap(const char *) +void PORT::user_map(const char *, Map_Params&) +{ + +} + +void PORT::user_unmap(const char *, Map_Params&) { } @@ -2190,7 +2236,7 @@ void PORT::process_last_message(port_connection *conn_ptr) } } -void PORT::map(const char *system_port, boolean translation) +void PORT::map(const char *system_port, Map_Params& params, boolean translation) { if (!is_active) TTCN_error("Inactive port %s cannot be mapped.", port_name); @@ -2215,7 +2261,13 @@ void PORT::map(const char *system_port, boolean translation) set_system_parameters(port_name); } - user_map(system_port); + if (params.get_nof_params() == 0) { + // call the legacy function if there are no parameters (for backward compatibility) + user_map(system_port); + } + else { + user_map(system_port, params); + } if (translation == FALSE) { TTCN_Logger::log_port_misc( @@ -2241,7 +2293,7 @@ void PORT::map(const char *system_port, boolean translation) "addressing.", port_name); } -void PORT::unmap(const char *system_port, boolean translation) +void PORT::unmap(const char *system_port, Map_Params& params, boolean translation) { int del_posn; for (del_posn = 0; del_posn < n_system_mappings; del_posn++) { @@ -2273,7 +2325,13 @@ void PORT::unmap(const char *system_port, boolean translation) n_system_mappings * sizeof(*system_mappings)); try { - user_unmap(system_port); + if (params.get_nof_params() == 0) { + // call the legacy function if there are no parameters (for backward compatibility) + user_unmap(system_port); + } + else { + user_unmap(system_port, params); + } } catch (...) { // prevent from memory leak Free(unmapped_port); @@ -2517,7 +2575,8 @@ void PORT::terminate_local_connection(const char *src_port, } } -void PORT::map_port(const char *component_port, const char *system_port, boolean translation) +void PORT::map_port(const char *component_port, const char *system_port, + Map_Params& params, boolean translation) { if (translation == TRUE) { TTCN_Runtime::initialize_system_port(system_port); @@ -2530,9 +2589,9 @@ void PORT::map_port(const char *component_port, const char *system_port, boolean TTCN_error("Map operation is not allowed on a connected port (%s).", port_name); } if (translation == FALSE) { - port_ptr->map(system_port, translation); + port_ptr->map(system_port, params, translation); } else { - port_ptr->map(component_port, translation); + port_ptr->map(component_port, params, translation); } if (translation == TRUE) { PORT* other_port_ptr = lookup_by_name(component_port, FALSE); @@ -2544,7 +2603,8 @@ void PORT::map_port(const char *component_port, const char *system_port, boolean } } -void PORT::unmap_port(const char *component_port, const char *system_port, boolean translation) +void PORT::unmap_port(const char *component_port, const char *system_port, + Map_Params& params, boolean translation) { if (translation == TRUE) { TTCN_Runtime::initialize_system_port(system_port); @@ -2554,9 +2614,9 @@ void PORT::unmap_port(const char *component_port, const char *system_port, boole if (port_ptr == NULL) TTCN_error("Unmap operation refers to " "non-existent port %s.", port_name); if (translation == FALSE) { - port_ptr->unmap(system_port, translation); + port_ptr->unmap(system_port, params, translation); } else { - port_ptr->unmap(component_port, translation); + port_ptr->unmap(component_port, params, translation); } if (translation == TRUE) { PORT* other_port_ptr = lookup_by_name(component_port, FALSE); diff --git a/core/Port.hh b/core/Port.hh index 568177c4f1c23fad0dc8606f16b0180175f3767b..e969b86a6d313b779eff756ed5f5a1b4009519b4 100644 --- a/core/Port.hh +++ b/core/Port.hh @@ -39,6 +39,20 @@ extern const COMPONENT_template& any_compref; struct port_connection; // no user serviceable parts inside +class Map_Params { + unsigned int nof_params; + CHARSTRING* params; + + Map_Params(const Map_Params&); // copy disabled + Map_Params& operator=(const Map_Params&); // assignment disabled +public: + Map_Params(unsigned int p_nof_params); + ~Map_Params(); + void set_param(unsigned int p_index, const CHARSTRING& p_param); + unsigned int get_nof_params() const; + const CHARSTRING& get_param(unsigned int p_index) const; +}; + /** Base class for all test ports */ class PORT : public Fd_And_Timeout_Event_Handler { friend class PORT_LIST; @@ -305,10 +319,15 @@ protected: * It can be used together with the interface introduced in TITAN R7E. */ void Uninstall_Handler(); - + + // legacy map and unmap functions for backward compatibility virtual void user_map(const char *system_port); virtual void user_unmap(const char *system_port); + // new map and unmap functions (with parameters) + virtual void user_map(const char *system_port, Map_Params& params); + virtual void user_unmap(const char *system_port, Map_Params& params); + virtual void user_start(); virtual void user_stop(); @@ -376,8 +395,8 @@ private: void handle_incoming_data(port_connection *conn_ptr); void process_last_message(port_connection *conn_ptr); - void map(const char *system_port, boolean translation); - void unmap(const char *system_port, boolean translation); + void map(const char *system_port, Map_Params& params, boolean translation); + void unmap(const char *system_port, Map_Params& params, boolean translation); public: static void process_connect_listen(const char *local_port, @@ -393,8 +412,8 @@ public: static void terminate_local_connection(const char *src_port, const char *dest_port); - static void map_port(const char *component_port, const char *system_port, boolean translation); - static void unmap_port(const char *component_port, const char *system_port, boolean translation); + static void map_port(const char *component_port, const char *system_port, Map_Params& params, boolean translation); + static void unmap_port(const char *component_port, const char *system_port, Map_Params& params, boolean translation); }; #endif diff --git a/core/Runtime.cc b/core/Runtime.cc index 13819f516168877a081f8d7aecbbc94b52b954c7..c1bb2a57d37b58159f7807c6fa0a36277cbbf865 100644 --- a/core/Runtime.cc +++ b/core/Runtime.cc @@ -1865,7 +1865,8 @@ void TTCN_Runtime::disconnect_port( void TTCN_Runtime::map_port( const COMPONENT& src_compref, const char *src_port, - const COMPONENT& dst_compref, const char *dst_port, boolean translation) + const COMPONENT& dst_compref, const char *dst_port, Map_Params& params, + boolean translation) { check_port_name(src_port, "map", "first"); check_port_name(dst_port, "map", "second"); @@ -1913,20 +1914,20 @@ void TTCN_Runtime::map_port( case SINGLE_TESTCASE: if (comp_reference != MTC_COMPREF) TTCN_error("Only the ports of mtc " "can be mapped in single mode."); - PORT::map_port(comp_port, system_port, FALSE); + PORT::map_port(comp_port, system_port, params, FALSE); if (translation == TRUE) { - PORT::map_port(comp_port, system_port, TRUE); + PORT::map_port(comp_port, system_port, params, TRUE); } break; case MTC_TESTCASE: TTCN_Communication::send_map_req(comp_reference, comp_port, - system_port, translation); + system_port, params, translation); executor_state = MTC_MAP; wait_for_state_change(); break; case PTC_FUNCTION: TTCN_Communication::send_map_req(comp_reference, comp_port, - system_port, translation); + system_port, params, translation); executor_state = PTC_MAP; wait_for_state_change(); break; @@ -1946,7 +1947,8 @@ void TTCN_Runtime::map_port( void TTCN_Runtime::unmap_port( const COMPONENT& src_compref, const char *src_port, - const COMPONENT& dst_compref, const char *dst_port, boolean translation) + const COMPONENT& dst_compref, const char *dst_port, Map_Params& params, + boolean translation) { check_port_name(src_port, "unmap", "first"); check_port_name(dst_port, "unmap", "second"); @@ -1994,20 +1996,20 @@ void TTCN_Runtime::unmap_port( case SINGLE_TESTCASE: if (comp_reference != MTC_COMPREF) TTCN_error("Only the ports of mtc " "can be unmapped in single mode."); - PORT::unmap_port(comp_port, system_port, FALSE); + PORT::unmap_port(comp_port, system_port, params, FALSE); if (translation == TRUE) { - PORT::unmap_port(comp_port, system_port, TRUE); + PORT::unmap_port(comp_port, system_port, params, TRUE); } break; case MTC_TESTCASE: TTCN_Communication::send_unmap_req(comp_reference, comp_port, - system_port, translation); + system_port, params, translation); executor_state = MTC_UNMAP; wait_for_state_change(); break; case PTC_FUNCTION: TTCN_Communication::send_unmap_req(comp_reference, comp_port, - system_port, translation); + system_port, params, translation); executor_state = PTC_UNMAP; wait_for_state_change(); break; diff --git a/core/Runtime.hh b/core/Runtime.hh index c8b057480d2089c5dae466fcaf9797990d207652..0dc86197d9410c104fcc73ef8626f8a2e42a817c 100644 --- a/core/Runtime.hh +++ b/core/Runtime.hh @@ -33,6 +33,7 @@ class CHARSTRING; class INTEGER; class FLOAT; class PORT; +class Map_Params; extern "C" { typedef void (*signal_handler_type)(int); @@ -270,10 +271,12 @@ public: const COMPONENT& dst_compref, const char *dst_port); static void map_port( const COMPONENT& src_compref, const char *src_port, - const COMPONENT& dst_compref, const char *dst_port, boolean translation = FALSE); + const COMPONENT& dst_compref, const char *dst_port, + Map_Params& params, boolean translation = FALSE); static void unmap_port( const COMPONENT& src_compref, const char *src_port, - const COMPONENT& dst_compref, const char *dst_port, boolean translation = FALSE); + const COMPONENT& dst_compref, const char *dst_port, + Map_Params& params, boolean translation = FALSE); static void begin_controlpart(const char *module_name); static void end_controlpart(); diff --git a/function_test/Semantic_Analyser/Makefile.semantic b/function_test/Semantic_Analyser/Makefile.semantic index ffbf6d0b9c7626c83a40873885029632f7a23d88..151bdb7df69ec5b29d9bac5fcd2d11af4d730560 100644 --- a/function_test/Semantic_Analyser/Makefile.semantic +++ b/function_test/Semantic_Analyser/Makefile.semantic @@ -16,7 +16,7 @@ include ../../Makefile.personal SADIRS := ver param template any_from pattern_ref float recof_index \ port_translation mtc_and_system_clause port_map_connect deterministic invoking_function_from_specific_places \ -json realtime +json realtime map_param ifdef RT2 SADIRS += deprecated erroneous_attributes template_concat endif diff --git a/function_test/Semantic_Analyser/map_param/.gitignore b/function_test/Semantic_Analyser/map_param/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2d293255e6d2f314e34950e486a48630d873491 --- /dev/null +++ b/function_test/Semantic_Analyser/map_param/.gitignore @@ -0,0 +1,2 @@ +!Makefile +!*.ttcn diff --git a/function_test/Semantic_Analyser/map_param/Makefile b/function_test/Semantic_Analyser/map_param/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..12d2217e87b8d0a1ddc38baad5b76c3685d4dc5a --- /dev/null +++ b/function_test/Semantic_Analyser/map_param/Makefile @@ -0,0 +1,13 @@ +############################################################################## +# Copyright (c) 2000-2019 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Balasko, Jeno +# Baranyi, Botond +# +############################################################################## +include ../common.mk diff --git a/function_test/Semantic_Analyser/map_param/map_param_SE.ttcn b/function_test/Semantic_Analyser/map_param/map_param_SE.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..5c69d208429be0ac5dbab555100336f9c5b0b84b --- /dev/null +++ b/function_test/Semantic_Analyser/map_param/map_param_SE.ttcn @@ -0,0 +1,92 @@ +/****************************************************************************** + * Copyright (c) 2000-2019 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html + * + * Contributors: + * Baranyi, Botond + * + ******************************************************************************/ +module map_param_SE { //^In TTCN-3 module// + +/* testing the 'map param' and 'unmap' param clauses in port type definitions */ +type port PT1 message { + inout charstring +} + +type component CT1 {} + +type record of CT1 CompList; //Prohibited type is here// + +type set Set_w_default { + default f //Prohibited type is here// +} + +type port PT2 message { //^In type definition// + inout integer + map param (CT1 a, in default b, inout PT1 c) //^In `map' parameters// //^In formal parameter list// //^In parameter//3 //The `map'/`unmap' parameters of a port type cannot be or contain a field/element of component type// //Prohibited type is here//2 //The `map'/`unmap' parameters of a port type cannot be or contain a field/element of default type// //The `map'/`unmap' parameters of a port type cannot have port parameter// + unmap param (out CompList d, inout Set_w_default e) //^In `unmap' parameters// //In formal parameter list// //^In parameter//2 //The `map'/`unmap' parameters of a port type cannot be or contain a field/element of component type// //The `map'/`unmap' parameters of a port type cannot be or contain a field/element of default type// +} + +signature Sig(in integer x, out float y); + +type port PT3 procedure { //^In type definition// + inout Sig + map param (in integer x, out float x) //^In `map' parameters// //^In formal parameter list// //Duplicate parameter with name// //Previous definition of `x' is here// + unmap param (inout Nonexistent x) //^In `unmap' parameters// //^In formal parameter list// //^In parameter// //There is no local or imported definition with name// +} + +type record of integer IntList; + +type octetstring Oct2 length (2); + +type port PT4 message { + inout integer + map param (in Oct2 x, out IntList y) + unmap param (inout integer z) +} + +type component CT4 { + port PT4 pt +} + +/* testing the 'param' clause in 'map' and 'unmap' operations */ +testcase tc() runs on CT4 { //^In testcase definition// + map(mtc:pt, system:pt); + unmap(mtc:pt, system:pt); + + var IntList list; + var integer i := 6; + map(mtc:pt, system:pt) param ('ABCD'O, list); + unmap(mtc:pt, system:pt) param (i); + + map(mtc:pt, system:pt) param (x := 'ABCD'O, y := list); + unmap(mtc:pt, system:pt) param (z := i); + + map(mtc:pt, system:pt) param (octetstring: 'ABCD'O, IntList: list); //^In map statement// //^In parameter// //Explicit type specification is useless for// + unmap(mtc:pt, system:pt) param (integer: i); //^In unmap statement// //^In parameter// //Explicit type specification is useless for// + + map(mtc:pt, system:pt) param ('11223344'O, i); //^In map statement// //^In parameter//2 //is not a valid value for type `octetstring' which has subtype// //Reference to a variable or value parameter of type `@map_param_SE.IntList' was expected instead of `integer'// + unmap(mtc:pt, system:pt) param ("2"); //^In unmap statement// //^In parameter// //Reference to a variable or value parameter was expected for an `inout' value parameter// + + map(mtc:pt, system:pt) param (octetstring: ?); //^In map statement// //Too few parameters\: 2 was expected instead of 1// //^In parameter// //A specific value without matching symbols was expected for a value parameter// + unmap(mtc:pt, system:pt) param (-); //^In unmap statement// //^In parameter// //Not used symbol \(`-'\) cannot be used for parameter that does not have default value// +} + +function func_w_system() system CT4 { + var IntList list; + var integer i := 6; + map(mtc:pt, system:pt) param ('ABCD'O, list); + unmap(mtc:pt, system:pt) param (i); +} + +function func_w_no_system() runs on CT4 mtc CT4 { //^In function definition// + var IntList list; + var integer i := 6; + map(mtc:pt, system:pt) param ('ABCD'O, list); //^In map statement// //Cannot determine system component in `map' operation with `param' clause// + unmap(mtc:pt, system:pt) param (i); //^In unmap statement// //Cannot determine system component in `unmap' operation with `param' clause// +} + +} diff --git a/function_test/Semantic_Analyser/map_param/t b/function_test/Semantic_Analyser/map_param/t new file mode 100755 index 0000000000000000000000000000000000000000..3a4b58ec16cf2f1390a36c7a92f8823e3b94b425 --- /dev/null +++ b/function_test/Semantic_Analyser/map_param/t @@ -0,0 +1,9 @@ +#!/usr/bin/perl +# note this is called through "perl -w" +use strict; + +my $self = $0; +$self =~ s!/t!!; + +exec('make check --no-print-directory -s -C ' . $self); + diff --git a/mctr2/mctr/MainController.cc b/mctr2/mctr/MainController.cc index eb011582107520d5db8cf7f3ad31d4ff87fe796f..dc8acb618e6167d0b88b260662c1d01d1eff38ba 100644 --- a/mctr2/mctr/MainController.cc +++ b/mctr2/mctr/MainController.cc @@ -3410,13 +3410,18 @@ void MainController::send_disconnect_ack(component_struct *tc) } void MainController::send_map(component_struct *tc, - const char *local_port, const char *system_port, boolean translation) + const char *local_port, const char *system_port, unsigned int nof_params, + char** params, boolean translation) { Text_Buf text_buf; text_buf.push_int(MSG_MAP); text_buf.push_int(translation == FALSE ? 0 : 1); text_buf.push_string(local_port); text_buf.push_string(system_port); + text_buf.push_int(nof_params); + for (unsigned int i = 0; i < nof_params; ++i) { + text_buf.push_string(params[i]); + } send_message(tc->tc_fd, text_buf); } @@ -3428,13 +3433,18 @@ void MainController::send_map_ack(component_struct *tc) } void MainController::send_unmap(component_struct *tc, - const char *local_port, const char *system_port, boolean translation) + const char *local_port, const char *system_port, unsigned int nof_params, + char** params, boolean translation) { Text_Buf text_buf; text_buf.push_int(MSG_UNMAP); text_buf.push_int(translation == FALSE ? 0 : 1); text_buf.push_string(local_port); text_buf.push_string(system_port); + text_buf.push_int(nof_params); + for (unsigned int i = 0; i < nof_params; ++i) { + text_buf.push_string(params[i]); + } send_message(tc->tc_fd, text_buf); } @@ -5371,11 +5381,18 @@ void MainController::process_map_req(component_struct *tc) delete [] system_port; return; } + + unsigned int nof_params = text_buf.pull_int().get_val(); + char** params = new char*[nof_params]; + for (unsigned int i = 0; i < nof_params; ++i) { + params[i] = text_buf.pull_string(); + } port_connection *conn = find_connection(src_compref, src_port, SYSTEM_COMPREF, system_port); if (conn == NULL) { - send_map(components[src_compref], src_port, system_port, translate == 0 ? FALSE : TRUE); + send_map(components[src_compref], src_port, system_port, nof_params, + params, translate == 0 ? FALSE : TRUE); conn = new port_connection; conn->head.comp_ref = src_compref; conn->head.port_name = src_port; @@ -5408,6 +5425,11 @@ void MainController::process_map_req(component_struct *tc) delete [] src_port; delete [] system_port; } + + for (unsigned int i = 0; i < nof_params; ++i) { + delete [] params[i]; + } + delete [] params; } void MainController::process_mapped(component_struct *tc) @@ -5470,6 +5492,13 @@ void MainController::process_unmap_req(component_struct *tc) delete [] system_port; return; } + + unsigned int nof_params = text_buf.pull_int().get_val(); + char** params = new char*[nof_params]; + for (unsigned int i = 0; i < nof_params; ++i) { + params[i] = text_buf.pull_string(); + } + port_connection *conn = find_connection(src_compref, src_port, SYSTEM_COMPREF, system_port); if (conn == NULL) { @@ -5477,7 +5506,8 @@ void MainController::process_unmap_req(component_struct *tc) } else { switch (conn->conn_state) { case CONN_MAPPED: - send_unmap(components[src_compref], src_port, system_port, translation); + send_unmap(components[src_compref], src_port, system_port, nof_params, + params, translation); conn->conn_state = CONN_UNMAPPING; case CONN_UNMAPPING: add_requestor(&conn->requestors, tc); @@ -5497,6 +5527,11 @@ void MainController::process_unmap_req(component_struct *tc) delete [] src_port; delete [] system_port; + + for (unsigned int i = 0; i < nof_params; ++i) { + delete [] params[i]; + } + delete [] params; } void MainController::process_unmapped(component_struct *tc) diff --git a/mctr2/mctr/MainController.h b/mctr2/mctr/MainController.h index 17dc8b4bf70b0301f58fd3728260ea1c411b61b5..6cb22d4293c83a308338640b898021283f579d03 100644 --- a/mctr2/mctr/MainController.h +++ b/mctr2/mctr/MainController.h @@ -526,10 +526,12 @@ private: const char *local_port, component remote_comp, const char *remote_port); static void send_disconnect_ack(component_struct *tc); static void send_map(component_struct *tc, - const char *local_port, const char *system_port, boolean translate); + const char *local_port, const char *system_port, unsigned int nof_params, + char** params, boolean translate); static void send_map_ack(component_struct *tc); static void send_unmap(component_struct *tc, - const char *local_port, const char *system_port, boolean translate); + const char *local_port, const char *system_port, unsigned int nof_params, + char** params, boolean translate); static void send_unmap_ack(component_struct *tc); static void send_debug_command(int fd, int commandID, const char* arguments); static void send_debug_setup(host_struct *hc); diff --git a/regression_test/map_param/Makefile b/regression_test/map_param/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9c9f97c991007c587d1cb8b50ccef9914dc0da5c --- /dev/null +++ b/regression_test/map_param/Makefile @@ -0,0 +1,20 @@ +############################################################################## +# Copyright (c) 2000-2019 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################## +TOPDIR := .. +include $(TOPDIR)/Makefile.regression + +DIR_SINGLE := single_mode +DIR_PARALLEL := parallel_mode + +all clean distclean run dep: + $(MAKE) -C $(DIR_SINGLE) $@ + $(MAKE) -C $(DIR_PARALLEL) $@ diff --git a/regression_test/map_param/PT.cc b/regression_test/map_param/PT.cc new file mode 100644 index 0000000000000000000000000000000000000000..de3944bd01d75ca9752a53aed4a9c0b50ce9dede --- /dev/null +++ b/regression_test/map_param/PT.cc @@ -0,0 +1,136 @@ +// This Test Port skeleton source file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/6 R5B +// for ebotbar (ebotbar@ebotbarVB) on Mon Apr 29 13:25:58 2019 + +// Copyright (c) 2000-2019 Ericsson Telecom AB + +// You may modify this file. Complete the body of empty functions and +// add your member functions here. + +#include "PT.hh" + +namespace common { + +PT::PT(const char *par_port_name) + : PT_BASE(par_port_name) +{ + +} + +PT::~PT() +{ + +} + +void PT::set_parameter(const char * /*parameter_name*/, + const char * /*parameter_value*/) +{ + +} + +/*void PT::Handle_Fd_Event(int fd, boolean is_readable, + boolean is_writable, boolean is_error) {}*/ + +void PT::Handle_Fd_Event_Error(int /*fd*/) +{ + +} + +void PT::Handle_Fd_Event_Writable(int /*fd*/) +{ + +} + +void PT::Handle_Fd_Event_Readable(int /*fd*/) +{ + +} + +/*void PT::Handle_Timeout(double time_since_last_call) {}*/ + +void PT::user_map(const char * /*system_port*/, Map_Params& params) +{ + if (params.get_nof_params() != 0) { + CHARSTRING p1_str = params.get_param(0); + if (p1_str.lengthof() > 0) { + // OK + OCTETSTRING p1; + string_to_ttcn(params.get_param(0), p1); + // check the value + if (p1 != P1__INITIAL) { + char* reason = mprintf("Initial value of parameter p1 is incorrect: %s", (const char*) p1_str); + TTCN_Runtime::setverdict(FAIL, reason); + Free(reason); + } + } + else { + // not OK + TTCN_Runtime::setverdict(FAIL, "Parameter p1 is unset"); + } + + CHARSTRING p2_str = params.get_param(1); + if (p2_str.lengthof() == 0) { + // OK + // now set the output value + params.set_param(1, ttcn_to_string(P2__FINAL)); + } + else { + // not OK + char* reason = mprintf("Parameter p2 is set: %s", (const char*) p2_str); + TTCN_Runtime::setverdict(FAIL, reason); + Free(reason); + } + CT_component_map__param = TRUE; + } + else { + CT_component_map__empty = TRUE; + } +} + +void PT::user_unmap(const char * /*system_port*/, Map_Params& params) +{ + if (params.get_nof_params() != 0) { + CHARSTRING p_str = params.get_param(0); + if (p_str.lengthof() > 0) { + // OK + INTEGER p; + string_to_ttcn(params.get_param(0), p); + // check the input value + if (p != P__INITIAL) { + char* reason = mprintf("Initial value of parameter p is incorrect: %s", (const char*) p_str); + TTCN_Runtime::setverdict(FAIL, reason); + Free(reason); + } + else { + // set the output value + params.set_param(0, ttcn_to_string(P__FINAL)); + } + } + else { + // not OK + TTCN_Runtime::setverdict(FAIL, "Parameter p is unset"); + } + CT_component_unmap__param = TRUE; + } + else { + CT_component_unmap__empty = TRUE; + } +} + +void PT::user_start() +{ + +} + +void PT::user_stop() +{ + +} + +void PT::outgoing_send(const CHARSTRING& /*send_par*/) +{ + +} + +} /* end of namespace */ + diff --git a/regression_test/map_param/PT.hh b/regression_test/map_param/PT.hh new file mode 100644 index 0000000000000000000000000000000000000000..1798dbc0f5ca24c99acaf91334a44916cbb4a60d --- /dev/null +++ b/regression_test/map_param/PT.hh @@ -0,0 +1,44 @@ +// This Test Port skeleton header file was generated by the +// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/6 R5B +// for ebotbar (ebotbar@ebotbarVB) on Mon Apr 29 13:25:58 2019 + +// Copyright (c) 2000-2019 Ericsson Telecom AB + +// You may modify this file. Add your attributes and prototypes of your +// member functions here. + +#ifndef PT_HH +#define PT_HH + +#include "common.hh" + +namespace common { + +class PT : public PT_BASE { +public: + PT(const char *par_port_name = NULL); + ~PT(); + + void set_parameter(const char *parameter_name, + const char *parameter_value); + +private: + /* void Handle_Fd_Event(int fd, boolean is_readable, + boolean is_writable, boolean is_error); */ + void Handle_Fd_Event_Error(int fd); + void Handle_Fd_Event_Writable(int fd); + void Handle_Fd_Event_Readable(int fd); + /* void Handle_Timeout(double time_since_last_call); */ +protected: + void user_map(const char *system_port, Map_Params& params); + void user_unmap(const char *system_port, Map_Params& params); + + void user_start(); + void user_stop(); + + void outgoing_send(const CHARSTRING& send_par); +}; + +} /* end of namespace */ + +#endif diff --git a/regression_test/map_param/common.ttcn b/regression_test/map_param/common.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..b4810185a4917f22069c6c8aa8671c80e340576d --- /dev/null +++ b/regression_test/map_param/common.ttcn @@ -0,0 +1,53 @@ +/****************************************************************************** + * Copyright (c) 2000-2019 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html + * + * Contributors: + * Baranyi, Botond + * + ******************************************************************************/ +module common { + +type record of integer IntList; + +type port PT message { + in integer + out charstring + map param (in octetstring p1 := P1_INITIAL, out IntList p2) + unmap param (inout integer p) +} + +type component CT { + port PT pt; + var boolean map_param := false; + var boolean unmap_param := false; + var boolean map_empty := false; + var boolean unmap_empty := false; +} + +const octetstring P1_INITIAL := '1123'O; + +const IntList P2_INITIAL := { 1, 2, 3 }; +const IntList P2_FINAL := { 1, 2, 4, 8 }; + +const integer P_INITIAL := -2; +const integer P_FINAL := 2; + +function f_check_calls() runs on CT { + // check whether all 4 user functions have been called + if (map_param and unmap_param and map_empty and unmap_empty) { + setverdict(pass); + } + else { + setverdict(fail, "Not all user functions have been called."); + log("user_map with parameters: ", map_param); + log("user_unmap with parameters: ", unmap_param); + log("user_map without parameters: ", map_empty); + log("user_unmap without parameters: ", unmap_empty); + } +} + +} diff --git a/regression_test/map_param/parallel_mode/.gitignore b/regression_test/map_param/parallel_mode/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..f9a644002a83b3bc48d7a6bb30cde2b894e43815 --- /dev/null +++ b/regression_test/map_param/parallel_mode/.gitignore @@ -0,0 +1,12 @@ +map_param_parallel +map_param_parallel.exe +common*.cc +common*.hh +parallel_test*.cc +parallel_test*.hh +*.o +*.d +PT.cc +PT.hh +common.ttcn +map_param_parallel*.log diff --git a/regression_test/map_param/parallel_mode/Makefile b/regression_test/map_param/parallel_mode/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..3799c55ee8309372ce65ffd8158a0b7ac5d864f4 --- /dev/null +++ b/regression_test/map_param/parallel_mode/Makefile @@ -0,0 +1,65 @@ +############################################################################## +# Copyright (c) 2000-2019 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################## +TOPDIR := ../.. +include $(TOPDIR)/Makefile.regression + +.PHONY: all clean dep run + +TTCN3_LIB = ttcn3$(RT2_SUFFIX)-parallel$(DYNAMIC_SUFFIX) + +COMMON_TTCN3_MODULES = common.ttcn +TTCN3_MODULES = $(COMMON_TTCN3_MODULES) parallel_test.ttcn + +GENERATED_SOURCES = $(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 + +PORT_SOURCES = PT.cc +PORT_HEADERS = $(PORT_SOURCES:.cc=.hh) + + +OBJECTS = $(GENERATED_SOURCES:.cc=.o) $(PORT_SOURCES:.cc=.o) + +TARGET = map_param_parallel$(EXESUFFIX) + +all: $(TARGET) + +$(COMMON_TTCN3_MODULES) $(PORT_SOURCES) $(PORT_HEADERS): + ln -s ../$@ + +$(TARGET): $(OBJECTS) + $(CXX) $(LDFLAGS) -o $@ $(OBJECTS) -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS) + +.cc.o: + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< + +$(GENERATED_SOURCES) $(GENERATED_HEADERS): $(TTCN3_MODULES) $(PORT_HEADERS) + $(TTCN3_COMPILER) $(TTCN3_MODULES) + +clean distclean: + -rm -f $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \ + $(GENERATED_SOURCES) *.log Makefile.bak + +dep: $(GENERATED_SOURCES) + makedepend $(CPPFLAGS) $(GENERATED_SOURCES) + +run: $(TARGET) + $(TTCN3_DIR)/bin/ttcn3_start $(TARGET) parallel.cfg + + diff --git a/regression_test/map_param/parallel_mode/parallel.cfg b/regression_test/map_param/parallel_mode/parallel.cfg new file mode 100644 index 0000000000000000000000000000000000000000..03783dd7c50fd8e58ffc940572758b3c4834d810 --- /dev/null +++ b/regression_test/map_param/parallel_mode/parallel.cfg @@ -0,0 +1,21 @@ +############################################################################### +# Copyright (c) 2000-2019 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################### +[MODULE_PARAMETERS] +[LOGGING] +Logfile := "map_param_parallel_%r.log" +FileMask := LOG_ALL +ConsoleMask := TTCN_WARNING | TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS + +[EXECUTE] +parallel_test.tc_parallel_mtc +parallel_test.tc_parallel_ptc + diff --git a/regression_test/map_param/parallel_mode/parallel_test.ttcn b/regression_test/map_param/parallel_mode/parallel_test.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..418cab6ca5752a9841074f359e2c1bf709eb3d1f --- /dev/null +++ b/regression_test/map_param/parallel_mode/parallel_test.ttcn @@ -0,0 +1,61 @@ +/****************************************************************************** + * Copyright (c) 2000-2019 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html + * + * Contributors: + * Baranyi, Botond + * + ******************************************************************************/ + +// this module contains tests for 'map'/'unmap' parameters in parallel mode +// ('out' and 'inout' do not retain the new values set in the port implementation, +// because the 'map' and 'unmap' operations are asynchronous, i.e. they don't +// wait for a response before the next operation is executed) +module parallel_test { + +import from common all; + +testcase tc_parallel_mtc() runs on CT { + var IntList v_p2 := P2_INITIAL; + map(mtc:pt, system:pt) param (-, v_p2); + if (v_p2 != P2_INITIAL) { + setverdict(fail, "Final value of parameter p2 is incorrect: ", v_p2); + } + + var integer v_p := P_INITIAL; + unmap(mtc:pt, system:pt) param(v_p); + if (v_p != P_INITIAL) { + setverdict(fail, "Final value of parameter p is incorrect: ", v_p); + } + + map(mtc:pt, system:pt); + unmap(mtc:pt, system:pt); + + f_check_calls(); +} + +testcase tc_parallel_ptc() runs on CT { + var CT ptc := CT.create; + + var IntList v_p2 := P2_INITIAL; + map(ptc:pt, system:pt) param (-, v_p2); + if (v_p2 != P2_INITIAL) { + setverdict(fail, "Final value of parameter p2 is incorrect: ", v_p2); + } + + var integer v_p := P_INITIAL; + unmap(ptc:pt, system:pt) param(v_p); + if (v_p != P_INITIAL) { + setverdict(fail, "Final value of parameter p is incorrect: ", v_p); + } + map(ptc:pt, system:pt); + unmap(ptc:pt, system:pt); + + ptc.start(f_check_calls()); + ptc.done; +} + +} diff --git a/regression_test/map_param/single_mode/.gitignore b/regression_test/map_param/single_mode/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..cbe76a5861b26d82b155be905a75badbc94fb568 --- /dev/null +++ b/regression_test/map_param/single_mode/.gitignore @@ -0,0 +1,12 @@ +map_param_single +map_param_single.exe +common*.cc +common*.hh +single_test*.cc +single_test*.hh +*.o +*.d +PT.cc +PT.hh +common.ttcn +map_param_single.log diff --git a/regression_test/map_param/single_mode/Makefile b/regression_test/map_param/single_mode/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..2986a4d208b5e375ecc950ebfee90e47377dd85d --- /dev/null +++ b/regression_test/map_param/single_mode/Makefile @@ -0,0 +1,65 @@ +############################################################################## +# Copyright (c) 2000-2019 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################## +TOPDIR := ../.. +include $(TOPDIR)/Makefile.regression + +.PHONY: all clean dep run + +TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) + +COMMON_TTCN3_MODULES = common.ttcn +TTCN3_MODULES = $(COMMON_TTCN3_MODULES) single_test.ttcn + +GENERATED_SOURCES = $(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 + +PORT_SOURCES = PT.cc +PORT_HEADERS = $(PORT_SOURCES:.cc=.hh) + + +OBJECTS = $(GENERATED_SOURCES:.cc=.o) $(PORT_SOURCES:.cc=.o) + +TARGET = map_param_single$(EXESUFFIX) + +all: $(TARGET) + +$(COMMON_TTCN3_MODULES) $(PORT_SOURCES) $(PORT_HEADERS): + ln -s ../$@ + +$(TARGET): $(OBJECTS) + $(CXX) $(LDFLAGS) -o $@ $(OBJECTS) -L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) -L$(OPENSSL_DIR)/lib -lcrypto $($(PLATFORM)_LIBS) + +.cc.o: + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< + +$(GENERATED_SOURCES) $(GENERATED_HEADERS): $(TTCN3_MODULES) $(PORT_HEADERS) + $(TTCN3_COMPILER) $(TTCN3_MODULES) + +clean distclean: + -rm -f $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \ + $(GENERATED_SOURCES) *.log Makefile.bak + +dep: $(GENERATED_SOURCES) + makedepend $(CPPFLAGS) $(GENERATED_SOURCES) + +run: $(TARGET) single.cfg + ./$^ + + diff --git a/regression_test/map_param/single_mode/single.cfg b/regression_test/map_param/single_mode/single.cfg new file mode 100644 index 0000000000000000000000000000000000000000..7856f410ff5f04a23d2a35e68d3e81f0ba9b735a --- /dev/null +++ b/regression_test/map_param/single_mode/single.cfg @@ -0,0 +1,20 @@ +############################################################################### +# Copyright (c) 2000-2019 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################### +[MODULE_PARAMETERS] +[LOGGING] +Logfile := "map_param_single.log" +FileMask := LOG_ALL +ConsoleMask := TTCN_WARNING | TTCN_ERROR | TTCN_TESTCASE | TTCN_STATISTICS + +[EXECUTE] +single_test.tc_single + diff --git a/regression_test/map_param/single_mode/single_test.ttcn b/regression_test/map_param/single_mode/single_test.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..b2d050454139f60ad082340a19db4e72056b2faa --- /dev/null +++ b/regression_test/map_param/single_mode/single_test.ttcn @@ -0,0 +1,39 @@ +/****************************************************************************** + * Copyright (c) 2000-2019 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html + * + * Contributors: + * Baranyi, Botond + * + ******************************************************************************/ + +// this module contains tests for 'map'/'unmap' parameters in single mode +// ('out' and 'inout' parameters function normally, i.e. they retain the new +// values set in the port implementation) +module single_test { + +import from common all; + +testcase tc_single() runs on CT { + var IntList v_p2 := P2_INITIAL; + map(mtc:pt, system:pt) param (-, v_p2); + if (v_p2 != P2_FINAL) { + setverdict(fail, "Final value of parameter p2 is incorrect: ", v_p2); + } + + var integer v_p := P_INITIAL; + unmap(mtc:pt, system:pt) param(v_p); + if (v_p != P_FINAL) { + setverdict(fail, "Final value of parameter p is incorrect: ", v_p); + } + + map(mtc:pt, system:pt); + unmap(mtc:pt, system:pt); + + f_check_calls(); +} + +}