Commit f5015a57 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Fixed port translation with central storage (bug 542610)



Change-Id: If713b6c4a75fc6c65d78ce40ca7adae19c7aca7c
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent 3cfe23a2
......@@ -2493,16 +2493,6 @@ namespace Ttcn {
pdef.provider_msg_in.elements = NULL;
}
if (port_type == PT_PROVIDER) {
pdef.mapper_name = (const char**)Malloc(mapper_types.size() * sizeof(const char*));
pdef.mapper_realtime = (boolean*)Malloc(mapper_types.size() * sizeof(boolean));
pdef.n_mapper_name = mapper_types.size();
for (size_t i = 0; i < mapper_types.size(); i++) {
pdef.mapper_name[i] = pool.add(mapper_types[i]->get_genname_value(my_scope));
pdef.mapper_realtime[i] = mapper_types[i]->get_PortBody()->is_realtime();
}
}
defPortClass(&pdef, target);
if (generate_skeleton && testport_type != TP_INTERNAL &&
(port_type != PT_USER || !legacy)) generateTestPortSkeleton(&pdef);
......@@ -2537,8 +2527,6 @@ namespace Ttcn {
for (size_t i = 0; i < pdef.provider_msg_outlist.nElements; i++)
Free(pdef.provider_msg_outlist.elements[i].out_msg_type_names);
Free(pdef.provider_msg_outlist.elements);
Free(pdef.mapper_name);
Free(pdef.mapper_realtime);
Free(pdef.var_decls);
Free(pdef.var_defs);
Free(pdef.mapping_func_decls);
......
......@@ -1752,13 +1752,11 @@ void defPortClass(const port_def* pdef, output_struct* output)
}
// 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"
"size_t n_%i;\n", pdef->mapper_name[i], (int)i, (int)i);
}
if (pdef->port_type == PROVIDER) {
def = mputstr(def,
"private:\n"
"PORT** mapped_ports;\n"
"size_t n_mapped_ports;\n");
}
def = mputstr(def, "public:\n");
......@@ -1789,10 +1787,10 @@ void defPortClass(const port_def* pdef, output_struct* output)
src = mputprintf(src, "port_state = UNSET;\n");
}
// Port type variables in the provider types.
for (i = 0; i < pdef->n_mapper_name; i++) {
src = mputprintf(src,
"p_%i = NULL;\n"
"n_%i = 0;\n", (int)i, (int)i);
if (pdef->port_type == PROVIDER) {
src = mputstr(src,
"mapped_ports = NULL;\n"
"n_mapped_ports = 0;\n");
}
src = mputstr(src, "}\n\n");
......@@ -2311,76 +2309,54 @@ void defPortClass(const port_def* pdef, output_struct* output)
}
// Port type variables in the provider types.
if (pdef->n_mapper_name > 0) {
if (pdef->port_type == PROVIDER) {
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++) {
src = mputprintf(src,
"%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] = 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");
src = mputprintf(src,
"void %s::add_port(PORT* p)\n"
"{\n"
"++n_mapped_ports;\n"
"mapped_ports = static_cast<PORT**>(Realloc(mapped_ports, "
"n_mapped_ports * sizeof(PORT*)));\n"
"mapped_ports[n_mapped_ports - 1] = p;\n"
"}\n\n", class_name);
def = mputstr(def, "void remove_port(PORT* p);\n");
src = mputprintf(src, "void %s::remove_port(PORT* p)\n{\n", class_name);
for (i = 0; i < pdef->n_mapper_name; i++) {
src = mputprintf(src,
"%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] == x_%i) {\n"
"p_%i[i] = NULL;\n"
"}\n"
"}\n"
"size_t size = 0;\n"
"%s** port_list = NULL;\n"
"for (size_t i = 0; i < n_%i; i++) {\n"
"if (p_%i[i] != NULL) {\n"
"size++;\n"
"port_list = static_cast<%s**>(Realloc(port_list, size * sizeof(%s*)));\n"
"port_list[size-1] = p_%i[i];\n"
"}\n"
"}\n"
"Free(p_%i);\n"
"p_%i = port_list;\n"
"n_%i = size;\n"
"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");
src = mputprintf(src,
"void %s::remove_port(PORT* p)\n"
"{\n"
"size_t new_size = n_mapped_ports;\n"
"for (size_t i = 0; i < n_mapped_ports; ++i) {\n"
"if (mapped_ports[i] == p) {\n"
"mapped_ports[i] = NULL;\n"
"--new_size;\n"
"}\n"
"}\n"
"if (new_size != n_mapped_ports) {\n"
"PORT** new_list = static_cast<PORT**>(Malloc(new_size * sizeof(PORT*)));\n"
"for (size_t i = 0, j = 0; i < n_mapped_ports; ++i) {\n"
"if (mapped_ports[i] != NULL) {\n"
"new_list[j] = mapped_ports[i];\n"
"++j;\n"
"}\n"
"}\n"
"Free(mapped_ports);\n"
"mapped_ports = new_list;\n"
"n_mapped_ports = new_size;\n"
"}\n"
"}\n\n", class_name);
def = mputstr(def, "private:\n");
// 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++) {
src = mputprintf(src,
"Free(p_%i);\n"
"p_%i = NULL;\n"
"n_%i = 0;\n", (int)i, (int)i, (int)i);
}
src = mputstr(src, "}\n\n");
src = mputprintf(src,
"void %s::reset_port_variables()\n"
"{\n"
"Free(mapped_ports);\n"
"mapped_ports = NULL;\n"
"n_mapped_ports = 0;\n"
"}\n\n", class_name);
}
if ((pdef->testport_type != INTERNAL || !pdef->legacy) &&
......@@ -2608,7 +2584,7 @@ void defPortClass(const port_def* pdef, output_struct* output)
def = mputstr(def, "public:\n");
// Generate new functions for provider types to avoid changing the visibility of outgoing_send
if (pdef->n_mapper_name > 0) {
if (pdef->port_type == PROVIDER) {
for (i = 0; i < pdef->msg_out.nElements; i++) {
def = mputprintf(def, "void outgoing_public_send("
"const %s& send_par%s);\n", pdef->msg_out.elements[i].name,
......@@ -2767,9 +2743,6 @@ void defPortClass(const port_def* pdef, output_struct* output)
if (pdef->port_type == USER) {
/* incoming_message() functions for the incoming types of the provider
* port type */
if (!pdef->legacy) {
def = mputstr(def, "public:\n");
}
for (i = 0; i < pdef->provider_msg_in.nElements; i++) {
const port_msg_mapped_type *mapped_type =
pdef->provider_msg_in.elements + i;
......@@ -2866,11 +2839,43 @@ void defPortClass(const port_def* pdef, output_struct* output)
}
src = mputstr(src, "}\n\n");
}
if (!pdef->legacy && pdef->provider_msg_in.nElements) {
/* virtual incoming_message_handler function */
def = mputprintf(def,
"boolean incoming_message_handler(const void* message_ptr, "
"const char* message_type, component sender_component, "
"const FLOAT& timestamp);\n"); /* TODO: address? */
src = mputprintf(src,
"boolean %s::incoming_message_handler(const void* message_ptr, "
"const char* message_type, component sender_component, "
"const FLOAT&%s)\n"
"{\n", class_name, pdef->realtime ? " timestamp" : "");
for (i = 0; i < pdef->provider_msg_in.nElements; i++) {
const port_msg_mapped_type* mapped_type =
pdef->provider_msg_in.elements + i;
if (i > 0) {
src = mputstr(src, "else ");
}
src = mputprintf(src,
"if (strcmp(message_type, \"%s\") == 0) {\n"
"const %s* typed_ptr = reinterpret_cast<const %s*>(message_ptr);\n"
"if (typed_ptr == NULL) {\n"
"TTCN_error(\"Internal error: Type of message in incoming message "
"handler function is not the indicated `%s'\");\n"
"}\n"
"incoming_message(*typed_ptr, sender_component%s);\n"
"return TRUE;\n"
"}\n", mapped_type->dispname, mapped_type->name, mapped_type->name,
mapped_type->dispname, pdef->realtime ? ", timestamp" : "");
}
src = mputstr(src,
"return FALSE;\n"
"}\n\n");
}
} else { /* not user */
/* incoming_message functions */
if (pdef->port_type == PROVIDER && pdef->n_mapper_name > 0) {
def = mputstr(def, "public:\n");
}
for (i = 0; i < pdef->msg_in.nElements; i++) {
def = mputprintf(def, "void incoming_message(const %s& "
"incoming_par, component sender_component",
......@@ -2895,18 +2900,17 @@ void defPortClass(const port_def* pdef, output_struct* output)
src = mputstr(src, ", const FLOAT& timestamp");
}
src = mputstr(src, ")\n{\n");
if (pdef->port_type == PROVIDER && pdef->n_mapper_name > 0) {
if (pdef->port_type == PROVIDER) {
// We forward the incoming_message to the mapped port
for (size_t j = 0; j < pdef->n_mapper_name; j++) {
src = mputprintf(src,
"for (size_t i = 0; i < n_%i; i++) {\n"
"if (p_%i[i] != NULL) {\n"
"p_%i[i]->incoming_message(incoming_par, sender_component%s);\n"
"return;\n}"
"}\n",
(int)j, (int)j, (int)j,
(pdef->realtime && pdef->mapper_realtime[j]) ? ", timestamp" : "");
}
src = mputprintf(src,
"for (size_t i = 0; i < n_mapped_ports; i++) {\n"
"if (mapped_ports[i] != NULL && mapped_ports[i]->"
"incoming_message_handler(&incoming_par, \"%s\", sender_component, %s)) {\n"
"return;\n"
"}\n"
"}\n",
pdef->msg_in.elements[i].dispname,
pdef->realtime ? "timestamp" : "FLOAT()");
}
src = mputstr(src,
"if (!is_started) TTCN_error(\"Port %s is not started but a "
......@@ -2956,8 +2960,7 @@ void defPortClass(const port_def* pdef, output_struct* output)
}
}
if ((pdef->port_type == PROVIDER && pdef->n_mapper_name > 0) ||
(pdef->port_type == USER && !pdef->legacy)) {
if (pdef->port_type == PROVIDER || (pdef->port_type == USER && !pdef->legacy)) {
def = mputstr(def, "private:\n");
}
......
......@@ -116,9 +116,6 @@ typedef struct port_def_tag {
testport_type_t testport_type;
port_type_t port_type;
port_msg_prov_list provider_msg_outlist;
const char **mapper_name;
boolean* mapper_realtime;
size_t n_mapper_name;
port_msg_mapped_type_list provider_msg_in;
boolean has_sliding;
boolean legacy; // true if the old user port is used false if translation ports used
......
......@@ -525,6 +525,12 @@ PORT* PORT::get_provider_port() {
return NULL;
}
boolean PORT::incoming_message_handler(const void* message_ptr, const char* message_type,
component sender_component, const FLOAT& timestamp)
{
return FALSE;
}
alt_status PORT::receive(const COMPONENT_template&, COMPONENT *, FLOAT*, Index_Redirect*)
{
TTCN_Logger::log_matching_problem(
......
......@@ -157,6 +157,9 @@ public:
// capability and dual faced ports.
virtual PORT* get_provider_port();
virtual boolean incoming_message_handler(const void* message_ptr, const char* message_type,
component sender_component, const FLOAT& timestamp);
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);
......
......@@ -49,7 +49,7 @@ all_from lazyEval tryCatch text2ttcn json ttcn2json profiler templateOmit \
customEncoding makefilegen uidChars checkstate hostid templateIstemplatekind \
selectUnion templateExclusiveRange any_from templatePatternRef indexWithRecofArray \
connectMapOperTest fuzzy portTranslation ischosen OER functionSubref done \
nondeterministicDefaultParam predefFunction2 realtime
nondeterministicDefaultParam predefFunction2 realtime portTranslationCentralStorage
ifdef DYN
DIRS += loggerplugin junitlogger
......
##############################################################################
# Copyright (c) 2000-2018 Ericsson Telecom AB
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v2.0
# which accompanies this distribution, and is available at
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
#
# Contributors:
# Baranyi, Botond
#
##############################################################################
TOPDIR := ..
include ../Makefile.regression
.PHONY: all run clean distclean dep
all clean distclean dep run:
$(MAKE) -C ProjA/bin $@
$(MAKE) -C ProjB/bin $@
ProjA
ProjA.exe
A*.cc
A*.hh
*.o
*.d
compile
*.log
##############################################################################
# Copyright (c) 2000-2018 Ericsson Telecom AB
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v2.0
# which accompanies this distribution, and is available at
# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
#
# Contributors:
# Baranyi, Botond
#
##############################################################################
TOPDIR := ../../..
include ../../../Makefile.regression
#
# Do NOT touch this line...
#
.PHONY: all run archive check clean dep objects
.SUFFIXES: .d
#
# Set these variables...
#
# Flags for the C++ preprocessor (and makedepend as well):
CPPFLAGS += -I. -I../src
#CXXFLAGS += -save-temps
CXXFLAGS += -g
# Flags for dependency generation
CXXDEPFLAGS = -MM
# Flags for the linker:
LDFLAGS += -g
ifeq ($(PLATFORM), WIN32)
# Silence linker warnings.
LDFLAGS += -Wl,--enable-auto-import,--enable-runtime-pseudo-reloc
endif
# Flags for the TTCN-3 and ASN.1 compiler:
COMPILER_FLAGS += -I
# Execution mode: (either ttcn3 or ttcn3-parallel)
TTCN3_LIB = ttcn3$(RT2_SUFFIX)-parallel$(DYNAMIC_SUFFIX)
# TTCN-3 modules of this project:
TTCN3_MODULES = ../src/A.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 = A.cc
GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
ifdef SPLIT_TO_SLICES
POSTFIXES := $(foreach file, $(SPLIT_TO_SLICES), $(addsuffix $(file), _part_))
POSTFIXES := $(foreach file, $(POSTFIXES), $(addprefix $(file), .cc))
GENERATED_SOURCES2 := $(foreach file, $(GENERATED_SOURCES:.cc=), $(addprefix $(file), $(POSTFIXES)))
GENERATED_SOURCES += $(GENERATED_SOURCES2)
endif
# C/C++ Source & header files of Test Ports, external functions and
# other modules:
USER_SOURCES = ../src/PortA.cc ../src/PortA_RT.cc
USER_HEADERS = $(USER_SOURCES:.cc=.hh)
# Object files of this project that are needed for the executable test suite:
OBJECTS = $(GENERATED_OBJECTS) $(USER_OBJECTS)
GENERATED_OBJECTS = $(GENERATED_SOURCES:.cc=.o)
USER_OBJECTS = PortA.o PortA_RT.o
DEPFILES = $(USER_OBJECTS:.o=.d) $(GENERATED_OBJECTS:.o=.d)
# Other files of the project (Makefile, configuration files, etc.)
# that will be added to the archived source files:
OTHER_FILES = Makefile
# The name of the executable test suite:
TARGET = ProjA$(EXESUFFIX)
#
# Rules for building the executable...
#
all: $(TARGET) ;
objects: $(OBJECTS) ;
$(TARGET): $(OBJECTS)
$(TTCN3_DIR)/bin/titanver $(OBJECTS)
$(CXX) $(LDFLAGS) -o $@ $^ \
-L$(TTCN3_DIR)/lib -l$(TTCN3_LIB) \
-L$(OPENSSL_DIR)/lib -lcrypto \
-L$(XMLDIR)/lib $($(PLATFORM)_LIBS)
PortA.o : ../src/PortA.cc
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
PortA_RT.o : ../src/PortA_RT.cc
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
.cc.o .c.o:
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) -o $@ $<
PortA.d : ../src/PortA.cc
@echo Creating dependency file for '$<'; set -e; \
$(CXX) $(CXXDEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $< \
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
[ -s $@ ] || rm -f $@
PortA_RT.d : ../src/PortA_RT.cc
@echo Creating dependency file for '$<'; set -e; \
$(CXX) $(CXXDEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $< \
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
[ -s $@ ] || rm -f $@
.cc.d .c.d:
@echo Creating dependency file for '$<'; set -e; \
$(CXX) $(CXXDEPFLAGS) $(CPPFLAGS) $(CXXFLAGS) $< \
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
[ -s $@ ] || rm -f $@
$(GENERATED_SOURCES) $(GENERATED_HEADERS): compile
@if [ ! -f $@ ]; then $(RM) compile; $(MAKE) compile; fi
compile: $(TTCN3_MODULES) $(ASN1_MODULES)
$(TTCN3_DIR)/bin/compiler $(COMPILER_FLAGS) $^ - $?
touch $@
clean distclean:
-$(RM) $(TARGET) $(OBJECTS) $(GENERATED_HEADERS) \
$(GENERATED_SOURCES) compile $(DEPFILES) \
*.log
dep: $(GENERATED_SOURCES) $(USER_SOURCES) ;
ifeq ($(findstring n,$(MAKEFLAGS)),)
ifeq ($(filter clean distclean check compile archive diag,$(MAKECMDGOALS)),)
-include $(DEPFILES)
endif
endif
#
# Add your rules here if necessary...
#
run: $(TARGET)
/******************************************************************************
* Copyright (c) 2000-2018 Ericsson Telecom AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
*
* Contributors:
* Baranyi, Botond
*
******************************************************************************/
// This module tests translation ports when using central storage (or project
// references in the Eclipse Designer plug-in)
// The provider port types declared here must work in translation mode with
// user ports from another project
module A {
type port PortA message {
inout integer
}
with {
extension "provider"
}
type port PortA_RT message realtime {
inout integer
}
with {
extension "provider"
}
}
// This Test Port skeleton source file was generated by the
// TTCN-3 Compiler of the TTCN-3 Test Executor version CRL 113 200/6 R5A
// for ebotbar (ebotbar@ebotbarVB) on Thu Dec 6 15:58:49 2018
// Copyright (c) 2000-2018 Ericsson Telecom AB
// You may modify this file. Complete the body of empty functions and
// add your member functions here.
#include "PortA.hh"
#include "A.hh"
namespace A {
PortA_PROVIDER::PortA_PROVIDER(const char *par_port_name)
: PORT(par_port_name)
{
}
PortA_PROVIDER::~PortA_PROVIDER()
{
}
void PortA_PROVIDER::set_parameter(const char * /*parameter_name*/,
const char * /*parameter_value*/)
{
}
/*void PortA_PROVIDER::Handle_Fd_Event(int fd, boolean is_readable,
boolean is_writable, boolean is_error) {}*/
void PortA_PROVIDER::Handle_Fd_Event_Error(int /*fd*/)
{
}
void PortA_PROVIDER::Handle_Fd_Event_Writable(int /*fd*/)
{
}
void PortA_PROVIDER::Handle_Fd_Event_Readable(int /*fd*/)
{
}
/*void PortA_PROVIDER::Handle_Timeout(double time_since_last_call) {}*/
void PortA_PROVIDER::user_map(const char * /*system_port*/)