Commit 992ee5a5 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Implemented remote mapping in translation mode (bug 534266)



Change-Id: I8c4e454d8ba843b983388ec8beaa134c5c9eb8cc
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent 2801e85e
......@@ -1064,6 +1064,29 @@ namespace Common {
output->functions.init_comp = NULL;
has_init_comp = true;
} else has_init_comp = false;
// init system port function
bool has_init_system_port;
if (output->functions.init_system_port != NULL) {
output->source.static_function_prototypes =
mputprintf(output->source.static_function_prototypes,
"%sboolean init_system_port(const char* component_type, const char* port_name);\n",
split_to_slices ? "extern " : "static ");
output->source.static_function_bodies =
mputprintf(output->source.static_function_bodies,
"%sboolean init_system_port(const char* component_type, const char* port_name)\n"
"{\n", split_to_slices ? "" : "static ");
output->source.static_function_bodies =
mputstr(output->source.static_function_bodies, output->functions.init_system_port);
output->source.static_function_bodies =
mputstr(output->source.static_function_bodies, "return FALSE;\n"
"}\n\n");
Free(output->functions.init_system_port);
output->functions.init_system_port = NULL;
has_init_system_port = true;
}
else {
has_init_system_port = false;
}
// start function
bool has_start;
if (output->functions.start) {
......@@ -1187,15 +1210,16 @@ namespace Common {
}
string extra_str = extra ? ( string('"') + extra + string('"') ) : string("NULL");
output->source.global_vars = mputprintf(output->source.global_vars,
", %uU, %uU, %uU, %uU, %s, %luLU, %s, %s, %s, %s, %s, %s, %s, %s",
", %uU, %uU, %uU, %uU, %s, %luLU, %s, %s, %s, %s, %s, %s, %s, %s, %s",
suffix, release, patch, build, extra_str.c_str(),
(unsigned long)num_xml_namespaces,
((num_xml_namespaces || (control_ns && control_ns_prefix)) ? "xml_namespaces" : "0"),
has_post_init ? "post_init_module" : "NULL",
has_set_param ? "set_module_param" : "NULL",
has_get_param ? "get_module_param" : "NULL",
has_get_param ? "get_module_param" : "NULL",
has_log_param ? "log_module_param" : "NULL",
has_init_comp ? "init_comp_type" : "NULL",
has_init_system_port ? "init_system_port" : "NULL",
has_start ? "start_ptc_function" : "NULL",
has_control ? "module_control_part" : "NULL");
} else {
......@@ -1210,6 +1234,8 @@ namespace Common {
FATAL_ERROR("Module::generate_functions(): log_param function in ASN.1 module");
if (has_init_comp)
FATAL_ERROR("Module::generate_functions(): init_comp function in ASN.1 module");
if (has_init_system_port)
FATAL_ERROR("Module::generate_functions(): init_system_port function in ASN.1 module");
if (has_start)
FATAL_ERROR("Module::generate_functions(): startable function in ASN.1 module");
if (has_control)
......
......@@ -54,6 +54,7 @@ namespace Common {
output->functions.get_param = NULL;
output->functions.log_param = NULL;
output->functions.init_comp = NULL;
output->functions.init_system_port = NULL;
output->functions.start = NULL;
output->functions.control = NULL;
output->intervals.pre_things_size = 0;
......@@ -136,6 +137,8 @@ namespace Common {
mputstr(dest->functions.log_param, src->functions.log_param);
dest->functions.init_comp =
mputstr(dest->functions.init_comp, src->functions.init_comp);
dest->functions.init_system_port =
mputstr(dest->functions.init_system_port, src->functions.init_system_port);
dest->functions.start =
mputstr(dest->functions.start, src->functions.start);
dest->functions.control =
......@@ -167,6 +170,7 @@ namespace Common {
Free(output->functions.get_param);
Free(output->functions.log_param);
Free(output->functions.init_comp);
Free(output->functions.init_system_port);
Free(output->functions.start);
Free(output->functions.control);
Free(output->intervals.methods);
......
......@@ -373,6 +373,7 @@ void CodeGenHelper::finalize_generation(Type* type) {
transfer_value(dst.functions.get_param, src.functions.get_param);
transfer_value(dst.functions.log_param, src.functions.log_param);
transfer_value(dst.functions.init_comp, src.functions.init_comp);
transfer_value(dst.functions.init_system_port, src.functions.init_system_port);
transfer_value(dst.functions.start, src.functions.start);
transfer_value(dst.functions.control, src.functions.control);
}
......
......@@ -546,6 +546,37 @@ void ComponentTypeBody::generate_code(output_struct* target)
target->functions.init_comp = mputstr(target->functions.init_comp,
"return TRUE;\n"
"} else ");
// system port initializer function
bool first_port_found = false;
nof_defs = all_defs_m.size();
for (size_t i = 0; i < nof_defs; i++) {
// go through all port definitions, including inherited ones
Ttcn::Definition* def = all_defs_m.get_nth_elem(i);
if (def->get_asstype() == Common::Assignment::A_PORT) {
if (!first_port_found) {
// only add a segment for this component if it has at least one port
first_port_found = true;
target->functions.init_system_port = mputprintf(
target->functions.init_system_port,
"%sif (!strcmp(component_type, \"%s\")) {\n",
target->functions.init_system_port == NULL ? "" : "else ",
comp_id->get_dispname().c_str());
}
target->functions.init_system_port = mputprintf(
target->functions.init_system_port,
"if (!strcmp(port_name, \"%s\")) {\n"
"%s.safe_start();\n"
"return TRUE;\n"
"}\n",
def->get_id().get_dispname().c_str(),
def->get_genname_from_scope(my_type->get_my_scope()).c_str());
}
}
if (first_port_found) {
target->functions.init_system_port = mputstr(
target->functions.init_system_port, "}\n");
}
}
char *ComponentTypeBody::generate_code_comptype_name(char *str)
......
......@@ -1414,7 +1414,6 @@ namespace Ttcn {
config_op.compref2=p_compref2;
config_op.portref2=p_portref2;
config_op.translate=false;
config_op.first_is_system = false;
break;
default:
FATAL_ERROR("Statement::Statement()");
......@@ -4959,9 +4958,6 @@ error:
warning("Port type `%s' cannot send or receive from system port type `%s'.",
pt2->get_typename().c_str(), pt1->get_typename().c_str());
}
if (config_op.translate) {
config_op.first_is_system = true;
}
} else {
// we have no idea which one is the system port
bool first_is_mapped_to_second = !ptb1->is_legacy() && ptb1->is_translate(ptb2);
......@@ -4971,9 +4967,6 @@ error:
error("The mapping between port types `%s' and `%s' is not consistent",
pt1->get_typename().c_str(), pt2->get_typename().c_str());
}
if (config_op.translate) {
config_op.first_is_system = second_is_mapped_to_first;
}
}
if (!config_op.translate) {
if (ptb1->is_internal()) {
......@@ -7624,10 +7617,8 @@ error:
{
expression_struct expr;
Code::init_expr(&expr);
bool warning = false;
if (config_op.translate == true) {
if (!config_op.compref1->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)) {
warning = true;
if (strcmp(opname, "map") == 0) {
config_op.compref1->warning(
"Cannot determine the type of the component in the first parameter."
......@@ -7635,24 +7626,12 @@ error:
}
}
if (!config_op.compref2->get_expr_governor(Type::EXPECTED_DYNAMIC_VALUE)) {
warning = true;
if (strcmp(opname, "map") == 0) {
config_op.compref2->warning(
"Cannot determine the type of the component in the second parameter."
"The port translation will not work.");
}
}
if (warning == false) {
Reference* portref = config_op.first_is_system ?
config_op.portref1 : config_op.portref2;
expr.expr = mputstr(expr.expr, "if (!(");
portref->generate_code_portref(&expr, my_sb);
expr.expr = mputstr(expr.expr, ".port_is_started())) {\n");
portref->generate_code_portref(&expr, my_sb);
expr.expr = mputstr(expr.expr, ".activate_port(TRUE);\n");
portref->generate_code_portref(&expr, my_sb);
expr.expr = mputstr(expr.expr, ".start();\n}\n");
}
}
expr.expr = mputprintf(expr.expr, "TTCN_Runtime::%s_port(", opname);
config_op.compref1->generate_code_expr(&expr);
......@@ -7680,32 +7659,10 @@ error:
// a simple string shall be formed from the port name and array indices
generate_code_portref(&expr, config_op.portref2);
}
if (config_op.translate == true && warning == false) {
expr.expr = mputstr(expr.expr, ", TRUE");
}
expr.expr = mputstr(expr.expr, ")");
if (config_op.translate == true) {
string funcname;
if (strcmp(opname, "map") == 0) {
funcname = "add_port";
} else if (strcmp(opname, "unmap") == 0) {
funcname = "remove_port";
} else {
//connect, disconnect are not supported
}
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());
config_op.portref2->generate_code_portref(&expr, my_sb);
expr.expr = mputstr(expr.expr, "));\n");
config_op.portref2->generate_code_portref(&expr, my_sb);
expr.expr = mputprintf(expr.expr, ".%s(&(", funcname.c_str());
config_op.portref1->generate_code_portref(&expr, my_sb);
expr.expr = mputstr(expr.expr, "))");
}
expr.expr = mputstr(expr.expr, ", TRUE");
}
expr.expr = mputstr(expr.expr, ")");
return Code::merge_free_expr(str, &expr);
}
......
......@@ -348,7 +348,6 @@ namespace Ttcn {
Value *compref2;
Reference *portref2;
bool translate; // true if a map statement enables translation mode
bool first_is_system; // true if the first operand is the system component (only used in translation mode)
} config_op; ///< used by S_CONNECT, S_MAP, S_DISCONNECT, S_UNMAP
struct {
......
......@@ -63,6 +63,7 @@ extern "C" {
char *get_param; /**< Code for get_module_param() */
char *log_param; /**< Code for log_module_param() */
char *init_comp; /**< Code for init_comp_type() */
char* init_system_port; /**< Code for init_system_port() */
char *start; /**< Code for start_ptc_function() */
char *control; /**< Code for module_control_part() */
} functions;
......
......@@ -2136,24 +2136,35 @@ void defPortClass(const port_def* pdef, output_struct* output)
if (pdef->port_type == USER && !pdef->legacy) {
// add_port and remove_port is called after the map and unmap statements.
def = mputstr(def, "void add_port(PORT* p);\n");
src = mputprintf(src, "void %s::add_port(PORT* p)\n{\n", class_name);
for (i = 0; i < pdef->provider_msg_outlist.nElements; i++) {
def = mputprintf(def, "void add_port(%s* p);\n", pdef->provider_msg_outlist.elements[i].name);
src = mputprintf(src,
"void %s::add_port(%s*p) {\n"
"%s* x_%i = dynamic_cast<%s*>(p);\n"
"if (x_%i != NULL) {\n"
"n_%i++;\n"
"p_%i = static_cast<%s**>(Realloc(p_%i, n_%i * sizeof(%s*)));\n"
"p_%i[n_%i-1] = p;\n"
"}\n\n",
class_name, pdef->provider_msg_outlist.elements[i].name, (int)i,
"p_%i[n_%i-1] = x_%i;\n"
"return;\n"
"}\n",
pdef->provider_msg_outlist.elements[i].name, (int)i,
pdef->provider_msg_outlist.elements[i].name, (int)i, (int)i,
(int)i, pdef->provider_msg_outlist.elements[i].name, (int)i, (int)i,
pdef->provider_msg_outlist.elements[i].name, (int)i, (int)i);
pdef->provider_msg_outlist.elements[i].name, (int)i, (int)i, (int)i);
}
src = mputstr(src,
"TTCN_error(\"Internal error: Adding invalid port type.\");\n"
"}\n\n");
def = mputstr(def, "void remove_port(PORT* p);\n");
src = mputprintf(src, "void %s::remove_port(PORT* p)\n{\n", class_name);
def = mputprintf(def, "void remove_port(%s* p);\n", pdef->provider_msg_outlist.elements[i].name);
for (i = 0; i < pdef->provider_msg_outlist.nElements; i++) {
src = mputprintf(src,
"void %s::remove_port(%s* p) {\n"
"%s* x_%i = dynamic_cast<%s*>(p);\n"
"if (x_%i != NULL) {\n"
"for (size_t i = 0; i < n_%i; i++) {\n"
"if (p_%i[i] == p) {\n"
"p_%i[i]->remove_port(static_cast<%s*>(this));\n"
"if (p_%i[i] == x_%i) {\n"
"p_%i[i] = NULL;\n"
"}\n"
"}\n"
......@@ -2169,12 +2180,19 @@ void defPortClass(const port_def* pdef, output_struct* output)
"Free(p_%i);\n"
"p_%i = port_list;\n"
"n_%i = size;\n"
"}\n\n", class_name, pdef->provider_msg_outlist.elements[i].name, (int)i, (int)i,
(int)i, pdef->name, (int)i, pdef->provider_msg_outlist.elements[i].name, (int)i, (int)i,
"return;\n"
"}\n",
pdef->provider_msg_outlist.elements[i].name, (int)i,
pdef->provider_msg_outlist.elements[i].name, (int)i, (int)i, (int)i,
(int)i, (int)i, pdef->provider_msg_outlist.elements[i].name, (int)i, (int)i,
pdef->provider_msg_outlist.elements[i].name, pdef->provider_msg_outlist.elements[i].name,
(int)i, (int)i, (int)i, (int)i);
}
src = mputstr(src,
"TTCN_error(\"Internal error: Removing invalid port type.\");\n"
"}\n\n");
// 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);
......@@ -2211,22 +2229,35 @@ void defPortClass(const port_def* pdef, output_struct* output)
if (pdef->n_mapper_name > 0) {
def = mputstr(def, "public:\n");
// add_port and remove_port is called after the map and unmap statements.
def = mputstr(def, "void add_port(PORT* p);\n");
src = mputprintf(src, "void %s::add_port(PORT* p)\n{\n", class_name);
for (i = 0; i < pdef->n_mapper_name; i++) {
def = mputprintf(def, "void add_port(%s* p);\n", pdef->mapper_name[i]);
src = mputprintf(src,
"void %s::add_port(%s*p) {\n"
"%s* x_%i = dynamic_cast<%s*>(p);\n"
"if (x_%i != NULL) {\n"
"n_%i++;\n"
"p_%i = static_cast<%s**>(Realloc(p_%i, n_%i * sizeof(%s*)));\n"
"p_%i[n_%i-1] = p;\n"
"}\n\n", class_name, pdef->mapper_name[i], (int)i, (int)i,
pdef->mapper_name[i], (int)i, (int)i, pdef->mapper_name[i],
(int)i, (int)i);
"p_%i[n_%i-1] = x_%i;\n"
"return;\n"
"}\n",
pdef->mapper_name[i], (int)i,
pdef->mapper_name[i], (int)i, (int)i,
(int)i, pdef->mapper_name[i], (int)i, (int)i,
pdef->mapper_name[i], (int)i, (int)i, (int)i);
}
src = mputstr(src,
"TTCN_error(\"Internal error: Adding invalid port type.\");\n"
"}\n\n");
def = mputstr(def, "void remove_port(PORT* p);\n");
src = mputprintf(src, "void %s::remove_port(PORT* p)\n{\n", class_name);
def = mputprintf(def, "void remove_port(%s*);\n", pdef->mapper_name[i]);
for (i = 0; i < pdef->n_mapper_name; i++) {
src = mputprintf(src,
"void %s::remove_port(%s* p) {\n"
"%s* x_%i = dynamic_cast<%s*>(p);\n"
"if (x_%i != NULL) {\n"
"for (size_t i = 0; i < n_%i; i++) {\n"
"if (p_%i[i] == p) {\n"
"if (p_%i[i] == x_%i) {\n"
"p_%i[i] = NULL;\n"
"}\n"
"}\n"
......@@ -2242,11 +2273,18 @@ void defPortClass(const port_def* pdef, output_struct* output)
"Free(p_%i);\n"
"p_%i = port_list;\n"
"n_%i = size;\n"
"}\n\n", class_name, pdef->mapper_name[i], (int)i,
(int)i, (int)i, pdef->mapper_name[i], (int)i, (int)i,
"return;\n"
"}\n",
pdef->mapper_name[i], (int)i, pdef->mapper_name[i], (int)i,
(int)i, (int)i, (int)i, (int)i, pdef->mapper_name[i], (int)i, (int)i,
pdef->mapper_name[i], pdef->mapper_name[i],
(int)i, (int)i, (int)i, (int)i);
}
src = mputstr(src,
"TTCN_error(\"Internal error: Removing invalid port type.\");\n"
"}\n\n");
def = mputstr(def, "private:\n");
// Resets all port type variables to NULL
def = mputstr(def, "void reset_port_variables();\n");
......
......@@ -204,6 +204,14 @@ public:
array_elements[v_index].activate_port();
}
}
// needed by the init_system_port function
void safe_start()
{
for (unsigned int v_index = 0; v_index < array_size; v_index++) {
array_elements[v_index].safe_start();
}
}
void log() const
{
......
......@@ -1357,15 +1357,20 @@ void TTCN_Communication::process_create_ptc()
"component reference %d.", component_reference);
return;
}
qualified_name component_type;
qualified_name component_type, system_type;
incoming_buf.pull_qualified_name(component_type);
incoming_buf.pull_qualified_name(system_type);
if (component_type.module_name == NULL ||
component_type.definition_name == NULL) {
component_type.definition_name == NULL ||
system_type.module_name == NULL ||
system_type.definition_name == NULL) {
incoming_buf.cut_message();
delete [] component_type.module_name;
delete [] component_type.definition_name;
delete [] system_type.module_name;
delete [] system_type.definition_name;
send_error("Message CREATE_PTC with component reference %d contains "
"an invalid component type.", component_reference);
"an invalid component type or system type.", component_reference);
return;
}
char *component_name = incoming_buf.pull_string();
......@@ -1377,12 +1382,15 @@ void TTCN_Communication::process_create_ptc()
try {
TTCN_Runtime::process_create_ptc(component_reference,
component_type.module_name, component_type.definition_name,
system_type.module_name, system_type.definition_name,
component_name, is_alive, current_testcase.module_name,
current_testcase.definition_name);
} catch (...) {
// to prevent from memory leaks
delete [] component_type.module_name;
delete [] component_type.definition_name;
delete [] system_type.module_name;
delete [] system_type.definition_name;
delete [] component_name;
delete [] current_testcase.module_name;
delete [] current_testcase.definition_name;
......@@ -1391,6 +1399,8 @@ void TTCN_Communication::process_create_ptc()
delete [] component_type.module_name;
delete [] component_type.definition_name;
delete [] system_type.module_name;
delete [] system_type.definition_name;
delete [] component_name;
delete [] current_testcase.module_name;
delete [] current_testcase.definition_name;
......@@ -1759,6 +1769,13 @@ void TTCN_Communication::process_map()
if (translation == TRUE) {
PORT::map_port(local_port, system_port, TRUE);
}
if (!TTCN_Runtime::is_single()) {
if (translation == FALSE) {
send_mapped(local_port, system_port, translation);
} else {
send_mapped(system_port, local_port, translation);
}
}
} catch (...) {
delete [] local_port;
delete [] system_port;
......@@ -1798,6 +1815,13 @@ void TTCN_Communication::process_unmap()
if (translation == TRUE) {
PORT::unmap_port(local_port, system_port, TRUE);
}
if (!TTCN_Runtime::is_single()) {
if (translation == FALSE) {
send_unmapped(local_port, system_port, translation);
} else {
send_unmapped(system_port, local_port, translation);
}
}
} catch (...) {
delete [] local_port;
delete [] system_port;
......
......@@ -155,6 +155,24 @@ void Module_List::initialize_component(const char *module_name,
"module %s.", component_type, module_name);
}
void Module_List::initialize_system_port(const char* module_name,
const char* component_type, const char* port_name)
{
TTCN_Module* system_module = Module_List::lookup_module(module_name);
if (system_module == NULL) {
TTCN_error("Internal error: Module %s does not exist.", module_name);
}
if (system_module->initialize_system_port_func == NULL) {
TTCN_error("Internal error: Module %s does not have a system port "
"initializer function.", module_name);
}
if (!system_module->initialize_system_port_func(component_type, port_name)) {
TTCN_error("Internal error: Cannot find port %s in component type %s, or "
"component type %s in module %s.", port_name, component_type,
component_type, module_name);
}
}
void Module_List::set_param(Module_Param& param)
{
#ifndef TITAN_RUNTIME_2
......@@ -786,6 +804,7 @@ TTCN_Module::TTCN_Module(const char *par_module_name,
get_param_func_t par_get_param_func,
log_param_func_t par_log_param_func,
initialize_component_func_t par_initialize_component_func,
initialize_system_port_func_t par_initialize_system_port_func,
start_func_t par_start_func,
control_func_t par_control_func)
: list_prev(NULL), list_next(NULL)
......@@ -810,6 +829,7 @@ TTCN_Module::TTCN_Module(const char *par_module_name,
, get_param_func(par_get_param_func)
, log_param_func(par_log_param_func)
, initialize_component_func(par_initialize_component_func)
, initialize_system_port_func(par_initialize_system_port_func)
, start_func(par_start_func)
, control_func(par_control_func)
, function_head(NULL)
......@@ -850,6 +870,7 @@ TTCN_Module::TTCN_Module(const char *par_module_name,
, get_param_func(NULL)
, log_param_func(NULL)
, initialize_component_func(NULL)
, initialize_system_port_func(NULL)
, start_func(NULL)
, control_func(NULL)
, function_head(NULL)
......@@ -888,6 +909,7 @@ TTCN_Module::TTCN_Module(const char *par_module_name,
, set_param_func(NULL)
, log_param_func(NULL)
, initialize_component_func(NULL)
, initialize_system_port_func(NULL)
, start_func(NULL)
, control_func(NULL)
, function_head(NULL)
......
......@@ -56,6 +56,8 @@ public:
static void initialize_component(const char *module_name,
const char *component_type, boolean init_base_comps);
static void initialize_system_port(const char* module_name,
const char* component_type, const char* port_name);
static void set_param(Module_Param& param);
#ifdef TITAN_RUNTIME_2
......@@ -122,6 +124,8 @@ public:
typedef void (*log_param_func_t)();
typedef boolean (*initialize_component_func_t)(const char *component_type,
boolean init_base_comps);
typedef boolean (*initialize_system_port_func_t)(const char* component_type,
const char* port_name);
typedef boolean (*start_func_t)(const char *function_name,
Text_Buf& function_arguments);
typedef void (*control_func_t)();
......@@ -152,6 +156,7 @@ private:
get_param_func_t get_param_func;
log_param_func_t log_param_func;
initialize_component_func_t initialize_component_func;
initialize_system_port_func_t initialize_system_port_func;
start_func_t start_func;
control_func_t control_func;
struct function_list_item;
......@@ -184,6 +189,7 @@ public:
get_param_func_t par_get_param_func,
log_param_func_t par_log_param_func,
initialize_component_func_t par_initialize_component_func,
initialize_system_port_func_t par_initialize_system_port_func,
start_func_t par_start_func,
control_func_t par_control_func);
TTCN_Module(const char *par_module_name,
......
......@@ -503,6 +503,24 @@ boolean PORT::port_is_started() {
return is_started;
}
void PORT::safe_start()
{
if (!is_started) {
activate_port(TRUE);
start();
}
}
void PORT::add_port(PORT* /*p*/)
{
TTCN_error("Internal error: Calling PORT::add_port");
}
void PORT::remove_port(PORT* /*p*/)
{
TTCN_error("Internal error: Calling PORT::remove_port");
}
PORT* PORT::get_provider_port() {
return NULL;
}
......@@ -2493,6 +2511,9 @@ void PORT::terminate_local_connection(const char *src_port,
void PORT::map_port(const char *component_port, const char *system_port, boolean translation)
{
if (translation == TRUE) {
TTCN_Runtime::initialize_system_port(system_port);
}
const char *port_name = translation == FALSE ? component_port : system_port;
PORT *port_ptr = lookup_by_name(port_name, translation);
if (port_ptr == NULL) TTCN_error("Map operation refers to "
......@@ -2505,17 +2526,21 @@ void PORT::map_port(const char *component_port, const char *system_port, boolean
} else {
port_ptr->map(component_port, translation);
}
if (!TTCN_Runtime::is_single()) {
if (translation == FALSE) {
TTCN_Communication::send_mapped(component_port, system_port, translation);
} else {
TTCN_Communication::send_mapped(system_port, component_port, translation);
if (translation == TRUE) {
PORT* other_port_ptr = lookup_by_name(component_port, FALSE);
if (other_port_ptr == NULL) {
TTCN_error("Map operation refers to non-existent port %s.", port_name);
}
other_port_ptr->add_port(port_ptr);