Commit 78a82971 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Implemented operation 'port.getref()' (bug 533006)



Change-Id: I9158d29e0e81ed2265a148081d8bcea6f3e82025
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent 39400ac7
...@@ -171,6 +171,9 @@ namespace Common { ...@@ -171,6 +171,9 @@ namespace Common {
case OPTYPE_TESTCASENAME: case OPTYPE_TESTCASENAME:
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
break; break;
case OPTYPE_GET_PORT_REF:
u.expr.type = p.u.expr.type; // the type is not owned, don't copy it
break;
case OPTYPE_COMP_RUNNING: // v1 [r2] b4 case OPTYPE_COMP_RUNNING: // v1 [r2] b4
case OPTYPE_COMP_ALIVE: case OPTYPE_COMP_ALIVE:
u.expr.r2 = p.u.expr.r2 != NULL ? p.u.expr.r2->clone() : NULL; u.expr.r2 = p.u.expr.r2 != NULL ? p.u.expr.r2->clone() : NULL;
...@@ -526,6 +529,7 @@ namespace Common { ...@@ -526,6 +529,7 @@ namespace Common {
case OPTYPE_GETVERDICT: case OPTYPE_GETVERDICT:
case OPTYPE_TESTCASENAME: case OPTYPE_TESTCASENAME:
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
case OPTYPE_GET_PORT_REF: // type (not owned)
break; break;
case OPTYPE_COMP_RUNNING: // v1 [r2] b4 case OPTYPE_COMP_RUNNING: // v1 [r2] b4
case OPTYPE_COMP_ALIVE: case OPTYPE_COMP_ALIVE:
...@@ -928,6 +932,9 @@ namespace Common { ...@@ -928,6 +932,9 @@ namespace Common {
case OPTYPE_TESTCASENAME: case OPTYPE_TESTCASENAME:
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
break; break;
case OPTYPE_GET_PORT_REF:
u.expr.type = NULL; // will be set during semantic analysis
break;
default: default:
FATAL_ERROR("Value::Value()"); FATAL_ERROR("Value::Value()");
} // switch } // switch
...@@ -1751,6 +1758,7 @@ namespace Common { ...@@ -1751,6 +1758,7 @@ namespace Common {
case OPTYPE_GETVERDICT: case OPTYPE_GETVERDICT:
case OPTYPE_TESTCASENAME: case OPTYPE_TESTCASENAME:
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
case OPTYPE_GET_PORT_REF:
break; break;
case OPTYPE_UNARYPLUS: // v1 case OPTYPE_UNARYPLUS: // v1
case OPTYPE_UNARYMINUS: case OPTYPE_UNARYMINUS:
...@@ -1998,6 +2006,7 @@ namespace Common { ...@@ -1998,6 +2006,7 @@ namespace Common {
case OPTYPE_GETVERDICT: case OPTYPE_GETVERDICT:
case OPTYPE_TESTCASENAME: case OPTYPE_TESTCASENAME:
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
case OPTYPE_GET_PORT_REF:
break; break;
case OPTYPE_COMP_RUNNING: // v1 [r2] b4 case OPTYPE_COMP_RUNNING: // v1 [r2] b4
case OPTYPE_COMP_ALIVE: case OPTYPE_COMP_ALIVE:
...@@ -2373,6 +2382,7 @@ namespace Common { ...@@ -2373,6 +2382,7 @@ namespace Common {
case OPTYPE_GETVERDICT: case OPTYPE_GETVERDICT:
case OPTYPE_TESTCASENAME: case OPTYPE_TESTCASENAME:
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
case OPTYPE_GET_PORT_REF:
break; break;
case OPTYPE_COMP_RUNNING: // v1 [r2] b4 case OPTYPE_COMP_RUNNING: // v1 [r2] b4
case OPTYPE_COMP_ALIVE: case OPTYPE_COMP_ALIVE:
...@@ -3345,6 +3355,8 @@ namespace Common { ...@@ -3345,6 +3355,8 @@ namespace Common {
return Type::T_BOOL; return Type::T_BOOL;
case OPTYPE_GETVERDICT: case OPTYPE_GETVERDICT:
return Type::T_VERDICT; return Type::T_VERDICT;
case OPTYPE_GET_PORT_REF:
return Type::T_PORT;
case OPTYPE_VALUEOF: { case OPTYPE_VALUEOF: {
Error_Context cntxt(this, "In the operand of operation `%s'", Error_Context cntxt(this, "In the operand of operation `%s'",
get_opname()); get_opname());
...@@ -3790,6 +3802,9 @@ namespace Common { ...@@ -3790,6 +3802,9 @@ namespace Common {
} else return 0; } else return 0;
case OPTYPE_COMP_CREATE: case OPTYPE_COMP_CREATE:
return chk_expr_operand_comptyperef_create(); return chk_expr_operand_comptyperef_create();
case OPTYPE_GET_PORT_REF:
chk_expr_operands(NULL, exp_val); // calculate the port type
return u.expr.type;
default: default:
break; break;
} }
...@@ -4079,6 +4094,8 @@ namespace Common { ...@@ -4079,6 +4094,8 @@ namespace Common {
return "ttcn2string()"; return "ttcn2string()";
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
return "@profiler.running"; return "@profiler.running";
case OPTYPE_GET_PORT_REF:
return "port.getref()";
default: default:
FATAL_ERROR("Value::get_opname()"); FATAL_ERROR("Value::get_opname()");
} // switch } // switch
...@@ -6876,6 +6893,26 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -6876,6 +6893,26 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_TESTCASENAME: case OPTYPE_TESTCASENAME:
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
break; break;
case OPTYPE_GET_PORT_REF:
if (u.expr.type == NULL) {
Ttcn::PortScope* port_scope = my_scope->get_scope_port();
if (port_scope == NULL) {
error("Operation `%s' can only be used in a function with a port clause.",
opname);
set_valuetype(V_ERROR);
break;
}
u.expr.type = port_scope->get_port_type();
if (u.expr.type == NULL) {
FATAL_ERROR("Value::chk_expr_operands");
}
if (my_governor != NULL && !u.expr.type->is_identical(my_governor)) {
error("Type mismatch: A value of type `%s' was expected instead of `%s'",
my_governor->get_typename().c_str(), u.expr.type->get_typename().c_str());
set_valuetype(V_ERROR);
}
}
break;
case OPTYPE_COMP_MTC: case OPTYPE_COMP_MTC:
case OPTYPE_COMP_SYSTEM: case OPTYPE_COMP_SYSTEM:
chk_expr_comptype_compat(); chk_expr_comptype_compat();
...@@ -7951,6 +7988,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -7951,6 +7988,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_TMR_RUNNING_ANY: case OPTYPE_TMR_RUNNING_ANY:
case OPTYPE_GETVERDICT: case OPTYPE_GETVERDICT:
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
case OPTYPE_GET_PORT_REF:
case OPTYPE_RNDWITHVAL: // v1 case OPTYPE_RNDWITHVAL: // v1
case OPTYPE_COMP_RUNNING: // v1 case OPTYPE_COMP_RUNNING: // v1
case OPTYPE_COMP_ALIVE: case OPTYPE_COMP_ALIVE:
...@@ -9275,6 +9313,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -9275,6 +9313,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_GETVERDICT: case OPTYPE_GETVERDICT:
case OPTYPE_TESTCASENAME: case OPTYPE_TESTCASENAME:
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
case OPTYPE_GET_PORT_REF:
case OPTYPE_RNDWITHVAL: // v1 case OPTYPE_RNDWITHVAL: // v1
case OPTYPE_MATCH: // v1 t2 case OPTYPE_MATCH: // v1 t2
case OPTYPE_UNDEF_RUNNING: // v1 case OPTYPE_UNDEF_RUNNING: // v1
...@@ -10949,6 +10988,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -10949,6 +10988,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_TMR_RUNNING_ANY: // - case OPTYPE_TMR_RUNNING_ANY: // -
case OPTYPE_GETVERDICT: // - case OPTYPE_GETVERDICT: // -
case OPTYPE_PROF_RUNNING: // - case OPTYPE_PROF_RUNNING: // -
case OPTYPE_GET_PORT_REF: // -
case OPTYPE_CHECKSTATE_ANY: case OPTYPE_CHECKSTATE_ANY:
case OPTYPE_CHECKSTATE_ALL: case OPTYPE_CHECKSTATE_ALL:
break; // nothing to do break; // nothing to do
...@@ -11825,6 +11865,8 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -11825,6 +11865,8 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
return ret_val; } return ret_val; }
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
return string("@profiler.running"); return string("@profiler.running");
case OPTYPE_GET_PORT_REF:
return string("port.getref()");
default: default:
return string("<unsupported optype>"); return string("<unsupported optype>");
} // switch u.expr.v_optype } // switch u.expr.v_optype
...@@ -13419,6 +13461,17 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -13419,6 +13461,17 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_PROF_RUNNING: case OPTYPE_PROF_RUNNING:
expr->expr = mputstr(expr->expr, "ttcn3_prof.is_running()"); expr->expr = mputstr(expr->expr, "ttcn3_prof.is_running()");
break; break;
case OPTYPE_GET_PORT_REF: {
string tmp_id = my_scope->get_scope_mod_gen()->get_temporary_id();
expr->preamble = mputprintf(expr->preamble,
"%s* %s = dynamic_cast<%s*>(TTCN_Runtime::get_translation_port());\n"
"if (%s == NULL) TTCN_error(\"Internal error: Conversion of port "
"reference to type `%s' failed.\");\n",
u.expr.type->get_genname_value(my_scope).c_str(), tmp_id.c_str(),
u.expr.type->get_genname_value(my_scope).c_str(), tmp_id.c_str(),
u.expr.type->get_typename().c_str());
expr->expr = mputprintf(expr->expr, "(*%s)", tmp_id.c_str());
break; }
default: default:
FATAL_ERROR("Value::generate_code_expr_expr()"); FATAL_ERROR("Value::generate_code_expr_expr()");
} }
...@@ -15099,6 +15152,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1, ...@@ -15099,6 +15152,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
case OPTYPE_TTCN2STRING: case OPTYPE_TTCN2STRING:
case OPTYPE_ENCVALUE_UNICHAR: case OPTYPE_ENCVALUE_UNICHAR:
case OPTYPE_DECVALUE_UNICHAR: case OPTYPE_DECVALUE_UNICHAR:
case OPTYPE_GET_PORT_REF:
return false; return false;
case OPTYPE_COMP_RUNNING: // v1 [r2] b4 case OPTYPE_COMP_RUNNING: // v1 [r2] b4
case OPTYPE_COMP_ALIVE: case OPTYPE_COMP_ALIVE:
......
...@@ -278,6 +278,8 @@ namespace Common { ...@@ -278,6 +278,8 @@ namespace Common {
OPTYPE_JSON2CBOR, // v1 OPTYPE_JSON2CBOR, // v1
OPTYPE_BSON2JSON, // v1 OPTYPE_BSON2JSON, // v1
OPTYPE_JSON2BSON, // v1 OPTYPE_JSON2BSON, // v1
OPTYPE_GET_PORT_REF, // -
NUMBER_OF_OPTYPES // must be last NUMBER_OF_OPTYPES // must be last
}; };
...@@ -343,6 +345,7 @@ namespace Common { ...@@ -343,6 +345,7 @@ namespace Common {
TemplateInstance *ti1; TemplateInstance *ti1;
Ttcn::Ref_base *r1; /**< timer or component */ Ttcn::Ref_base *r1; /**< timer or component */
LogArguments *logargs; /**< arguments of log2str() */ LogArguments *logargs; /**< arguments of log2str() */
Type* type;
}; };
union { union {
Value *v2; Value *v2;
...@@ -413,7 +416,7 @@ namespace Common { ...@@ -413,7 +416,7 @@ namespace Common {
/** Constructor used by V_EXPR "-": RND, TESTCASENAME, COMP_NULL, COMP_MTC, /** Constructor used by V_EXPR "-": RND, TESTCASENAME, COMP_NULL, COMP_MTC,
* COMP_SYSTEM, COMP_SELF, COMP_RUNNING_ANY, COMP_RUNNING_ALL, * COMP_SYSTEM, COMP_SELF, COMP_RUNNING_ANY, COMP_RUNNING_ALL,
* COMP_ALIVE_ALL, COMP_ALIVE_ANY, TMR_RUNNING_ANY, GETVERDICT, * COMP_ALIVE_ALL, COMP_ALIVE_ANY, TMR_RUNNING_ANY, GETVERDICT,
* PROF_RUNNING */ * PROF_RUNNING, OPTYPE_GET_PORT_REF */
Value(operationtype_t p_optype); Value(operationtype_t p_optype);
/** Constructor used by V_EXPR "v1" or [v1] */ /** Constructor used by V_EXPR "v1" or [v1] */
Value(operationtype_t p_optype, Value *p_v1); Value(operationtype_t p_optype, Value *p_v1);
......
...@@ -8382,11 +8382,10 @@ namespace Ttcn { ...@@ -8382,11 +8382,10 @@ namespace Ttcn {
if (!type) FATAL_ERROR("FormalPar::get_Type()"); if (!type) FATAL_ERROR("FormalPar::get_Type()");
return type; return type;
} }
void FormalPar::chk() void FormalPar::chk()
{ {
if (checked) return; if (checked) return;
checked = true;
TemplateInstance *default_value = defval.ti; TemplateInstance *default_value = defval.ti;
defval.ti = 0; defval.ti = 0;
if (type) { if (type) {
...@@ -8400,6 +8399,8 @@ namespace Ttcn { ...@@ -8400,6 +8399,8 @@ namespace Ttcn {
case A_PAR_VAL_INOUT: case A_PAR_VAL_INOUT:
asstype = A_PAR_PORT; asstype = A_PAR_PORT;
break; break;
case A_PAR_PORT:
break; // should only happen in recursive calls
default: default:
error("Port type `%s' cannot be used as %s", error("Port type `%s' cannot be used as %s",
t->get_fullname().c_str(), get_assname()); t->get_fullname().c_str(), get_assname());
...@@ -8428,7 +8429,9 @@ namespace Ttcn { ...@@ -8428,7 +8429,9 @@ namespace Ttcn {
} }
} }
} else if (asstype != A_PAR_TIMER) FATAL_ERROR("FormalPar::chk()"); } else if (asstype != A_PAR_TIMER) FATAL_ERROR("FormalPar::chk()");
checked = true;
if (default_value) { if (default_value) {
Error_Context cntxt(default_value, "In default value"); Error_Context cntxt(default_value, "In default value");
defval.ap = chk_actual_par(default_value, Type::EXPECTED_STATIC_VALUE); defval.ap = chk_actual_par(default_value, Type::EXPECTED_STATIC_VALUE);
...@@ -9016,6 +9019,18 @@ namespace Ttcn { ...@@ -9016,6 +9019,18 @@ namespace Ttcn {
} }
return new ActualPar(ref); return new ActualPar(ref);
} else { } else {
if (ap_template->get_templatetype() == Template::SPECIFIC_VALUE) {
Value* val = ap_template->get_specific_value();
if (val->get_valuetype() == Common::Value::V_EXPR &&
val->get_optype() == Common::Value::OPTYPE_GET_PORT_REF) {
Value *v = ap_template->get_Value(); // steal the value
v->set_my_governor(type);
type->chk_this_value_ref(v);
type->chk_this_value(v, 0, exp_val, INCOMPLETE_NOT_ALLOWED,
OMIT_NOT_ALLOWED, SUB_CHK);
return new ActualPar(v);
}
}
actual_par->error("Reference to a port or port parameter was expected " actual_par->error("Reference to a port or port parameter was expected "
"for a port parameter"); "for a port parameter");
return new ActualPar(); return new ActualPar();
......
...@@ -1038,7 +1038,7 @@ namespace Ttcn { ...@@ -1038,7 +1038,7 @@ namespace Ttcn {
: Node(), Location(), my_type(0), operation_mode(p_operation_mode), : 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_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), in_all(p_in_all), out_all(p_out_all), inout_all(p_inout_all),
checked(false), legacy(true), checked(false), attributes_checked(false), legacy(true),
in_msgs(0), out_msgs(0), in_sigs(0), out_sigs(0), in_msgs(0), out_msgs(0), in_sigs(0), out_sigs(0),
testport_type(TP_REGULAR), port_type(PT_REGULAR), testport_type(TP_REGULAR), port_type(PT_REGULAR),
provider_refs(), provider_types(), mapper_types(), provider_refs(), provider_types(), mapper_types(),
...@@ -1784,6 +1784,10 @@ namespace Ttcn { ...@@ -1784,6 +1784,10 @@ namespace Ttcn {
{ {
if (!w_attrib_path || !checked || !my_type) if (!w_attrib_path || !checked || !my_type)
FATAL_ERROR("PortTypeBody::chk_attributes()"); FATAL_ERROR("PortTypeBody::chk_attributes()");
if (attributes_checked) {
return;
}
attributes_checked = true;
Ttcn::ExtensionAttributes * extarts = parse_extattributes(w_attrib_path); Ttcn::ExtensionAttributes * extarts = parse_extattributes(w_attrib_path);
if (extarts != 0) { // NULL means parsing error if (extarts != 0) { // NULL means parsing error
......
...@@ -390,6 +390,7 @@ private: ...@@ -390,6 +390,7 @@ private:
Types *in_list, *out_list, *inout_list; Types *in_list, *out_list, *inout_list;
bool in_all, out_all, inout_all; // whether "(in|out|inout) all" was used bool in_all, out_all, inout_all; // whether "(in|out|inout) all" was used
bool checked; bool checked;
bool attributes_checked;
bool legacy; // Old extension syntax or new standard syntax bool legacy; // Old extension syntax or new standard syntax
/* Types and signatures that can be sent and received. /* Types and signatures that can be sent and received.
* These are initially empty; filled by PortTypeBody::chk_list based on * These are initially empty; filled by PortTypeBody::chk_list based on
......
...@@ -535,6 +535,8 @@ xor4b RETURN(Xor4bKeyword); ...@@ -535,6 +535,8 @@ xor4b RETURN(Xor4bKeyword);
"@profiler" RETURN(TitanSpecificProfilerKeyword); "@profiler" RETURN(TitanSpecificProfilerKeyword);
"@update" RETURN(TitanSpecificUpdateKeyword); "@update" RETURN(TitanSpecificUpdateKeyword);
"getref" RETURN_DOT(GetRefKeyword);
/* Predefined function identifiers */ /* Predefined function identifiers */
bit2hex RETURN(bit2hexKeyword); bit2hex RETURN(bit2hexKeyword);
......
...@@ -684,6 +684,7 @@ static const string anyname("anytype"); ...@@ -684,6 +684,7 @@ static const string anyname("anytype");
%token FromKeyword %token FromKeyword
%token FunctionKeyword %token FunctionKeyword
%token GetCallOpKeyword %token GetCallOpKeyword
%token GetRefKeyword
%token GetReplyOpKeyword %token GetReplyOpKeyword
%token GetVerdictKeyword %token GetVerdictKeyword
%token GotoKeyword %token GotoKeyword
...@@ -819,6 +820,7 @@ static const string anyname("anytype"); ...@@ -819,6 +820,7 @@ static const string anyname("anytype");
%token DotCreateKeyword %token DotCreateKeyword
%token DotDoneKeyword %token DotDoneKeyword
%token DotGetCallOpKeyword %token DotGetCallOpKeyword
%token DotGetRefKeyword
%token DotGetReplyOpKeyword %token DotGetReplyOpKeyword
%token DotHaltKeyword %token DotHaltKeyword
%token DotKillKeyword %token DotKillKeyword
...@@ -1899,16 +1901,16 @@ optDecodedModifier ...@@ -1899,16 +1901,16 @@ optDecodedModifier
%left '*' '/' ModKeyword RemKeyword %left '*' '/' ModKeyword RemKeyword
%left UnarySign %left UnarySign
%expect 67 %expect 69
%start GrammarRoot %start GrammarRoot
/* /*
XXX Source of conflicts (66 S/R): XXX Source of conflicts (69 S/R):
1.) 9 conflicts in one state 1.) 10 conflicts in one state
The Expression after 'return' keyword is optional in ReturnStatement. The Expression after 'return' keyword is optional in ReturnStatement.
For 9 tokens the parser cannot decide whether the token is a part of For 10 tokens the parser cannot decide whether the token is a part of
the return expression (shift) or it is the beginning of the next statement the return expression (shift) or it is the beginning of the next statement
(reduce). (reduce).
...@@ -1947,7 +1949,7 @@ non-standard language extension. ...@@ -1947,7 +1949,7 @@ non-standard language extension.
7.) 27 conflicts in one state 7.) 27 conflicts in one state
In the DecodedContentMatch rule a SingleExpression encased in round brackets is In the DecodedContentMatch rule a SingleExpression encased in round brackets is
followed by an in-line template. For 26 tokens (after the ')' ) the parser cannot followed by an in-line template. For 27 tokens (after the ')' ) the parser cannot
decide whether the token is the beginning of the in-line template (shift) or decide whether the token is the beginning of the in-line template (shift) or
the brackets are only part of the SingleExpression itself and the conflicting the brackets are only part of the SingleExpression itself and the conflicting
token is the next segment in the expression (reduce). token is the next segment in the expression (reduce).
...@@ -9437,6 +9439,11 @@ OpCall: // 611 ...@@ -9437,6 +9439,11 @@ OpCall: // 611
$$ = new Value(Value::OPTYPE_CHECKSTATE_ALL, r, $5); $$ = new Value(Value::OPTYPE_CHECKSTATE_ALL, r, $5);
$$->set_location(infile, @$); $$->set_location(infile, @$);
} }
| PortKeyword DotGetRefKeyword '(' ')'
{
$$ = new Value(Value::OPTYPE_GET_PORT_REF);
$$->set_location(infile, @$);
}
; ;
PredefinedOps: PredefinedOps:
......
...@@ -141,6 +141,13 @@ void TTCN_Runtime::set_port_state(const INTEGER& state, const CHARSTRING& info, ...@@ -141,6 +141,13 @@ void TTCN_Runtime::set_port_state(const INTEGER& state, const CHARSTRING& info,
} }
} }
PORT* TTCN_Runtime::get_translation_port() {
if (p == NULL) {
TTCN_error("Operation 'port.getref' was called while not in a port translation procedure.");
}
return p;
}
void TTCN_Runtime::set_translation_mode(boolean enabled, PORT* port) { void TTCN_Runtime::set_translation_mode(boolean enabled, PORT* port) {
if (enabled) { if (enabled) {
translation_count++; translation_count++;
......
...@@ -135,6 +135,7 @@ public: ...@@ -135,6 +135,7 @@ public:
static void set_port_state(const INTEGER& state, const CHARSTRING& info, boolean by_system); static void set_port_state(const INTEGER& state, const CHARSTRING& info, boolean by_system);
static void set_translation_mode(boolean enabled, PORT* port); static void set_translation_mode(boolean enabled, PORT* port);
static PORT* get_translation_port();
private: private:
inline static boolean in_controlpart() inline static boolean in_controlpart()
......
...@@ -208,8 +208,19 @@ module PortTranslation { ...@@ -208,8 +208,19 @@ module PortTranslation {
extension "prototype(fast)"; extension "prototype(fast)";
} }
function char_to_hex3(in charstring i, out hexstring j) { function f_port_ref_test(PT3 p1, inout PT3 p2)
{
if (log2str(p1) != "port p3") {
setverdict(fail, "First port argument is invalid. Expected port p3, got: ", p1);
}
if (log2str(p2) != "port p3") {
setverdict(fail, "First port argument is invalid. Expected port p3, got: ", p1);
}
}
function char_to_hex3(in charstring i, out hexstring j) port PT3 {
j := oct2hex(char2oct(i)); j := oct2hex(char2oct(i));
f_port_ref_test(port.getref(), port.getref());
port.setstate(0); // translated port.setstate(0); // translated
} with { } with {
extension "prototype(fast)"; extension "prototype(fast)";
...@@ -788,7 +799,8 @@ module PortTranslation { ...@@ -788,7 +799,8 @@ module PortTranslation {
} }
// This tests the 'discard' option in the 'setstate' operation when receiving // This tests the 'discard' option in the 'setstate' operation when receiving
testcase tc_receive_discarded() runs on MyComp system System { // It also tests the operation 'port.getref()'
testcase tc_receive_discarded_plus_port_ref() runs on MyComp system System {
map(self:p3, system:p4); map(self:p3, system:p4);
p3.send(123); p3.send(123);
...@@ -810,6 +822,7 @@ module PortTranslation { ...@@ -810,6 +822,7 @@ module PortTranslation {
// an integer (-10) and a charstring ("abc") are received on the provider port, // an integer (-10) and a charstring ("abc") are received on the provider port,
// the translation functions discard the integer and convert the charstring into a hexstring, // the translation functions discard the integer and convert the charstring into a hexstring,
// so only the hexstring is received on the main port // so only the hexstring is received on the main port
// (the charstring-to-hexstring translation function also contains tests for operation 'port.getref()')
alt { alt {
[] p3.receive(hexstring: '616263'H) { setverdict(pass); } [] p3.receive(hexstring: '616263'H) { setverdict(pass); }
[] p3.receive(hexstring: ?) -> value bad { setverdict(fail, "Test #2 failed. Received invalid hexstring: ", bad); } [] p3.receive(hexstring: ?) -> value bad { setverdict(fail, "Test #2 failed. Received invalid hexstring: ", bad); }
...@@ -836,7 +849,7 @@ module PortTranslation { ...@@ -836,7 +849,7 @@ module PortTranslation {
execute(tc_receive_partially_translated()); execute(tc_receive_partially_translated());
execute(tc_receive_fragmented()); execute(tc_receive_fragmented());
execute(tc_receive_discarded()); execute(tc_receive_discarded_plus_port_ref());
} }
} }
...@@ -253,7 +253,7 @@ static void printUsage(const char * argv0) { ...@@ -253,7 +253,7 @@ static void printUsage(const char * argv0) {
" -f|J file: the names of XSD files are taken from file instead of the command line\n" " -f|J file: the names of XSD files are taken from file instead of the command line\n"
" -g: generate TTCN-3 code disallowing element substitution\n" " -g: generate TTCN-3 code disallowing element substitution\n"
" -h: generate TTCN-3 code allowing type substitution\n" " -h: generate TTCN-3 code allowing type substitution\n"
" -m: generate only the UsefulTtcn3Types and XSD predefined modules" " -m: generate only the UsefulTtcn3Types and XSD predefined modules\n"
" -p: do not generate the UsefulTtcn3Types and XSD predefined modules\n" " -p: do not generate the UsefulTtcn3Types and XSD predefined modules\n"
" -q: quiet mode - disable the issue of status messages\n" " -q: quiet mode - disable the issue of status messages\n"
" -s: parse and validate only - no TTCN-3 module generation\n" " -s: parse and validate only - no TTCN-3 module generation\n"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment