diff --git a/compiler2/Identifier.cc b/compiler2/Identifier.cc index c09515a6532c3d1f731fa6d55bed2e8539470ff4..07a351772ac7249e598b72cc843c9e8a41097655 100644 --- a/compiler2/Identifier.cc +++ b/compiler2/Identifier.cc @@ -831,6 +831,7 @@ namespace Common { {"send__", "send", "send_"}, {"sender__", "sender", "sender_"}, {"set__", "set", "set_"}, + {"setstate__", "setstate", "setstate_"}, {"setverdict__", "setverdict", "setverdict_"}, {"signature__", "signature", "signature_"}, {"start__", "start", "start_"}, diff --git a/compiler2/ttcn3/Statement.cc b/compiler2/ttcn3/Statement.cc index a496eb39f4dc72a0c0d07ea31ef8549ba7407bf1..fcabbcc30851f86a9cc898a56db04ae2e42fd3da 100644 --- a/compiler2/ttcn3/Statement.cc +++ b/compiler2/ttcn3/Statement.cc @@ -718,6 +718,10 @@ namespace Ttcn { delete update_op.w_attrib_path; delete update_op.err_attrib; break; + case S_SETSTATE: + delete setstate_op.val; + delete setstate_op.ti; + break; default: FATAL_ERROR("Statement::clean_up()"); } // switch statementtype @@ -1032,6 +1036,10 @@ namespace Ttcn { case S_DEACTIVATE: deactivate=p_val; break; + case S_SETSTATE: + setstate_op.val = p_val; + setstate_op.ti = NULL; + break; default: FATAL_ERROR("Statement::Statement()"); } // switch statementtype @@ -1465,6 +1473,22 @@ namespace Ttcn { FATAL_ERROR("Statement::Statement()"); } } + + Statement::Statement(statementtype_t p_st, Value* p_val, TemplateInstance* p_ti) + : statementtype(p_st), my_sb(0) + { + switch (statementtype) { + case S_SETSTATE: + if (p_val == NULL || p_ti == NULL) { + FATAL_ERROR("Statement::Statement()"); + } + setstate_op.val = p_val; + setstate_op.ti = p_ti; + break; + default: + FATAL_ERROR("Statement::Statement()"); + } + } Statement::~Statement() { @@ -1595,6 +1619,7 @@ namespace Ttcn { case S_START_PROFILER: return "@profiler.start"; case S_STOP_PROFILER: return "@profiler.stop"; case S_UPDATE: return "@update"; + case S_SETSTATE: return "setstate"; default: FATAL_ERROR("Statement::get_stmt_name()"); return ""; @@ -1924,6 +1949,12 @@ namespace Ttcn { update_op.w_attrib_path->set_my_scope(p_scope); } break; + case S_SETSTATE: + setstate_op.val->set_my_scope(p_scope); + if (setstate_op.ti != NULL) { + setstate_op.ti->set_my_scope(p_scope); + } + break; default: FATAL_ERROR("Statement::set_my_scope()"); } // switch statementtype @@ -2208,6 +2239,12 @@ namespace Ttcn { update_op.w_attrib_path->set_fullname(p_fullname + ".<attribpath>"); } break; + case S_SETSTATE: + setstate_op.val->set_fullname(p_fullname + ".val"); + if (setstate_op.ti != NULL) { + setstate_op.ti->set_fullname(p_fullname + ".ti"); + } + break; default: FATAL_ERROR("Statement::set_fullname()"); } // switch statementtype @@ -2498,6 +2535,7 @@ namespace Ttcn { case S_STOP_PROFILER: case S_INT2ENUM: case S_UPDATE: + case S_SETSTATE: return false; case S_ALT: case S_INTERLEAVE: @@ -2755,6 +2793,9 @@ namespace Ttcn { case S_UPDATE: chk_update(); break; + case S_SETSTATE: + chk_setstate(); + break; default: FATAL_ERROR("Statement::chk()"); } // switch statementtype @@ -5628,6 +5669,42 @@ error: "this context"); } } + + void Statement::chk_setstate() { + Error_Context cntxt(this, "In setstate statement"); + { + Error_Context cntxt2(this, "In first parameter"); + setstate_op.val->chk_expr_int(Type::EXPECTED_DYNAMIC_VALUE); + if (!setstate_op.val->is_unfoldable()) { + bool error = false; + if (setstate_op.val->get_val_Int()->is_native()) { + switch(setstate_op.val->get_val_Int()->get_val()) { + case 0: + case 1: + case 2: + case 3: + break; + default: + error = true; + } + } else { + error = true; + } + if (error) { + setstate_op.val->error("The value of the first parameter must be 0, 1, 2 or 3."); + } + } + } + if (setstate_op.ti != NULL) { + Error_Context cntxt2(this, "In second parameter"); + Type* t = setstate_op.ti->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE); + if (t != NULL) { + setstate_op.ti->chk(t); + } else { + setstate_op.ti->error("Cannot determine the type of the parameter."); + } + } + } void Statement::set_code_section( GovernedSimple::code_section_t p_code_section) @@ -5886,6 +5963,12 @@ error: case S_UPDATE: update_op.ref->set_code_section(p_code_section); break; + case S_SETSTATE: + setstate_op.val->set_code_section(p_code_section); + if (setstate_op.ti != NULL) { + setstate_op.ti->set_code_section(p_code_section); + } + break; default: FATAL_ERROR("Statement::set_code_section()"); } // switch statementtype @@ -6082,6 +6165,9 @@ error: case S_UPDATE: str = generate_code_update(str, def_glob_vars, src_glob_vars); break; + case S_SETSTATE: + str = generate_code_setstate(str); + break; default: FATAL_ERROR("Statement::generate_code()"); } // switch @@ -7383,6 +7469,19 @@ error: } expr.expr = mputstr(expr.expr, ")"); if (config_op.translate) { + bool warning = false; + if (!config_op.compref1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)) { + warning = true; + config_op.compref2->warning( + "Cannot determine the type of the component in the first parameter." + "The port translation will not work."); + } + if (!config_op.compref2->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)) { + warning = true; + config_op.compref2->warning( + "Cannot determine the type of the component in the second parameter." + "The port translation will not work."); + } string funcname; if (strcmp(opname, "map") == 0) { funcname = "add_port"; @@ -7391,7 +7490,7 @@ error: } else { //TODO connect, disconnect } - if (!funcname.empty()) { + if (!funcname.empty() && warning == false) { expr.expr = mputstr(expr.expr, ";\n"); config_op.portref1->generate_code_portref(&expr, my_sb); expr.expr = mputprintf(expr.expr, ".%s(&(", funcname.c_str()); @@ -7567,6 +7666,27 @@ error: } return str; } + + char* Statement::generate_code_setstate(char *str) { + expression_struct expr; + Code::init_expr(&expr); + expr.expr = mputstr(expr.expr, "TTCN_Runtime::set_port_state("); + if (!setstate_op.val->is_unfoldable()) { + expr.expr = mputprintf(expr.expr, "%i", (int)setstate_op.val->get_val_Int()->get_val()); + } else { + setstate_op.val->generate_code_expr(&expr); + } + + expr.expr = mputstr(expr.expr, ", "); + if (setstate_op.ti != NULL) { + expr.expr = mputstr(expr.expr, "(TTCN_Logger::begin_event(TTCN_Logger::PORTEVENT_SETSTATE, TRUE), "); + setstate_op.ti->generate_code(&expr); + expr.expr = mputstr(expr.expr, ".log(), TTCN_Logger::end_event_log2str()), FALSE);\n"); + } else { + expr.expr = mputstr(expr.expr, "\"\", FALSE);\n"); + } + return Code::merge_free_expr(str, &expr); + } void Statement::generate_code_expr_receive(expression_struct *expr, const char *opname) @@ -8055,7 +8175,7 @@ error: Code::free_expr(&ref_expr); expr->expr = mputprintf(expr->expr, "&%s", tmp_id_var.c_str()); } - + void Statement::set_parent_path(WithAttribPath* p_path) { switch (statementtype) { case S_DEF: @@ -8146,6 +8266,7 @@ error: case S_STOP_PROFILER: case S_INT2ENUM: case S_UPDATE: + case S_SETSTATE: break; default: FATAL_ERROR("Statement::set_parent_path()"); diff --git a/compiler2/ttcn3/Statement.hh b/compiler2/ttcn3/Statement.hh index dd67c6a5b76a9d4baa68db1bc59973ac4727ba8f..299ea2f27b5dbd6e5e93e288f6743b1f718c785c 100644 --- a/compiler2/ttcn3/Statement.hh +++ b/compiler2/ttcn3/Statement.hh @@ -267,7 +267,8 @@ namespace Ttcn { S_STRING2TTCN, // convert_op S_INT2ENUM, // convert_op /* update statement */ - S_UPDATE // update_op + S_UPDATE, // update_op + S_SETSTATE // setstate_op }; enum component_t { @@ -482,6 +483,11 @@ namespace Ttcn { WithAttribPath* w_attrib_path; ErroneousAttributes* err_attrib; } update_op; /**< S_UPDATE */ + + struct { + Value* val; + TemplateInstance* ti; + } setstate_op; /**< S_SETSTATE */ }; Statement(const Statement& p); ///< copy disabled @@ -525,7 +531,7 @@ namespace Ttcn { Statement(statementtype_t p_st, AltGuards *p_ags); /** Constructor used by S_RETURN */ Statement(statementtype_t p_st, Template *p_temp); - /** Constructor used by S_DEACTIVATE, S_STOP_COMP, S_KILL */ + /** Constructor used by S_DEACTIVATE, S_STOP_COMP, S_KILL, S_SETSTATE */ Statement(statementtype_t p_st, Value *p_val); /** Constructor used by S_KILLED */ Statement(statementtype_t p_st, Value *p_val, bool p_any_from, @@ -607,6 +613,8 @@ namespace Ttcn { Statement(statementtype_t p_st, Value* p_val, Reference* p_ref); /** Constructor used by S_UPDATE */ Statement(statementtype_t p_st, Reference* p_ref, MultiWithAttrib* p_attrib); + /** Constructor used by S_SETSTATE */ + Statement(statementtype_t p_st, Value* p_val, TemplateInstance* p_ti); virtual ~Statement(); virtual Statement* clone() const; virtual void dump(unsigned int level) const; @@ -787,6 +795,7 @@ namespace Ttcn { void chk_string2ttcn(); void chk_int2enum(); void chk_update(); + void chk_setstate(); public: /** Sets the code section selector of all embedded values and * templates to \a p_code_section. */ @@ -858,6 +867,7 @@ namespace Ttcn { char *generate_code_testcaseinst(char *str); char *generate_code_execute_refd(char *str); char* generate_code_update(char *str, char*& def_glob_vars, char*& src_glob_vars); + char* generate_code_setstate(char *str); /** used for receive, check-receive, trigger */ void generate_code_expr_receive(expression_struct *expr, const char *opname); diff --git a/compiler2/ttcn3/Ttcnstuff.cc b/compiler2/ttcn3/Ttcnstuff.cc index 6ee5e66d1a1420a0ae9d1e1ba99fa6ca01324221..2d6676ae41e0f57f798545a75d670fcf9cd2315c 100644 --- a/compiler2/ttcn3/Ttcnstuff.cc +++ b/compiler2/ttcn3/Ttcnstuff.cc @@ -570,6 +570,8 @@ namespace Ttcn { FATAL_ERROR("TypeMappingTarget::fill_type_mapping_target()"); target->mapping.function.name = pool.add(u.func.function_ptr->get_genname_from_scope(p_scope)); + target->mapping.function.dispname = + pool.add(u.func.function_ptr->get_fullname()); switch (u.func.function_ptr->get_prototype()) { case Ttcn::Def_Function_Base::PROTOTYPE_CONVERT: target->mapping.function.prototype = PT_CONVERT; @@ -2297,10 +2299,15 @@ namespace Ttcn { mapped_type->targets[ind].mapping_type = M_FUNCTION; mapped_type->targets[ind].mapping.function.prototype = PT_FAST; - mapped_type->targets[ind].mapping.function.name = mapping_target->get_function()->get_genname_from_scope(my_scope).c_str(); - - mapped_type->targets[ind].target_name = pool.add(mapping->get_source_type()->get_genname_value(my_scope)); - mapped_type->targets[ind].target_dispname = pool.add(mapping->get_source_type()->get_typename()); + mapped_type->targets[ind].mapping.function.name = + mapping_target->get_function()->get_genname_from_scope(my_scope).c_str(); + mapped_type->targets[ind].mapping.function.dispname = + pool.add(mapping_target->get_function()->get_fullname()); + + mapped_type->targets[ind].target_name = + pool.add(mapping->get_source_type()->get_genname_value(my_scope)); + mapped_type->targets[ind].target_dispname = + pool.add(mapping->get_source_type()->get_typename()); if (in_msgs->has_type(mapping->get_source_type())) { mapped_type->targets[ind].target_index = diff --git a/compiler2/ttcn3/compiler.l b/compiler2/ttcn3/compiler.l index a251832aaa22fdc4d15c314a05c3129b22724804..62a04100982f0e9742dcfd9f4ff2917a8e7d4741 100644 --- a/compiler2/ttcn3/compiler.l +++ b/compiler2/ttcn3/compiler.l @@ -489,6 +489,7 @@ self RETURN(SelfKeyword); send RETURN_DOT(SendOpKeyword); sender RETURN(SenderKeyword); set RETURN(SetKeyword); +setstate RETURN(SetstateKeyword); setverdict RETURN(SetVerdictKeyword); signature RETURN(SignatureKeyword); start RETURN_DOT(StartKeyword); diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y index 5b096d7457cc92b47158cb1608eb0fc6be6d731d..5d771c1fc2571aaa1a67789711b31460927943c9 100644 --- a/compiler2/ttcn3/compiler.y +++ b/compiler2/ttcn3/compiler.y @@ -748,6 +748,7 @@ static const string anyname("anytype"); %token SenderKeyword %token SendOpKeyword %token SetKeyword +%token SetstateKeyword %token SetVerdictKeyword %token SignatureKeyword %token StartKeyword @@ -994,7 +995,7 @@ static const string anyname("anytype"); StartTimerStatement StopExecutionStatement StopStatement StopTCStatement StopTimerStatement TimeoutStatement TimerStatements TriggerStatement UnmapStatement VerdictStatements WhileStatement SelectCaseConstruct - SelectUnionConstruct UpdateStatement + SelectUnionConstruct UpdateStatement SetstateStatement StopTestcaseStatement String2TtcnStatement ProfilerStatement int2enumStatement %type <statementblock> StatementBlock optElseClause FunctionStatementOrDefList ControlStatementOrDefList ModuleControlBody @@ -1346,6 +1347,7 @@ SenderSpec SetDef SetLocalVerdict SetOfDef +SetstateStatement Signature SignatureDef SignatureFormalPar @@ -4264,6 +4266,7 @@ FunctionStatement: // 180 | ProfilerStatement { $$ = $1; } | int2enumStatement { $$ = $1; } | UpdateStatement { $$ = $1; } +| SetstateStatement { $$ = $1; } ; FunctionInstance: /* refpard */ // 181 @@ -8335,6 +8338,18 @@ UpdateStatement: } ; +SetstateStatement: + PortKeyword '.' SetstateKeyword '(' SingleExpression ')' + { + $$ = new Statement(Statement::S_SETSTATE, $5); + $$->set_location(infile, @$); + } +| PortKeyword '.' SetstateKeyword '(' SingleExpression ',' TemplateInstance ')' + { + $$ = new Statement(Statement::S_SETSTATE, $5, $7); + $$->set_location(infile, @$); + } + ProfilerRunningOp: TitanSpecificProfilerKeyword DotRunningKeyword { diff --git a/compiler2/ttcn3/port.c b/compiler2/ttcn3/port.c index b762ae6b106f5a6a2ec47ebed095254983e72db2..c4a876e2956cd049151d1dd25cc85caf10ddfe81 100644 --- a/compiler2/ttcn3/port.c +++ b/compiler2/ttcn3/port.c @@ -81,6 +81,9 @@ static char *generate_send_mapping(char *src, const port_def *pdef, } } src = mputstr(src, ") {\n"); + src = mputstr(src, "TTCN_Runtime::set_translation_mode(TRUE, this);\n"); + // Set to unset + src = mputstr(src, "TTCN_Runtime::set_port_state(-1, \"by test environment.\", TRUE);\n"); } if (mapped_type->nTargets > 1) src = mputstr(src, "{\n"); switch (target->mapping_type) { @@ -162,8 +165,10 @@ static char *generate_send_mapping(char *src, const port_def *pdef, default: FATAL_ERROR("generate_send_mapping(): invalid mapping type"); } - if (!pdef->legacy) { - src = mputstr(src, "if (mapped_par.is_bound()) {\n"); // temporary solution instead of setstate + if (!pdef->legacy && pdef->port_type == USER) { + src = mputstr(src, + "TTCN_Runtime::set_translation_mode(FALSE, NULL);\n" + "if (port_state == TRANSLATED) {\n"); } src = mputprintf(src, "if (TTCN_Logger::log_this_event(" "TTCN_Logger::PORTEVENT_DUALSEND)) {\n" @@ -196,8 +201,11 @@ static char *generate_send_mapping(char *src, const port_def *pdef, } report_error = TRUE; } - if (!pdef->legacy) { - src = mputstr(src, "}\n"); + if (!pdef->legacy && pdef->port_type == USER) { + src = mputprintf(src, + "} else if (port_state == UNSET) {\n" + "TTCN_error(\"The state of the port %%s remained unset after the mapping function %s finished.\", port_name);\n" + "}\n", target->mapping.function.dispname); } if (mapped_type->nTargets > 1) src = mputstr(src, "}\n"); if (!pdef->legacy && pdef->port_type == USER) { @@ -246,6 +254,10 @@ static char *generate_incoming_mapping(char *src, const port_def *pdef, src = mputstr(src, "TTCN_Buffer ttcn_buffer(incoming_par);\n"); /* has_buffer will be set to TRUE later */ } + if (!pdef->legacy && pdef->port_type == USER) { + src = mputstr(src, "TTCN_Runtime::set_translation_mode(TRUE, this);\n"); + src = mputstr(src, "port_state = UNSET;\n"); + } if (mapped_type->nTargets > 1) src = mputstr(src, "{\n"); switch (target->mapping_type) { case M_FUNCTION: @@ -353,8 +365,8 @@ static char *generate_incoming_mapping(char *src, const port_def *pdef, default: FATAL_ERROR("generate_incoming_mapping(): invalid mapping type"); } - src = mputprintf(src, "msg_tail_count++;\n" - "%s" + src = mputprintf(src, "%s" + "msg_tail_count++;\n" "if (TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_DUALRECV)) " "{\n" "TTCN_Logger::log_dualport_map(1, \"%s\",\n" @@ -366,7 +378,9 @@ static char *generate_incoming_mapping(char *src, const port_def *pdef, "new_item->item_selection = MESSAGE_%lu;\n" "new_item->message_%lu = mapped_par;\n" "new_item->sender_component = sender_component;\n", - !pdef->legacy ? "if (mapped_par->is_bound()) {\n" : "", //temporary solution instead of setstate + !pdef->legacy && pdef->port_type == USER ? + "TTCN_Runtime::set_translation_mode(FALSE, NULL);\n" + "if (port_state == TRANSLATED) {\n" : "", target->target_dispname, (unsigned long) target->target_index, (unsigned long) target->target_index); @@ -388,7 +402,15 @@ static char *generate_incoming_mapping(char *src, const port_def *pdef, } else { src = mputstr(src, "return;\n" - "} else delete mapped_par;\n"); + "}"); + if (pdef->port_type == USER && !pdef->legacy) { + src = mputprintf(src, + " else if (port_state == UNSET) {\n" + "delete mapped_par;\n" + "TTCN_error(\"The state of the port %%s remained unset after the mapping function %s finished.\", port_name);\n" + "}\n", target->mapping.function.dispname); + } + src = mputstr(src, "else {\ndelete mapped_par;\n}\n"); } report_error = TRUE; } @@ -1625,16 +1647,17 @@ void defPortClass(const port_def* pdef, output_struct* output) src = mputstr(src, "}\n\n"); } - // Port variables which can be the mapped ports for translation if (pdef->port_type == USER && !pdef->legacy) { def = mputstr(def, "private:\n"); + // Port type variables which can be the mapped ports for translation for (i = 0; i < pdef->provider_msg_outlist.nElements; i++) { def = mputprintf(def, "%s* p_%i;\n", pdef->provider_msg_outlist.elements[i].name, (int)i); } + def = mputstr(def, "translation_port_state port_state;\n"); } - // Port variables which can be the mapper ports for translation - if (pdef->port_type == PROVIDER && pdef->n_mapper_name > 0) { + // Port type variables in the provider types. + if (pdef->n_mapper_name > 0) { def = mputstr(def, "private:\n"); for (i = 0; i < pdef->n_mapper_name; i++) { def = mputprintf(def, "%s* p_%i;\n", pdef->mapper_name[i], (int)i); @@ -1664,11 +1687,11 @@ void defPortClass(const port_def* pdef, output_struct* output) for (i = 0; i < pdef->provider_msg_outlist.nElements; i++) { src = mputprintf(src, "p_%i = NULL;\n", (int)i); } + src = mputprintf(src, "port_state = UNSET;\n"); } - if (pdef->port_type == PROVIDER && pdef->n_mapper_name > 0) { - for (i = 0; i < pdef->n_mapper_name; i++) { - src = mputprintf(src, "p_%i = NULL;\n", (int)i); - } + // Port type variables in the provider types. + for (i = 0; i < pdef->n_mapper_name; i++) { + src = mputprintf(src, "p_%i = NULL;\n", (int)i); } src = mputstr(src, "}\n\n"); @@ -1707,7 +1730,8 @@ void defPortClass(const port_def* pdef, output_struct* output) if (pdef->port_type != USER || (msg->nTargets == 1 && msg->targets[0].mapping_type == M_SIMPLE) || (pdef->port_type == USER && !pdef->legacy)) { // If not in translation mode then send message as normally would. - if (pdef->port_type == USER && !pdef->legacy && msg->nTargets > 1) { + if (pdef->port_type == USER && !pdef->legacy && + (msg->nTargets > 1 || (msg->nTargets > 0 && msg->targets[0].mapping_type != M_SIMPLE))) { src = mputstr(src, "if (!in_translation_mode()) {\n"); } /* the same message type goes through the external interface */ @@ -1731,7 +1755,8 @@ void defPortClass(const port_def* pdef, output_struct* output) "send_par.encode_text(text_buf);\n" "send_data(text_buf, destination_component);\n" "}\n", msg->dispname); - if (pdef->port_type == USER && !pdef->legacy && msg->nTargets > 1) { + if (pdef->port_type == USER && !pdef->legacy && + (msg->nTargets > 1 || (msg->nTargets > 0 && msg->targets[0].mapping_type != M_SIMPLE))) { // If in translation mode then generate the send mappings and send // according to them. src = mputstr(src, "} else {\n"); @@ -2054,7 +2079,7 @@ void defPortClass(const port_def* pdef, output_struct* output) src = mputprintf(src, "void %s::remove_port(%s*) {\n p_%i = NULL;\n}\n\n", class_name, pdef->provider_msg_outlist.elements[i].name, (int)i); } - // in_translation_mode returns true if one of the port variables are not null + // in_translation_mode returns true if one of the port type variables are not null def = mputstr(def, "boolean in_translation_mode() const;\n"); src = mputprintf(src, "boolean %s::in_translation_mode() const {\nreturn ", class_name); for (i = 0; i < pdef->provider_msg_outlist.nElements; i++) { @@ -2064,8 +2089,14 @@ void defPortClass(const port_def* pdef, output_struct* output) } src = mputstr(src, ";\n}\n\n"); + def = mputstr(def, "void change_port_state(translation_port_state state);\n"); + src = mputprintf(src, + "void %s::change_port_state(translation_port_state state) {\n" + "port_state = state;\n" + "}\n\n", class_name); + def = mputstr(def, "private:\n"); - // Resets all port variables to NULL + // Resets all port type variables to NULL def = mputstr(def, "void reset_port_variables();\n"); src = mputprintf(src, "void %s::reset_port_variables() {\n", class_name); for (i = 0; i < pdef->provider_msg_outlist.nElements; i++) { @@ -2073,8 +2104,8 @@ void defPortClass(const port_def* pdef, output_struct* output) } src = mputstr(src, "}\n\n"); } - - if (pdef->port_type == PROVIDER && pdef->n_mapper_name > 0) { + // Port type variables in the provider types. + if (pdef->n_mapper_name > 0) { def = mputstr(def, "public:\n"); // add_port and remove_port is called after the map and unmap statements. for (i = 0; i < pdef->n_mapper_name; i++) { @@ -2085,7 +2116,7 @@ void defPortClass(const port_def* pdef, output_struct* output) src = mputprintf(src, "void %s::remove_port(%s*) {\n p_%i = NULL;\n}\n\n", class_name, pdef->mapper_name[i], (int)i); } def = mputstr(def, "private:\n"); - // Resets all port variables to NULL + // Resets all port type variables to NULL def = mputstr(def, "void reset_port_variables();\n"); src = mputprintf(src, "void %s::reset_port_variables() {\n", class_name); for (i = 0; i < pdef->n_mapper_name; i++) { @@ -2161,7 +2192,7 @@ void defPortClass(const port_def* pdef, output_struct* output) if (found) { src = mputprintf(src, "outgoing_send(send_par);\n"); } else { - src = mputprintf(src, "TTCN_error(\"Cannot send this correctly %s\");\n", pdef->msg_out.elements[i].name); // todo + src = mputprintf(src, "TTCN_error(\"Cannot send message correctly with type %s\");\n", pdef->msg_out.elements[i].name); } src = mputstr(src, "}\n\n"); } @@ -3153,7 +3184,7 @@ void generateTestPortSkeleton(const port_def *pdef) "\tvoid user_start();\n" "\tvoid user_stop();\n\n", class_name, base_class_name, class_name, - pdef->port_type == REGULAR ? " = NULL" : "", class_name); + pdef->port_type == REGULAR || pdef->port_type == USER ? " = NULL" : "", class_name); if (pdef->port_type == PROVIDER && pdef->n_mapper_name > 0) { fprintf(fp, "public:\n"); diff --git a/compiler2/ttcn3/port.h b/compiler2/ttcn3/port.h index 930c50b43c332ebee0a05774f8d48ff2d5df19ed..9258329904dec42440252edb8e6ecaadaabeacd1 100644 --- a/compiler2/ttcn3/port.h +++ b/compiler2/ttcn3/port.h @@ -48,6 +48,7 @@ typedef struct port_msg_type_mapping_target_tag { msg_mapping_type_t mapping_type; union { struct { + const char *dispname; const char *name; function_prototype_t prototype; } function; diff --git a/core/LegacyLogger.cc b/core/LegacyLogger.cc index e4e787ceb39aaff51b72cad5e38339532fd7ee2f..5abd4be365a29cd380fbbdfac5672b5a75e56dcc 100644 --- a/core/LegacyLogger.cc +++ b/core/LegacyLogger.cc @@ -12,6 +12,7 @@ * Kovacs, Ferenc * Raduly, Csaba * Szabados, Kristof + * Szabo, Bence Janos * Szalai, Gabor * Pandi, Krisztian * @@ -1064,6 +1065,15 @@ extract_common: : "was discarded on port %s."), (const char*) dualop.port__name()); break; } + + case API::PortEvent_choice::ALT_setState: { + API::Setstate const& setstate = pec.setState(); + ret_val = mputprintf(ret_val, "The state of the %s port was changed by a setstate operation to %s.", + (const char*)setstate.port__name(), (const char*)setstate.state()); + if (setstate.info().lengthof() != 0) { + ret_val = mputprintf(ret_val, " Information: %s", (const char*)setstate.info()); + } + break; } case API::PortEvent_choice::ALT_portMisc: { API::Port__Misc const& pmisc = pec.portMisc(); diff --git a/core/Logger.cc b/core/Logger.cc index 01291dbc5c15b82f7105f2e908f089216efbc346..ae87ef3694d857fcbf6fe5369c2815081eea0cb2 100644 --- a/core/Logger.cc +++ b/core/Logger.cc @@ -15,6 +15,7 @@ * Kovacs, Ferenc * Raduly, Csaba * Szabados, Kristof + * Szabo, Bence Janos * Szabo, Janos Zoltan – initial implementation * Zalanyi, Balazs Andor * Pandi, Krisztian @@ -202,6 +203,7 @@ const char* TTCN_Logger::severity_subcategory_names[NUMBER_OF_LOGSEVERITIES] = { "DUALRECV", "DUALSEND", "UNQUALIFIED", + "SETSTATE", // STATISTICS: "VERDICT", "UNQUALIFIED", @@ -392,6 +394,7 @@ char *TTCN_Logger::mputstr_severity(char *str, const TTCN_Logger::Severity& seve case TTCN_Logger::PORTEVENT_DUALRECV: case TTCN_Logger::PORTEVENT_DUALSEND: case TTCN_Logger::PORTEVENT_UNQUALIFIED: + case TTCN_Logger::PORTEVENT_SETSTATE: return mputstr(str, "PORTEVENT"); case TTCN_Logger::STATISTICS_VERDICT: case TTCN_Logger::STATISTICS_UNQUALIFIED: @@ -1417,6 +1420,12 @@ void TTCN_Logger::log_dualport_discard(boolean incoming, const char *target_type unhandled); } +void TTCN_Logger::log_setstate(const char* port_name, translation_port_state state, + const CHARSTRING& info) +{ + get_logger_plugin_manager()->log_setstate(port_name, state, info); +} + void TTCN_Logger::log_port_misc(int reason, const char *port_name, int remote_component, const char *remote_port, const char *ip_address, int tcp_port, int new_size) diff --git a/core/Logger.hh b/core/Logger.hh index 18c74dcfcc4c0252b89e701b09d396f87292673e..a50f1edb67fb34ceeff952f1c6b172258e8ce33c 100644 --- a/core/Logger.hh +++ b/core/Logger.hh @@ -14,6 +14,7 @@ * Kovacs, Ferenc * Raduly, Csaba * Szabados, Kristof + * Szabo, Bence Janos * Szabo, Janos Zoltan – initial implementation * Zalanyi, Balazs Andor * Pandi, Krisztian @@ -123,45 +124,46 @@ public: PORTEVENT_DUALRECV, PORTEVENT_DUALSEND, PORTEVENT_UNQUALIFIED, //35 + PORTEVENT_SETSTATE, STATISTICS_VERDICT, STATISTICS_UNQUALIFIED, TIMEROP_READ, - TIMEROP_START, - TIMEROP_GUARD, //40 + TIMEROP_START, //40 + TIMEROP_GUARD, TIMEROP_STOP, TIMEROP_TIMEOUT, TIMEROP_UNQUALIFIED, - USER_UNQUALIFIED, + USER_UNQUALIFIED, //45 - VERDICTOP_GETVERDICT, //45 + VERDICTOP_GETVERDICT, VERDICTOP_SETVERDICT, VERDICTOP_FINAL, VERDICTOP_UNQUALIFIED, - WARNING_UNQUALIFIED, + WARNING_UNQUALIFIED, //50 // MATCHING and DEBUG should be at the end (not included in LOG_ALL) - MATCHING_DONE, //50 + MATCHING_DONE, MATCHING_TIMEOUT, MATCHING_PCSUCCESS, MATCHING_PCUNSUCC, - MATCHING_PMSUCCESS, - MATCHING_PMUNSUCC, //55 + MATCHING_PMSUCCESS, //55 + MATCHING_PMUNSUCC, MATCHING_MCSUCCESS, MATCHING_MCUNSUCC, MATCHING_MMSUCCESS, - MATCHING_MMUNSUCC, - MATCHING_PROBLEM, //60 + MATCHING_MMUNSUCC, //60 + MATCHING_PROBLEM, MATCHING_UNQUALIFIED, DEBUG_ENCDEC, DEBUG_TESTPORT, DEBUG_USER, DEBUG_FRAMEWORK, - DEBUG_UNQUALIFIED, //66 + DEBUG_UNQUALIFIED, //67 NUMBER_OF_LOGSEVERITIES, // must follow the last individual severity LOG_ALL_IMPORTANT @@ -735,6 +737,8 @@ public: const CHARSTRING& value, int id); static void log_dualport_discard(boolean incoming, const char *target_type, const char *port_name, boolean unhaldled); + static void log_setstate(const char *port_name, translation_port_state state, + const CHARSTRING& info); static void log_port_misc(int reason, const char *port_name, int remote_component = NULL_COMPREF, const char *remote_port = NULL, diff --git a/core/LoggerPluginManager.cc b/core/LoggerPluginManager.cc index bcd5bf22f7d08bfcd91b782e63fd40ab9cca47fd..e3a2a6da1bcbb5af3a26206b8e4952e7b1d60106 100644 --- a/core/LoggerPluginManager.cc +++ b/core/LoggerPluginManager.cc @@ -12,6 +12,7 @@ * Kovacs, Ferenc * Raduly, Csaba * Szabados, Kristof + * Szabo, Bence Janos * Zalanyi, Balazs Andor * Pandi, Krisztian * @@ -1506,6 +1507,40 @@ void LoggerPluginManager::log_dualport_discard(boolean incoming, const char *tar log(event); } +void LoggerPluginManager::log_setstate(const char *port_name, translation_port_state state, + const CHARSTRING& info) +{ + if (!TTCN_Logger::log_this_event(TTCN_Logger::PORTEVENT_SETSTATE) && (TTCN_Logger::get_emergency_logging()<=0)) + return; + API::TitanLogEvent event; + fill_common_fields(event, TTCN_Logger::PORTEVENT_SETSTATE); + + API::Setstate& setstate = event.logEvent().choice().portEvent().choice().setState(); + setstate.port__name() = port_name; + setstate.info() = (const char*)info; + switch (state) { + case UNSET: + setstate.state() = "unset"; + break; + case TRANSLATED: + setstate.state() = "translated"; + break; + case NOT_TRANSLATED: + setstate.state() = "not translated"; + break; + case FRAGMENTED: + setstate.state() = "fragmented"; + break; + case PARTIALLY_TRANSLATED: + setstate.state() = "partially translated"; + break; + default: + TTCN_Logger::fatal_error("LoggerPluginManager::log_setstate(): unexpected port state"); + } + + log(event); +} + void LoggerPluginManager::log_port_misc(int reason, const char *port_name, int remote_component, const char *remote_port, const char *ip_address, int tcp_port, int new_size) diff --git a/core/LoggerPluginManager.hh b/core/LoggerPluginManager.hh index e31d1927a94aebd85d7fa1faf799f7dd5f94aa1d..e332ed1268dcf174007ff5eb75c686b5feaf51eb 100644 --- a/core/LoggerPluginManager.hh +++ b/core/LoggerPluginManager.hh @@ -11,6 +11,7 @@ * Kovacs, Ferenc * Raduly, Csaba * Szabados, Kristof + * Szabo, Bence Janos * Zalanyi, Balazs Andor * Pandi, Krisztian * @@ -224,6 +225,8 @@ public: const CHARSTRING& value, int id); void log_dualport_discard(boolean incoming, const char *target_type, const char *port_name, boolean unhandled); + void log_setstate(const char *port_name, translation_port_state state, + const CHARSTRING& info); void log_port_misc(int reason, const char *port_name, int remote_component, const char *remote_port, const char *ip_address, int tcp_port, int new_size); diff --git a/core/LoggingBits.cc b/core/LoggingBits.cc index 48189d8f0c920f856d68d63ba09f1e8f6bcc5472..4da48036e97f409d5e83053a393ec94c330a6683 100644 --- a/core/LoggingBits.cc +++ b/core/LoggingBits.cc @@ -9,6 +9,7 @@ * Balasko, Jeno * Delic, Adam * Raduly, Csaba + * Szabo, Bence Janos * ******************************************************************************/ #include "LoggingBits.hh" @@ -120,7 +121,7 @@ const Logging_Bits Logging_Bits::log_all = { 1,1, // FUNCTION 1,1,1,1, // PARALLEL 1,1,1, // TESTCASE - 1,1,1,1,1,1,1,1,1,1,1,1,1,1, // PORTEVENT + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // PORTEVENT 1,1, // STATISTICS 1,1,1,1,1,1, // TIMEROP 1, // USER @@ -133,7 +134,7 @@ const Logging_Bits Logging_Bits::log_all = { const Logging_Bits Logging_Bits::log_everything = { { 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 } + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 } }; // TTCN_ERROR | TTCN_WARNING | TTCN_ACTION | TTCN_TESTCASE | TTCN_STATISTICS @@ -146,7 +147,7 @@ const Logging_Bits Logging_Bits::default_console_mask = { 0,0, // FUNCTION 0,0,0,0, // PARALLEL 1,1,1, // TESTCASE - 0,0,0,0,0,0,0,0,0,0,0,0,0,0, // PORTEVENT + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // PORTEVENT 1,1, // STATISTICS 0,0,0,0,0,0, // TIMEROP 0, // USER diff --git a/core/Port.cc b/core/Port.cc index 0451572b05ad92e2688ce48daf072d93877dc82b..7fdfc1de480e6d90698ad08fd59b47a0413c234e 100644 --- a/core/Port.cc +++ b/core/Port.cc @@ -2215,6 +2215,10 @@ void PORT::reset_port_variables() { } +void PORT::change_port_state(translation_port_state /*state*/) { + +} + void PORT::process_connect_listen(const char *local_port, component remote_component, const char *remote_port, transport_type_enum transport_type) diff --git a/core/Port.hh b/core/Port.hh index 4e1c582852744c044eaad086b0222f2bbae45317..f75927a288babf0373018a30bf4fe279735471b8 100644 --- a/core/Port.hh +++ b/core/Port.hh @@ -133,6 +133,9 @@ public: boolean check_port_state(const CHARSTRING& type) const; static boolean any_check_port_state(const CHARSTRING& type); static boolean all_check_port_state(const CHARSTRING& type); + + // Used by the setstate operation through TTCN_Runtime + virtual void change_port_state(translation_port_state state); virtual alt_status receive(const COMPONENT_template& sender_template = any_compref, COMPONENT *sender_ptr = NULL, diff --git a/core/Runtime.cc b/core/Runtime.cc index 64fad5f1f39d9064b38fd89a697fa6c13c63d8c5..67eee909ef904d3a79f39fee6a3257b4ea7da9b2 100644 --- a/core/Runtime.cc +++ b/core/Runtime.cc @@ -59,6 +59,8 @@ #include "Fd_And_Timeout_User.hh" #include <TitanLoggerApi.hh> #include "Profiler.hh" +#include "Integer.hh" +#include "Port.hh" namespace API = TitanLoggerApi; @@ -116,6 +118,31 @@ struct TTCN_Runtime::component_process_struct { } **TTCN_Runtime::components_by_compref = NULL, **TTCN_Runtime::components_by_pid = NULL; +boolean TTCN_Runtime::translation_flag = FALSE; +PORT* TTCN_Runtime::p = NULL; + +void TTCN_Runtime::set_port_state(const INTEGER& state, const CHARSTRING& info, boolean by_system) { + if (translation_flag) { + if (p != NULL) { + int lowed_end = by_system ? -1 : 0; + if (state < lowed_end || state > 3) { + TTCN_error("The value of the first parameter in the setstate operation must be 0, 1, 2 or 3."); + } + p->change_port_state((translation_port_state)((int)state)); + TTCN_Logger::log_setstate(p->get_name(), (translation_port_state)((int)state), info); + } else { + TTCN_error("Internal error: TTCN_Runtime::set_port_state: The port is NULL."); + } + } else { + TTCN_error("setstate operation was called without being in a translation procedure."); + } +} + +void TTCN_Runtime::set_translation_mode(boolean enabled, PORT* port) { + translation_flag = enabled; + p = port; +} + boolean TTCN_Runtime::is_idle() { switch (executor_state) { diff --git a/core/Runtime.hh b/core/Runtime.hh index 4be6bba6f44d8d1e0819819e821d26d70265e751..798f2e8e6c19e7977bfa92ce2c5a1c4cf2aad3df 100644 --- a/core/Runtime.hh +++ b/core/Runtime.hh @@ -29,6 +29,8 @@ class Text_Buf; class COMPONENT; class VERDICTTYPE; class CHARSTRING; +class INTEGER; +class PORT; extern "C" { typedef void (*signal_handler_type)(int); @@ -93,6 +95,12 @@ private: struct component_process_struct; static component_process_struct **components_by_compref, **components_by_pid; + + // Translation flag is set to true before each port translation function called, + // and set to false after each port translation function. + static boolean translation_flag; + // The port which state will be changed by change_port_state + static PORT* p; public: inline static executor_state_enum get_state() { return executor_state; } @@ -122,6 +130,9 @@ public: /** @} */ static boolean is_in_ttcn_try_block() { return in_ttcn_try_block; } + + static void set_port_state(const INTEGER& state, const CHARSTRING& info, boolean by_system); + static void set_translation_mode(boolean enabled, PORT* port); private: inline static boolean in_controlpart() diff --git a/core/TitanLoggerApi.xsd b/core/TitanLoggerApi.xsd index 77c225ae9cc03ff2f2fcc0761c814f818c935b3f..a2afa7fcb7cb3119a0bcaf99a7bdeac4fcef6a60 100644 --- a/core/TitanLoggerApi.xsd +++ b/core/TitanLoggerApi.xsd @@ -271,6 +271,7 @@ <element name="dualMapped" type="TitanLoggerApi:Dualface_mapped" /> <element name="dualDiscard" type="TitanLoggerApi:Dualface_discard" /> + <element name="setState" type="TitanLoggerApi:Setstate" /> <element name="portMisc" type="TitanLoggerApi:Port_Misc" /> </choice> @@ -915,6 +916,14 @@ </sequence> </complexType> +<complexType name="Setstate"> + <sequence> + <element name="port_name" type="string" /> + <element name="state" type="string" /> + <element name="info" type="string" /> + </sequence> +</complexType> + <complexType name="Port_Misc"> <sequence> <element name="reason"> diff --git a/core/TitanLoggerControl.ttcn b/core/TitanLoggerControl.ttcn index 2898b2a95cb1e8641c012b838de7b22d1ac9a62a..85b84c19befe53226b7d0413a2f8d40251ee692e 100644 --- a/core/TitanLoggerControl.ttcn +++ b/core/TitanLoggerControl.ttcn @@ -81,6 +81,7 @@ type enumerated Severity // copy-paste from Logger.hh PORTEVENT_DUALRECV, PORTEVENT_DUALSEND, PORTEVENT_UNQUALIFIED, + PORTEVENT_SETSTATE, STATISTICS_VERDICT, STATISTICS_UNQUALIFIED, @@ -164,7 +165,7 @@ const Severities log_all := PORTEVENT_PQUEUE, PORTEVENT_MQUEUE, PORTEVENT_STATE, PORTEVENT_PMIN, PORTEVENT_PMOUT, PORTEVENT_PCIN, PORTEVENT_PCOUT, PORTEVENT_MMRECV, PORTEVENT_MMSEND, PORTEVENT_MCRECV, PORTEVENT_MCSEND, - PORTEVENT_DUALRECV, PORTEVENT_DUALSEND, PORTEVENT_UNQUALIFIED, + PORTEVENT_DUALRECV, PORTEVENT_DUALSEND, PORTEVENT_UNQUALIFIED, PORTEVENT_SETSTATE, STATISTICS_VERDICT, STATISTICS_UNQUALIFIED, @@ -198,7 +199,7 @@ const Severities log_everything := PORTEVENT_PQUEUE, PORTEVENT_MQUEUE, PORTEVENT_STATE, PORTEVENT_PMIN, PORTEVENT_PMOUT, PORTEVENT_PCIN, PORTEVENT_PCOUT, PORTEVENT_MMRECV, PORTEVENT_MMSEND, PORTEVENT_MCRECV, PORTEVENT_MCSEND, - PORTEVENT_DUALRECV, PORTEVENT_DUALSEND, PORTEVENT_UNQUALIFIED, + PORTEVENT_DUALRECV, PORTEVENT_DUALSEND, PORTEVENT_UNQUALIFIED, PORTEVENT_SETSTATE, STATISTICS_VERDICT, STATISTICS_UNQUALIFIED, diff --git a/core/Types.h b/core/Types.h index 85b35525fd76bc7050af506d5e61ab530dbee13a..1ffd1dbf98460a6818c4ef8cbc8bdc64d49c969b 100644 --- a/core/Types.h +++ b/core/Types.h @@ -12,6 +12,7 @@ * Forstner, Matyas * Kovacs, Ferenc * Raduly, Csaba + * Szabo, Bence Janos * Szabo, Janos Zoltan – initial implementation * Zalanyi, Balazs Andor * @@ -128,4 +129,13 @@ struct namespace_t { const char * const px; }; +// States defined with the setstate operation. +enum translation_port_state { + UNSET = -1, + TRANSLATED = 0, + NOT_TRANSLATED = 1, + FRAGMENTED = 2, + PARTIALLY_TRANSLATED = 3 +}; + #endif diff --git a/core/config_process.l b/core/config_process.l index b88b61ab4c363405dc7da1dbff974be2f3a82d45..3f8a760bc988fc17078bd9836b021510e8da9bf6 100644 --- a/core/config_process.l +++ b/core/config_process.l @@ -894,6 +894,10 @@ PORTEVENT_UNQUALIFIED { yylval.logseverity_val = TTCN_Logger::PORTEVENT_UNQUALIFIED; return LoggingBit; } +PORTEVENT_SETSTATE { + yylval.logseverity_val = TTCN_Logger::PORTEVENT_SETSTATE; + return LoggingBit; + } (TTCN_)?PORTEVENT { yylval.logseverity_val = TTCN_Logger::PORTEVENT_UNQUALIFIED; return LoggingBitCollection; diff --git a/core/config_process.y b/core/config_process.y index 82ae8ed8e65dcdec9d72b1981f94175da0b5ed52..72bea827cf2a8e6649f0c51dea37e1a917d09e3a 100644 --- a/core/config_process.y +++ b/core/config_process.y @@ -1708,6 +1708,7 @@ LoggingBitOrCollection: $$.add_sev(TTCN_Logger::PORTEVENT_DUALRECV); $$.add_sev(TTCN_Logger::PORTEVENT_DUALSEND); $$.add_sev(TTCN_Logger::PORTEVENT_UNQUALIFIED); + $$.add_sev(TTCN_Logger::PORTEVENT_SETSTATE); break; case TTCN_Logger::TESTCASE_UNQUALIFIED: $$.add_sev(TTCN_Logger::TESTCASE_START); diff --git a/function_test/Semantic_Analyser/port_translation/Setstate_SE.ttcn b/function_test/Semantic_Analyser/port_translation/Setstate_SE.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..ca283746ee34b13468da0c1cf481614aa563f280 --- /dev/null +++ b/function_test/Semantic_Analyser/port_translation/Setstate_SE.ttcn @@ -0,0 +1,24 @@ +/****************************************************************************** + * 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: + * Szabo, Bence Janos + * + ******************************************************************************/ +module Setstate_SE { //^In TTCN-3 module// + + const integer i1 := 4; + const integer i2 := 9999999999999999999999999999999999999999999999999999; + + function f() { //^In function definition \`f\'\:// + port.setstate(-1); //^In setstate statement\:// //^In first parameter\:// //^error\: The value of the first parameter must be 0\, 1\, 2 or 3\.// + port.setstate(9999999999999999999999999999999999999999999999999999); //^In setstate statement\:// //^In first parameter\:// //^error\: The value of the first parameter must be 0\, 1\, 2 or 3\.// + port.setstate(i1); //^In setstate statement\:// //^In first parameter\:// //^error\: The value of the first parameter must be 0\, 1\, 2 or 3\.// + port.setstate(i2); //^In setstate statement\:// //^In first parameter\:// //^error\: The value of the first parameter must be 0\, 1\, 2 or 3\.// + } + +} \ No newline at end of file diff --git a/help/info/BNF.html b/help/info/BNF.html index 6baa4bc511ecdd96a686f71bb06ddeed55a41cc3..918cf9fef08d82aa35c35965a93c0c2ce52783c4 100644 --- a/help/info/BNF.html +++ b/help/info/BNF.html @@ -374,6 +374,22 @@ This ABNF browser was generated from file <mockup_bnf.txt> on Tue Jul 20 1 <TD></TD> <TD></TD> </TR> + <TR VALIGN=TOP> + <TD> + <P><A NAME="setstatedef"></a><A HREF="#Xref.SetstateDef">SetstateDef</A> + <TD VALIGN=TOP>=</TD> + <TD><A HREF="#portkeyword">PortKeyword</A> . <A HREF="#setstatekeyword">SetstateKeyword</A> ( <A HREF="#singleexpression">SingleExpression</A> "," [ <A HREF="#freetext">FreeText</A> | <A HREF="#templateinstance">TemplateInstance</A></TD> + </TR> + <TR VALIGN=TOP> + <TD> + <P><A NAME="setstatekeyword"></a><A HREF="#Xref.SetstateKeyword">SetstateKeyword</A> + <TD VALIGN=TOP>=</TD> + <TD>"<FONT COLOR="black">setstate</FONT>"</TD> + </TR> + <TR VALIGN=TOP> + <TD></TD> + <TD></TD> + </TR> <TR VALIGN=TOP> <TD> <P><A NAME="recordofdef"></a><A HREF="#Xref.RecordOfDef">RecordOfDef</A> @@ -5796,7 +5812,7 @@ This ABNF browser was generated from file <mockup_bnf.txt> on Tue Jul 20 1 </TR> <TR VALIGN=TOP> <TD><A NAME="Xref.FreeText"></a><A HREF="#freetext">FreeText</A></TD> - <TD><A HREF="#languagespec">LanguageSpec</A>, <A HREF="#attribspec">AttribSpec</A>, <A HREF="#sutstatements">SUTStatements</A>, <A HREF="#logstatement">LogStatement</A></TD> + <TD><A HREF="#languagespec">LanguageSpec</A>, <A HREF="#attribspec">AttribSpec</A>, <A HREF="#sutstatements">SUTStatements</A>, <A HREF="#logstatement">LogStatement</A>, <A HREF="#setstatedef">SetstateDef</A></TD> </TR> <TR VALIGN=TOP> <TD><A NAME="Xref.FromClause"></a><A HREF="#fromclause">FromClause</A></TD> @@ -6496,7 +6512,7 @@ This ABNF browser was generated from file <mockup_bnf.txt> on Tue Jul 20 1 </TR> <TR VALIGN=TOP> <TD><A NAME="Xref.PortKeyword"></a><A HREF="#portkeyword">PortKeyword</A></TD> - <TD><A HREF="#portdef">PortDef</A>, <A HREF="#portinstance">PortInstance</A>, <A HREF="#portorany">PortOrAny</A>, <A HREF="#portorall">PortOrAll</A></TD> + <TD><A HREF="#portdef">PortDef</A>, <A HREF="#portinstance">PortInstance</A>, <A HREF="#portorany">PortOrAny</A>, <A HREF="#portorall">PortOrAll</A>, <A HREF="#setstatedef">SetstateDef</A></TD> </TR> <TR VALIGN=TOP> <TD><A NAME="Xref.PortOrAll"></a><A HREF="#portorall">PortOrAll</A></TD> @@ -6790,6 +6806,10 @@ This ABNF browser was generated from file <mockup_bnf.txt> on Tue Jul 20 1 <TD><A NAME="Xref.SetOfDef"></a><A HREF="#setofdef">SetOfDef</A></TD> <TD><A HREF="#structuredtypedef">StructuredTypeDef</A></TD> </TR> + <TR VALIGN=TOP> + <TD><A NAME="Xref.SetstateKeyword"></a><A HREF="#setstatekeyword">SetstateKeyword</A></TD> + <TD><A HREF="#setstatedef">SetstateDef</A></TD> + </TR> <TR VALIGN=TOP> <TD><A NAME="Xref.SetVerdictKeyword"></a><A HREF="#setverdictkeyword">SetVerdictKeyword</A></TD> <TD><A HREF="#setlocalverdict">SetLocalVerdict</A></TD> @@ -6856,7 +6876,7 @@ This ABNF browser was generated from file <mockup_bnf.txt> on Tue Jul 20 1 <TR VALIGN=TOP> <TD><A NAME="Xref.SingleExpression"></a><A HREF="#singleexpression">SingleExpression</A></TD> <TD><A HREF="#fieldorbitnumber">FieldOrBitNumber</A>, <A HREF="#singlevalueorattrib">SingleValueOrAttrib</A>, <A HREF="#setlocalverdict">SetLocalVerdict</A>, <A HREF="#expression">Expression</A>, - <A HREF="#singleconstexpression">SingleConstExpression</A>, <A HREF="#booleanexpression">BooleanExpression</A>, <A HREF="#primary">Primary</A></TD> + <A HREF="#singleconstexpression">SingleConstExpression</A>, <A HREF="#booleanexpression">BooleanExpression</A>, <A HREF="#primary">Primary</A>, <A HREF="#setstatedef">SetstateDef</A></TD> </TR> <TR VALIGN=TOP> <TD><A NAME="Xref.SingleTimerInstance"></a><A HREF="#singletimerinstance">SingleTimerInstance</A></TD> @@ -7049,7 +7069,7 @@ This ABNF browser was generated from file <mockup_bnf.txt> on Tue Jul 20 1 <TD><A NAME="Xref.TemplateInstance"></a><A HREF="#templateinstance">TemplateInstance</A></TD> <TD><A HREF="#templateactualpar">TemplateActualPar</A>, <A HREF="#matchop">MatchOp</A>, <A HREF="#valueofop">ValueofOp</A>, <A HREF="#functionactualpar">FunctionActualPar</A>, <A HREF="#testcaseactualpar">TestcaseActualPar</A>, <A HREF="#sendparameter">SendParameter</A>, <A HREF="#callparameters">CallParameters</A>, <A HREF="#portreplyop">PortReplyOp</A>, <A - HREF="#portraiseop">PortRaiseOp</A>, <A HREF="#receiveparameter">ReceiveParameter</A>, <A HREF="#valuematchspec">ValueMatchSpec</A>, <A HREF="#catchopparameter">CatchOpParameter</A></TD> + HREF="#portraiseop">PortRaiseOp</A>, <A HREF="#receiveparameter">ReceiveParameter</A>, <A HREF="#valuematchspec">ValueMatchSpec</A>, <A HREF="#catchopparameter">CatchOpParameter</A>, <A HREF="#setstatedef">SetstateDef</A></TD> </TR> <TR VALIGN=TOP> <TD><A NAME="Xref.TemplateKeyword"></a><A HREF="#templatekeyword">TemplateKeyword</A></TD> diff --git a/help/info/set.html b/help/info/set.html index 3bca52eb20f994940e70eb2cc9f68ad8641a2eb0..7883c059de69297a21689770f4f7fb24363f5211 100644 --- a/help/info/set.html +++ b/help/info/set.html @@ -32,7 +32,7 @@ <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td> <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td> <td><a href="sender.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> - <td><a href="setverdict.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> + <td><a href="setstate.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> </tr> </table> <p><br clear="all"> diff --git a/help/info/setstate.html b/help/info/setstate.html new file mode 100644 index 0000000000000000000000000000000000000000..63d74017a66424ad1fd8949d13916e539ded80c0 --- /dev/null +++ b/help/info/setstate.html @@ -0,0 +1,81 @@ +<!-- + 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: + Szabo, Bence Janos +--> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<meta http-equiv="Content-Language" content="en-us"> +<title>set</title> +</head> +<body bgcolor="#DAD3C5" vlink="#0094D2" link="#003258"> +<table align="left" border="0" cellspacing="0" cellpadding="0" valign=top> + <tr> + <td width=105 height=40><a href="https://projects.eclipse.org/projects/tools.titan"><img src="../images/titan_transparent.gif" border=0 width=105 height=40 align="left" alt="Titan"></a></td> + </tr> +</table> +<table border="0" align="right" cellpadding="0" cellspacing="0"> + <tr> + <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td> + <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td> + <td><a href="set.html" alt="previous"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> + <td><a href="setverdict.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> + </tr> +</table> +<p><br clear="all"> +</p> +<hr> +<h1>setstate</h1> +<hr align="left" width="75%"> +<p>The setstate operation can change the state of the port during a translation procedure. It can only be used inside a function that is called during a translation procedure to translate a sent or received message. +<ul> + <li>The setstate operation has two parameters. The second parameter is optional.</li> + <li>The first parameter has to be a type of integer and only the 0 (translated), 1 (not translated), 2 (fragmented) and 3 (partially translated) values are accepted.</li> + <li>The second parameter can be used for logging purposes.</li> +</ul> +<p>Related keywords:</p> +<ul> + <li><a href="port.html"><font face="Courier New" color="#003258" size="4"><b>port</b></font></a></li> + <li><a href="map.html"><font face="Courier New" color="#003258" size="4"><b>map</b></font></a></li> +</ul> +<hr align="left" width="50%"> +<div align="center"> +<center> +<table border="0" width="90%" bgcolor="#FFB599" cellpadding="4"> + <tr> + <td width="100%"> + <h3 align="center"><font face="Courier New" color="#003258" size="5"><b>port.setstate</b> </font> (<i>SimpleExpression ,</i> <font + face="Courier New" color="#003258" size="5"><b> {</b></font> <i>Freetext | TemplateInstance</i> [ <font face="Courier New" color="#003258" size="5"><b>optional</b></font> + ]<font face="Courier New" color="#003258" size="5"><b>};</b></font></h3> + </td> + </tr> +</table> +</center> +</div> +<ul> + <li> + <p><i>SimpleExpression</i> is the state which the ports state will be changed, and has to be of integer type.</p> + </li> + <li> + <p><i>FreeText or TemplateInstance</i> can be used for logging. Its value will be present in the logfile.</p> + </li> +</ul> +<hr align="left" width="50%"> +<p><a name="Example 1">Example 1</a>: set ports state to translated without additional information +<p><font face="Courier New">port.setstate(0); +</font> +<hr align="left" width="50%"> +<p><a name="Example 2">Example 2</a>: set the state of the port to not translated with additional information +<p><font face="Courier New">port.setstate(1, "Not successful");<br> +</font> +<hr align="left" width="25%"> +<hr align="left" width="25%"> +<p><a HREF="BNF.html#setstatedef">BNF definition</a> of <font face="Courier New"> setstate</font></p> +</body> +</html> diff --git a/help/info/setverdict.html b/help/info/setverdict.html index 548121660d933fca0e574f50f8a74332b1a5672f..5fb4e802f4a6a26bc0c6f689090cee146971af6c 100644 --- a/help/info/setverdict.html +++ b/help/info/setverdict.html @@ -28,7 +28,7 @@ <tr> <td><a href="../titan_main.html" alt="contents"><img border="0" src="../images/ao.jpg" width="53" height="40"></a></td> <td><a href="../titan_index.html" alt="index"><img border="0" src="../images/up.jpg" width="53" height="40"></a></td> - <td><a alt="previous" href="set.html"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> + <td><a alt="previous" href="setstate.html"><img border="0" src="../images/left.jpg" width="53" height="40"></a></td> <td><a href="signature.html" alt="next"><img border="0" src="../images/right.jpg" width="53" height="40"></a></td> </tr> </table> diff --git a/help/titan_index.html b/help/titan_index.html index 905aeff535aa0bdbc02d179f297a538176f586d3..16437d6d5e741e1b82fc8657037c8aa13c929c75 100644 --- a/help/titan_index.html +++ b/help/titan_index.html @@ -16,6 +16,7 @@ Kovacs, Ferenc Raduly, Csaba Szabados, Kristof + Szabo, Bence Janos Zalanyi, Balazs Andor --> <html> @@ -321,26 +322,26 @@ <td width="17%"><a href="info/send.html">send</a></td> <td width="17%"><a href="info/sender.html">sender</a></td> <td width="17%"><a href="info/set.html">set</a></td> + <td width="17%"><a href="info/setstate.html">setstate</a></td> <td width="17%"><a href="info/setverdict.html">setverdict</a></td> - <td width="17%"><a href="info/signature.html">signature</a></td> </tr> <tr> + <td width="17%"><a href="info/signature.html">signature</a></td> <td width="17%"><a href="info/sizeof.html">sizeof</a></td> <td width="17%"><a href="info/start.html">start</a></td> <td width="17%"><a href="info/stop.html">stop</a></td> <td width="17%"><a href="info/str2bit.html">str2bit</a></td> <td width="17%"><a href="info/str2float.html">str2float</a></td> <td width="17%"><a href="info/str2hex.html">str2hex</a></td> - <td width="17%"><a href="info/str2int.html">str2int</a></td> </tr> <tr> + <td width="17%"><a href="info/str2int.html">str2int</a></td> <td width="17%"><a href="info/str2oct.html">str2oct</a></td> <td width="17%"><a href="info/subset.html">subset</a></td> <td width="17%"><a href="info/substr.html">substr</a></td> <td width="17%"><a href="info/superset.html">superset</a></td> <td width="17%"><a href="info/system.html">system</a></td> <td width="17%"> </td> - <td width="17%"> </td> </tr> <tr> <td width="17%"><a name="t"></a><a href="info/template.html">template</a></td> diff --git a/mctr2/cli/config_read.l b/mctr2/cli/config_read.l index c19066b9f129c05d7478376dab4c2831b282d362..5b232c98e2885b131c39ca93faed1a5a8f0fae52 100644 --- a/mctr2/cli/config_read.l +++ b/mctr2/cli/config_read.l @@ -579,6 +579,7 @@ PORTEVENT_PMOUT | PORTEVENT_PQUEUE | PORTEVENT_STATE | PORTEVENT_UNQUALIFIED | +PORTEVENT_SETSTATE | STATISTICS_UNQUALIFIED | STATISTICS_VERDICT | TESTCASE_FINISH | diff --git a/regression_test/compileonly/portTranslation/PortTranslate.ttcn b/regression_test/compileonly/portTranslation/PortTranslate.ttcn index 1d6ef2304e0bcdb0a248ae63a686eba1339bfd53..d0d1e74ad7d44aacb5cf6bb973a8b6504ea2d758 100644 --- a/regression_test/compileonly/portTranslation/PortTranslate.ttcn +++ b/regression_test/compileonly/portTranslation/PortTranslate.ttcn @@ -293,7 +293,14 @@ module PortTranslate { } + type component Comp1 { + port PT16 pt16[4][5][5]; + port P22 p22[3][5][6]; + } + testcase tc_port_arr() runs on Comp1 { + map(self:pt16[1][2][3], system:p22[1][2][3]); + } /* Conversion functions */ @@ -426,4 +433,5 @@ module PortTranslate { } + } \ No newline at end of file diff --git a/regression_test/portTranslation/Makefile b/regression_test/portTranslation/Makefile index 2e832903ba7a2b97403099e05cb420c9492ca2e4..108ffb482c566d1bcc76ef3097a497c3b0160563 100644 --- a/regression_test/portTranslation/Makefile +++ b/regression_test/portTranslation/Makefile @@ -47,14 +47,14 @@ TTCN3_LIB = ttcn3$(RT2_SUFFIX)-parallel$(DYNAMIC_SUFFIX) # TTCN-3 modules of this project: -TTCN3_MODULES = PortTranslation.ttcn +TTCN3_MODULES = PortTranslation.ttcn Setstate_neg.ttcn # ASN.1 modules of this project: ASN1_MODULES = # C++ source & header files generated from the TTCN-3 & ASN.1 modules of # this project: -GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) $(ASN1_MODULES:.asn=.cc) +GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) $(ASN1_MODULES:.asn=.cc) NP1.cc NPT2.cc GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh) ifdef SPLIT_TO_SLICES POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_)) @@ -114,7 +114,7 @@ compile:: $(TTCN3_DIR)/bin/compiler # $(TTCN3_COMPILER) @if [ -f $@ ]; then $(RM) compile; $(MAKE) compile; fi compile:: $(TTCN3_MODULES) $(ASN1_MODULES) - $(TTCN3_COMPILER) $(COMPILER_FLAGS) $^ - $? + $(TTCN3_COMPILER) $(COMPILER_FLAGS) -t $^ - $? touch $@ clean distclean: diff --git a/regression_test/portTranslation/P3.cc b/regression_test/portTranslation/P3.cc index 91d1624a49d66f75ab6694ca8815d28e71416a44..0125a047e6ef4864869ed8a4fba61ee98b95dfc1 100644 --- a/regression_test/portTranslation/P3.cc +++ b/regression_test/portTranslation/P3.cc @@ -87,5 +87,15 @@ void P3::outgoing_send(const OCTETSTRING& /*send_par*/) } +void P3::outgoing_send(const HEXSTRING& /*send_par*/) +{ + +} + +void P3::outgoing_send(const INTEGER& /*send_par*/) +{ + +} + } /* end of namespace */ diff --git a/regression_test/portTranslation/P3.hh b/regression_test/portTranslation/P3.hh index ee06a1b105f727bf8b84257ee5d05d8f8d079ab4..c2ecf73f8e61cb0aeceb6e902bdc7f68e811e23c 100644 --- a/regression_test/portTranslation/P3.hh +++ b/regression_test/portTranslation/P3.hh @@ -42,6 +42,8 @@ protected: void outgoing_send(const MyRec& send_par); void outgoing_send(const BITSTRING& send_par); void outgoing_send(const OCTETSTRING& send_par); + void outgoing_send(const HEXSTRING& send_par); + void outgoing_send(const INTEGER& send_par); }; } /* end of namespace */ diff --git a/regression_test/portTranslation/PT2.cc b/regression_test/portTranslation/PT2.cc index 096f62da2c8fc37200e3f1dd4e98a06b0aae9817..e68cf3d33c61754f2832d39aa4146fb5023f9e0d 100644 --- a/regression_test/portTranslation/PT2.cc +++ b/regression_test/portTranslation/PT2.cc @@ -87,5 +87,10 @@ void PT2::outgoing_send(const BITSTRING& /*send_par*/) } +void PT2::outgoing_send(const HEXSTRING& /*send_par*/) +{ + +} + } /* end of namespace */ diff --git a/regression_test/portTranslation/PT2.hh b/regression_test/portTranslation/PT2.hh index 504c09268f0cc0a2bfb3e192d2632b560a082724..613efe348e56fad4845d96ec1174f0cf6c6bda27 100644 --- a/regression_test/portTranslation/PT2.hh +++ b/regression_test/portTranslation/PT2.hh @@ -42,6 +42,7 @@ protected: void outgoing_send(const MyRec& send_par); void outgoing_send(const OCTETSTRING& send_par); void outgoing_send(const BITSTRING& send_par); + void outgoing_send(const HEXSTRING& send_par); }; } /* end of namespace */ diff --git a/regression_test/portTranslation/PortTranslation.ttcn b/regression_test/portTranslation/PortTranslation.ttcn index fbf89f62d9b0d0b034990f534cbf6fb77c5be6de..a628adc6bbe20752e1485aa0e73676438617ac74 100644 --- a/regression_test/portTranslation/PortTranslation.ttcn +++ b/regression_test/portTranslation/PortTranslation.ttcn @@ -13,12 +13,12 @@ module PortTranslation { /* Converter functions */ - // Temporarily if the out param of the mapping functions are unbound it will - // try the next one in order - function MyRec_to_oct(in MyRec i, out octetstring j) { if (i.types == Oct) { j := i.val; + port.setstate(0, "Some message"); // translated + } else { + port.setstate(1); // not translated } } with { extension "prototype(fast)"; @@ -27,6 +27,9 @@ module PortTranslation { function MyRec_to_int(in MyRec i, out integer j) { if (i.types == Int) { j := oct2int(i.val); + port.setstate(0); // translated + } else { + port.setstate(1); // not translated } } with { extension "prototype(fast)"; @@ -35,6 +38,9 @@ module PortTranslation { function MyRec_to_MyRec(in MyRec i, out MyRec j) { if (i.types == MyRec) { j := i; + port.setstate(0); // translated + } else { + port.setstate(1); // not translated } } with { extension "prototype(fast)"; @@ -43,6 +49,9 @@ module PortTranslation { function MyRec_to_char(in MyRec i, out charstring j) { if (i.types == Char) { j := oct2str(i.val); + port.setstate(0); // translated + } else { + port.setstate(1); // not translated } } with { extension "prototype(fast)"; @@ -51,6 +60,9 @@ module PortTranslation { function char_to_hex(in charstring i, out hexstring j) { if (i == "0001") { j := str2hex(i); + port.setstate(0); // translated + } else { + port.setstate(1); // not translated } } with { extension "prototype(fast)"; @@ -59,6 +71,9 @@ module PortTranslation { function char_to_hex2(in charstring i, out hexstring j) { if (i == "0002") { j := str2hex(i); + port.setstate(0); // translated + } else { + port.setstate(1); // not translated } } with { extension "prototype(fast)"; @@ -67,6 +82,9 @@ module PortTranslation { function char_to_char(in charstring i, out charstring j) { if (i == oct2char('010203'O)) { j := ""; + port.setstate(0); // translated + } else { + port.setstate(1); // not translated } } with { extension "prototype(fast)"; @@ -75,11 +93,40 @@ module PortTranslation { function MyRec_to_hex(in MyRec i, out hexstring j) { if (i.types == Hex) { j := oct2hex(i.val); + port.setstate(0); // translated + } else { + port.setstate(1); // not translated + } + } with { + extension "prototype(fast)"; + } + + function hex_to_bit(in hexstring i, out bitstring j) { + if (lengthof(i) > 4) { + j := hex2bit(substr(i, 0, 4)); + i := substr(i, 4, lengthof(i)-4); + port.setstate(3); // partially translated, more messages to decode + } else { + j := hex2bit(substr(i, 0, lengthof(i))); + port.setstate(0); // translated } } with { extension "prototype(fast)"; } + function hex_to_char(in hexstring i, out charstring j) { + // dummy + } with { + extension "prototype(fast)"; + } + + function int_to_bit_bad(in integer i, out bitstring j) { + // do nothing. + // Will generate error because the state of the port stays unset. + } with { + extension "prototype(fast)"; + } + /////////////////////////////////////////////////////////////////////////////// /* Types */ @@ -110,7 +157,7 @@ module PortTranslation { type port P3 message { out MyRec - out bitstring + out bitstring, hexstring, integer inout octetstring } @@ -120,6 +167,7 @@ module PortTranslation { out MyRec to octetstring with MyRec_to_oct() : integer with MyRec_to_int() : MyRec with MyRec_to_MyRec() : charstring with MyRec_to_char() : hexstring with MyRec_to_hex() out octetstring inout bitstring + out hexstring to bitstring with hex_to_bit() : charstring with hex_to_char() } @@ -409,6 +457,20 @@ module PortTranslation { t.stop; } + testcase tc_send_partially_translated() runs on MyComp system System { + map(self:p, system:p1); + var hexstring hs := '12345678ABCDEF'H; + p.send(hs); + // TODO: wait for port variables + } + + testcase tc_send_fragmented() runs on MyComp system System { + map(self:p, system:p1); + var hexstring hs := '12345678ABCDEF'H; + p.send(hs); + // TODO: wait for port variables + } + control { execute(tc_send()) @@ -418,6 +480,9 @@ module PortTranslation { execute(tc_receive2()); execute(tc_send_and_receive_without_mapping()); + + //execute(tc_send_partially_translated()); + //execute(tc_send_fragmented()); } } \ No newline at end of file diff --git a/regression_test/portTranslation/Setstate_neg.ttcn b/regression_test/portTranslation/Setstate_neg.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..5bc69d32a4fe225845a9e6007c0bfe7390e7c097 --- /dev/null +++ b/regression_test/portTranslation/Setstate_neg.ttcn @@ -0,0 +1,126 @@ +/****************************************************************************** + * 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: + * Szabo, Bence Janos + * + ******************************************************************************/ +module Setstate_neg { + + function int_to_char_bad(in integer i, out charstring j) { + if (i == -1) { + port.setstate(i); + } else { + port.setstate(1); // Not translated + } + } with { + extension "prototype(fast)"; + } + + function int_to_char_bad2(in integer i, out charstring j) { + if (i == 4) { + port.setstate(i); + } else { + port.setstate(1); // Not translated + } + } with { + extension "prototype(fast)"; + } + + function int_to_char_bad3(in integer i, out charstring j) { + if (i != 5) { + port.setstate(1); // Not translated + } + // otherwise the state will remain unset which will cause an error. + } with { + extension "prototype(fast)"; + } + + function int_to_char(in integer i, out charstring j) { + j := "abc"; + port.setstate(0); // translated + } with { + extension "prototype(fast)"; + } + + /* Types */ + + type port NP1 message { + out charstring + } with { + extension "provider" + } + + type port NPT2 message map to NP1 { + out integer to charstring with int_to_char_bad() : charstring with int_to_char_bad2() : charstring with int_to_char_bad3() : charstring with int_to_char() + } + + + type component MyComp { + port NPT2 p; + } + + type component System { + port NP1 p1 + } + + + testcase tc_setstate_neg_test() runs on MyComp system System { + map(self:p, system:p1); + @try { + p.send(-1); + setverdict(fail); + } @catch(e) { + if (match(e, "Dynamic test case error: The value of the first parameter in the setstate operation must be 0, 1, 2 or 3.")) { + setverdict(pass); + } else { + setverdict(fail); + } + } + + @try { + p.send(4); + setverdict(fail); + } @catch(e) { + if (match(e, "Dynamic test case error: The value of the first parameter in the setstate operation must be 0, 1, 2 or 3.")) { + setverdict(pass); + } else { + setverdict(fail); + } + } + + @try { + p.send(5); + setverdict(fail); + } @catch(e) { + if (match(e, "Dynamic test case error: The state of the port p remained unset after the mapping function @Setstate_neg.int_to_char_bad3 finished.")) { + setverdict(pass); + } else { + setverdict(fail); + } + } + + @try { + var charstring cs; + int_to_char(4, cs); + setverdict(fail); + } @catch(e) { + if (match(e, "Dynamic test case error: setstate operation was called without being in a translation procedure.")) { + setverdict(pass); + } else { + setverdict(fail); + } + } + + // Will be successful + p.send(6); + } + + control { + execute(tc_setstate_neg_test()); + } +} \ No newline at end of file diff --git a/regression_test/portTranslation/config.cfg b/regression_test/portTranslation/config.cfg index cb3e7ee1b8d66fbce3bf42b86b5fcd3cdc368919..c4e964a2b01d626b6235f99583c6e01a3ec14475 100644 --- a/regression_test/portTranslation/config.cfg +++ b/regression_test/portTranslation/config.cfg @@ -11,3 +11,4 @@ ############################################################################### [EXECUTE] PortTranslation.control +Setstate_neg.control