Commit de7ae949 authored by balaskoa's avatar balaskoa
Browse files

C\++ changed to {cpp} in each adoc file.


Signed-off-by: default avatarbalaskoa <Jeno.Balasko@ericsson.com>
parent d79c3483
......@@ -2,7 +2,7 @@
== Overview
This document describes the TITAN API on C\++ level. It is intended for users who write test port implementation, external function implementation in language {cpp} and want to use the available resources of TITAN.
This document describes the TITAN API on {cpp} level. It is intended for users who write test port implementation, external function implementation in language {cpp} and want to use the available resources of TITAN.
Detailed information can be found on the following topics:
......
......@@ -12,7 +12,7 @@ The functions of Test Ports must be written by the user who knows the interface
A Test Port consists of two parts. One part is generated automatically by the Compiler, and it is put into the generated {cpp} code. The user has nothing to do with this part.
The other part is a C\++ class, which is written mainly by the user. This class can be found in a separate {cpp} header and source file (their suffixes are `.hh` and `.cc`, respectively). The names of the source files and the {cpp} class are identical to the name of the port type. Please note that the name mapping rules described in <<5-mapping_ttcn3_data_types_to_c+\+_constructs.adoc#mapping-of-names-and-identifiers, Mapping of Names and Identifiers>> also apply to these class and file names.
The other part is a {cpp} class, which is written mainly by the user. This class can be found in a separate {cpp} header and source file (their suffixes are `.hh` and `.cc`, respectively). The names of the source files and the {cpp} class are identical to the name of the port type. Please note that the name mapping rules described in <<5-mapping_ttcn3_data_types_to_c+\+_constructs.adoc#mapping-of-names-and-identifiers, Mapping of Names and Identifiers>> also apply to these class and file names.
During the translation, when the Compiler encounters a port type definition and the `*–t*` command line switch is used, it checks whether the header and source files of Test Port exist in its working directory. If none of them can be found there, the compiler generates the skeleton header and source files for the corresponding test port automatically. This means, once you have generated (and possibly modified) a skeleton, it will never be overwritten. If you want to re-generate the skeleton, you must rename or remove the existing one.
......
......@@ -30,7 +30,7 @@ The generated, runtime specific (load-test or function-test) header file `TitanL
#endif
----
Unfortunately, the `dlopen()` API is a C API, not a C\++ API, but each logger plug-in is a class, which needs to be instantiated. To resolve this, the logger plug-ins are always instantiated and destroyed through C factory functions. These functions are mandatory for all logger plug-ins and they must follow C-style linkage rules. Otherwise, the function names would be mangled by the {cpp} compiler, using its own, implementation dependent mangling mechanism, and `dlsym()` and such functions would not be able to locate the correct symbol in the SOs of the logger plug-ins. These functions look pretty simple:
Unfortunately, the `dlopen()` API is a C API, not a {cpp} API, but each logger plug-in is a class, which needs to be instantiated. To resolve this, the logger plug-ins are always instantiated and destroyed through C factory functions. These functions are mandatory for all logger plug-ins and they must follow C-style linkage rules. Otherwise, the function names would be mangled by the {cpp} compiler, using its own, implementation dependent mangling mechanism, and `dlsym()` and such functions would not be able to locate the correct symbol in the SOs of the logger plug-ins. These functions look pretty simple:
[source]
----
#ifdef __cplusplus
......@@ -79,7 +79,7 @@ void log(const TitanLoggerApi::TitanLogEvent& event, bool
The first parameter event is the event itself, the second parameter `log_buffered` indicates, whether the event is coming from an internal buffer or not, `separate_file` and `use_emergency_mask` are configuration options for emergency logging. The `use_emergency_mask` flag indicates that the given event is an emergency event and should be handled in a special way by the plug-ins, the `separate_file` flag indicates that all the emergency events should be handled separately (for example written into a separate file). For more details on emergency logging please check link:https://github.com/eclipse/titan.core/tree/master/usrguide/referenceguide[Programmer's Technical Reference]. In this function, the plug-in can handle the log events individually depending on the event’s type (that is, the alternative selected in the union `event.logEvent().choice()).`
`TitanLoggerApi::TitanLogEvent` is a generated type defined in TitanLoggerApi.xsd, which can be found in `${TTCN3_DIR}/include`. This file contains all the necessary type definitions a logger plug-in should be aware of. The corresponding header files generated from this XSD file can be found in `${TTCN3_DIR}/include/{RT1/RT2}`. The mapping between TTCN-3 types and C\++ types is defined in link:5-mapping_ttcn3_data_types_to_c+\+_constructs.adoc[Mapping TTCN–3 Data Types to {cpp} Constructs].
`TitanLoggerApi::TitanLogEvent` is a generated type defined in TitanLoggerApi.xsd, which can be found in `${TTCN3_DIR}/include`. This file contains all the necessary type definitions a logger plug-in should be aware of. The corresponding header files generated from this XSD file can be found in `${TTCN3_DIR}/include/{RT1/RT2}`. The mapping between TTCN-3 types and {cpp} types is defined in link:5-mapping_ttcn3_data_types_to_c+\+_constructs.adoc[Mapping TTCN–3 Data Types to {cpp} Constructs].
//The mapping between XSD and TTCN-3 types is defined in *Error! Reference source not found.*
== Execution
......
......@@ -3,20 +3,20 @@
:table-number: 7
:toc:
The TTCN–3 language elements of the test suite are individually mapped into more or less equivalent C\++ constructs. The data types are mapped to {cpp} classes, the test cases become {cpp} functions, and so on. In order to write a Test Port, it is inevitable to be familiar with the internal representation format of TTCN–3 data types and values. This section gives an overview about the data types and their equivalent {cpp} constructs.
The TTCN–3 language elements of the test suite are individually mapped into more or less equivalent {cpp} constructs. The data types are mapped to {cpp} classes, the test cases become {cpp} functions, and so on. In order to write a Test Port, it is inevitable to be familiar with the internal representation format of TTCN–3 data types and values. This section gives an overview about the data types and their equivalent {cpp} constructs.
[[mapping-of-names-and-identifiers]]
== Mapping of Names and Identifiers
In order to identify the TTCN–3 language elements in the generated C\++ program properly, the names of test suite are translated to {cpp} identifiers according to the following simple rules.
In order to identify the TTCN–3 language elements in the generated {cpp} program properly, the names of test suite are translated to {cpp} identifiers according to the following simple rules.
If the TTCN–3 identifier does not contain any underscore (_) character, its equivalent C\++ identifier will be the same. For example, the TTCN–3 variable `MyVar` will be translated to a {cpp} variable called `MyVar`.
If the TTCN–3 identifier does not contain any underscore (_) character, its equivalent {cpp} identifier will be the same. For example, the TTCN–3 variable `MyVar` will be translated to a {cpp} variable called `MyVar`.
If the TTCN–3 identifier contains one or more underscore characters, each underscore character will be duplicated in the C\++ identifier. So the TTCN–3 identifier `My_Long_Name` will be mapped to a {cpp} identifier called `My\__Long__Name`.
If the TTCN–3 identifier contains one or more underscore characters, each underscore character will be duplicated in the {cpp} identifier. So the TTCN–3 identifier `My_Long_Name` will be mapped to a {cpp} identifier called `My\__Long__Name`.
The idea behind this name mapping is that we may freely use the C\++ identifiers containing one underscore character in the generated code and in the Test Ports as well. Otherwise name clashes can always happen because the name space of TTCN–3 and {cpp} is identical. Furthermore, the generated C\++ language elements fulfill the condition that the scope of a translated {cpp} identifier is identical as the scope of the original TTCN–3 identifier.
The idea behind this name mapping is that we may freely use the {cpp} identifiers containing one underscore character in the generated code and in the Test Ports as well. Otherwise name clashes can always happen because the name space of TTCN–3 and {cpp} is identical. Furthermore, the generated {cpp} language elements fulfill the condition that the scope of a translated {cpp} identifier is identical as the scope of the original TTCN–3 identifier.
The identifiers that are keywords of C or C\++ but not keywords in TTCN–3 are mapped to themselves, but a single underscore character is appended at the end (for example `typedef` becomes `typedef_`). The same rule applies to the all-uppercase identifiers that are used in the Base Library: identifier `INTEGER` in TTCN–3 becomes `INTEGER_` in {cpp}, `TRUE` footnote:[The built-in `verdict` and `boolean` constants in TTCN–3 shall be written with all lowercase letters, such as true or pass. Although previous compiler versions have accepted `TRUE` or `PASS` as well, these words are treated by the compiler as regular identifiers as specified in the standard.] is mapped to `TRUE_`, etc.
The identifiers that are keywords of C or {cpp} but not keywords in TTCN–3 are mapped to themselves, but a single underscore character is appended at the end (for example `typedef` becomes `typedef_`). The same rule applies to the all-uppercase identifiers that are used in the Base Library: identifier `INTEGER` in TTCN–3 becomes `INTEGER_` in {cpp}, `TRUE` footnote:[The built-in `verdict` and `boolean` constants in TTCN–3 shall be written with all lowercase letters, such as true or pass. Although previous compiler versions have accepted `TRUE` or `PASS` as well, these words are treated by the compiler as regular identifiers as specified in the standard.] is mapped to `TRUE_`, etc.
Here is the complete list (in alphabetical order) of the identifiers that are handled in such special way:asm, auto, bitand, bitor, bool, break, case, class, compl, continue, delete, double, enum, explicit, export, friend, inline, int, ischosen, long, main, mutable, namespace, new, operator, private, protected, public, register, short, signed, static, stderr, stdin, stdout, struct, switch, this, throw, try, typedef, typeid, typename, unsigned, using, virtual, void, volatile, ADDRESS, BITSTRING, BOOLEAN, CHAR, CHARSTRING, COMPONENT, DEFAULT, ERROR, FAIL, FALSE, FLOAT, HEXSTRING, INCONC, INTEGER, NONE, OBJID, OCTETSTRING, PASS, PORT, TIMER, TRUE, VERDICTTYPE.
......@@ -32,12 +32,12 @@ The compiler generates a {cpp} namespace for every TTCN–3 and ASN.1 module. Al
The definitions of the TTCN–3 Base Library do not use any namespace.
When accessing a C\++ entity that belongs to a different module than the referring Test Port or external function is in the reference has to be prefixed with the namespace of the referenced module. For example, to access the {cpp} class that realizes type `MyType` defined in `MyModule1` from a Test Port that belongs to module `MyModule2` the reference shall be written as `MyModule1::MyType`.
When accessing a {cpp} entity that belongs to a different module than the referring Test Port or external function is in the reference has to be prefixed with the namespace of the referenced module. For example, to access the {cpp} class that realizes type `MyType` defined in `MyModule1` from a Test Port that belongs to module `MyModule2` the reference shall be written as `MyModule1::MyType`.
[[predefined-ttcn-3-data-types]]
== Predefined TTCN–3 Data Types
There are some basic data types in TTCN–3 that have no equivalent data types in language C/C\++ (for example bitstring, verdicttype). Other types have {cpp} equivalent, but the TTCN–3 executor must know whether a variable has a valid value or not because sending an unbound value must result in a dynamic test case error. Thus, in the TTCN–3 Base Library all basic data types of TTCN–3 were implemented as {cpp} classes. This section describes the member functions of these classes.
There are some basic data types in TTCN–3 that have no equivalent data types in language C/{cpp} (for example bitstring, verdicttype). Other types have {cpp} equivalent, but the TTCN–3 executor must know whether a variable has a valid value or not because sending an unbound value must result in a dynamic test case error. Thus, in the TTCN–3 Base Library all basic data types of TTCN–3 were implemented as {cpp} classes. This section describes the member functions of these classes.
=== `Integer`
......@@ -298,7 +298,7 @@ void TTCN_Runtime::setverdict(const VERDICTTYPE&);
verdicttype TTCN_Runtime::getverdict();
----
These functions are the C\++ equivalents of TTCN–3 `setverdict` and `getverdict` operations. Use them only if your Test Port or {cpp} function encounters a low-level failure, but it can continue its normal operation (that is, error recovery is not necessary).
These functions are the {cpp} equivalents of TTCN–3 `setverdict` and `getverdict` operations. Use them only if your Test Port or {cpp} function encounters a low-level failure, but it can continue its normal operation (that is, error recovery is not necessary).
Other operators (global functions):
[source]
......@@ -1085,7 +1085,7 @@ boolean operator!=(component component_value,
Empty `record` and `set` types are not real built-in types in TTCN–3, but the {cpp} realization of these types also differs from regular records or sets. The empty types are almost identical to each other, only their names are different. That is why we treat them as predefined types.
Each empty type is defined in a C\++ class, which is generated by the compiler. Using separate classes enables us to differentiate among them in {cpp} type polymorphism. For example, several empty types can be defined as incoming or outgoing types on the same TTCN–3 port type.
Each empty type is defined in a {cpp} class, which is generated by the compiler. Using separate classes enables us to differentiate among them in {cpp} type polymorphism. For example, several empty types can be defined as incoming or outgoing types on the same TTCN–3 port type.
Let us consider the following TTCN–3 type definition as an example:
[source, subs="+quotes"]
......@@ -1140,7 +1140,7 @@ The user-defined compound data types are implemented in {cpp} classes. These cla
=== Record and Set Type Constructs
The TTCN–3 type constructs `record` and `set` are mapped in an identical way to C\++. There will be a {cpp} class for each record type in the generated code. This class builds up the record from its fields.footnote:[This section deals with the record and set types that have at least one field. See <<empty-types, Empty Types>> for the {cpp} mapping of empty record and set types.] The fields can be either basic or compound types.
The TTCN–3 type constructs `record` and `set` are mapped in an identical way to {cpp}. There will be a {cpp} class for each record type in the generated code. This class builds up the record from its fields.footnote:[This section deals with the record and set types that have at least one field. See <<empty-types, Empty Types>> for the {cpp} mapping of empty record and set types.] The fields can be either basic or compound types.
Let us consider the following example type definition. The types `t1` and `t2` can be arbitrary.
[source]
......@@ -1296,7 +1296,7 @@ Using the value of an unbound `union` variable for anything will cause dynamic t
==== The anytype
The TTCN-3 anytype is implemented as a C\++ class named anytype. The class is generated only if an actual anytype access is present in the module. It has the same interface as any other {cpp} class generated for a union, with a few differences:
The TTCN-3 anytype is implemented as a {cpp} class named anytype. The class is generated only if an actual anytype access is present in the module. It has the same interface as any other {cpp} class generated for a union, with a few differences:
If a field is a built-in type or the address type, the name used in `union_selection_type` is the name of the runtime class implementing the type (usually the name of the type in all uppercase).
......@@ -1399,7 +1399,7 @@ boolean operator!=(null_type null_value, const t2& other_value); // Not equal
==== Pre-generated `record of` and `set of` constructs
The C\++ classes for the `record of` and `set of` constructs of most predefined TTCN-3 types are pre-generated and part of the TITAN runtime. Only a type alias ({cpp} `typedef`) is generated for instances of these types declared in TTCN-3 and ASN.1 modules. There is a class with regular memory allocation and one with optimized memory allocation pre-generated for each type. These classes are located in the `PreGenRecordOf` namespace.
The {cpp} classes for the `record of` and `set of` constructs of most predefined TTCN-3 types are pre-generated and part of the TITAN runtime. Only a type alias ({cpp} `typedef`) is generated for instances of these types declared in TTCN-3 and ASN.1 modules. There is a class with regular memory allocation and one with optimized memory allocation pre-generated for each type. These classes are located in the `PreGenRecordOf` namespace.
.Pre-generated classes for `record of`/`set of` predefined types
......@@ -1541,7 +1541,7 @@ Using the value of an unbound enumerated variable for anything will cause dynami
=== The `address` Type
The special TTCN–3 data type `address` is represented in C\++ as if it was a regular data type. The name of the equivalent {cpp} class is `ADDRESS`. If it is an alias to another (either built-in or user-defined) type then a {cpp} `typedef` is used.
The special TTCN–3 data type `address` is represented in {cpp} as if it was a regular data type. The name of the equivalent {cpp} class is `ADDRESS`. If it is an alias to another (either built-in or user-defined) type then a {cpp} `typedef` is used.
== Predefined Functions
......@@ -1549,7 +1549,7 @@ Annex C of link:https://www.etsi.org/deliver/etsi_es/201800_201899/20187301/04.0
The prototypes for these functions can be found in `*$TTCN3_DIR/include/Addfunc.hh*`, but for easier navigation we list them also in the present document.
The majority of these functions have more than one polymorphic version: when appropriate, one of them takes literal (built-in) C\++ types as arguments instead of the objects of equivalent {cpp} classes. For instance, if the incoming argument is stored in an `int` variable in your {cpp} code, you should not construct a temporary object of class `INTEGER` because passing an `int` is faster and produces smaller binary code. Similarly, the returned type is also literal when it is possible.
The majority of these functions have more than one polymorphic version: when appropriate, one of them takes literal (built-in) {cpp} types as arguments instead of the objects of equivalent {cpp} classes. For instance, if the incoming argument is stored in an `int` variable in your {cpp} code, you should not construct a temporary object of class `INTEGER` because passing an `int` is faster and produces smaller binary code. Similarly, the returned type is also literal when it is possible.
=== `Integer` to character
......@@ -1935,6 +1935,6 @@ The class representing the exceptions of a signature (remote procedure) is simil
|`void log() const` |Puts the contents of the exception into the log.
|===================================================================================================================================================================================================================================
If an exception type is a user-defined type the field name will be constructed from the C\++ namespace name of the module that the exception type resides in and the name of the {cpp} class that realizes the exception type. The two identifiers are glued together using a single underscore character. Please note that the namespace name is always present in the identifiers, even if the exception type is defined in the same module as the signature.
If an exception type is a user-defined type the field name will be constructed from the {cpp} namespace name of the module that the exception type resides in and the name of the {cpp} class that realizes the exception type. The two identifiers are glued together using a single underscore character. Please note that the namespace name is always present in the identifiers, even if the exception type is defined in the same module as the signature.
For example, if exception type `My_Record` is defined in module `My_Module` the respective field access functions will be named as `My\__Module_My__Record_field` and the associated enum value will be `MyProc_exception::ALT_My__Module_My__Record`.
......@@ -7,7 +7,7 @@ Information not fitting in any of the previous chapters is given in this chapter
[[migrating-existing-c-code-to-the-naming-rules-of-version-1-7]]
== Migrating Existing {cpp} Code to the Naming Rules of Version 1.7
When using the new naming rulesfootnote:[The new naming rules are used by default; the naming rules can be changed using the compiler command line switch -N.] the compiler generates a C\++ namespace for each TTCN–3 and ASN.1 module. The name of the namespace corresponds to the module. The generated {cpp} entities of a module are all placed in its namespace; therefore all the test port or protocol module code must use these namespaces.
When using the new naming rulesfootnote:[The new naming rules are used by default; the naming rules can be changed using the compiler command line switch -N.] the compiler generates a {cpp} namespace for each TTCN–3 and ASN.1 module. The name of the namespace corresponds to the module. The generated {cpp} entities of a module are all placed in its namespace; therefore all the test port or protocol module code must use these namespaces.
Rules to follow when writing {cpp} code:
......@@ -17,7 +17,7 @@ Rules to follow when writing {cpp} code:
* Encoding and decoding functions must be placed into the namespace of the TTCN–3 module in which the external function was defined.
* All C\++ entities have to be placed into namespace. An exception to this may be {cpp} entities used only locally; these are defined with the keyword `static`.
* All {cpp} entities have to be placed into namespace. An exception to this may be {cpp} entities used only locally; these are defined with the keyword `static`.
* For convenience the `using namespace` directive can be used in {cpp} source files. It is forbidden to use this directive in header files!
......@@ -59,7 +59,7 @@ The compiler will translate those external function definitions to {cpp} functio
[...]
----
Both pre-defined and user-defined TTCN–3 data types can be used as parameters and/or return types of the C\++ functions. The detailed description of the equivalent {cpp} classes as well as the name mapping rules are described in chapter <<4-encoding_and_decoding.adoc#xml-encoding-xer,XML Encoding (XER)>>.
Both pre-defined and user-defined TTCN–3 data types can be used as parameters and/or return types of the {cpp} functions. The detailed description of the equivalent {cpp} classes as well as the name mapping rules are described in chapter <<4-encoding_and_decoding.adoc#xml-encoding-xer,XML Encoding (XER)>>.
Using templates as formal parameters in external functions is possible, but not recommended because the API of the classes realizing templates is not documented and subject to change without notice.
......@@ -80,7 +80,7 @@ NOTE: In versions 1.6.pl3 and earlier the in keyword had an extra meaning in for
Due to the strictness of the TTCN–3 semantic analyzer one cannot use C/{cpp} data types with external functions as formal parameters or return types, only TTCN–3 and ASN.1 data types are allowed. Similarly, one cannot use pointers as parameters or return values because they have no equivalents in TTCN–3 .
The external functions can be implemented in one or more C\++ source files. The generated header file that contains the prototypes of the external functions shall be included into each {cpp} source file. This file makes accessible all built-in data types, the user-defined types of the corresponding TTCN–3 module and all available services of the run-time environment (logging, error handling, etc.).
The external functions can be implemented in one or more {cpp} source files. The generated header file that contains the prototypes of the external functions shall be included into each {cpp} source file. This file makes accessible all built-in data types, the user-defined types of the corresponding TTCN–3 module and all available services of the run-time environment (logging, error handling, etc.).
The name, return type and the parameters of the implemented {cpp} functions must match exactly the generated function prototypes or the compilation will fail. The generated function prototype is in the namespace of the module, therefore the implementation of the function has to be placed in that namespace, too.
[[logging-in-test-ports-or-external-functions]]
......@@ -273,7 +273,7 @@ In the executable test program there are system calls not only in the Base Libra
== Mixing C and {cpp} Modules
Modules written in C language may be used in the Test Ports. In this case the C header files must be included into the Test Port source code and the object files of the C module must be linked to the executable. Using a C compiler to compile the C modules may lead to errors when linking the modules together. This is because the C and C\++ compilers use different rules for mapping function names to symbol names of the object file to avoid name clashes caused by the {cpp} polymorphism. There are two possible solutions to solve this problem:
Modules written in C language may be used in the Test Ports. In this case the C header files must be included into the Test Port source code and the object files of the C module must be linked to the executable. Using a C compiler to compile the C modules may lead to errors when linking the modules together. This is because the C and {cpp} compilers use different rules for mapping function names to symbol names of the object file to avoid name clashes caused by the {cpp} polymorphism. There are two possible solutions to solve this problem:
1. Use the same {cpp} compiler to compile all of your source code (including C modules).
2. If the first one is impossible (when using a third party software that is available in binary format only), the definitions of the C header file must be put into an `extern "C"` block like this.
......@@ -290,4 +290,4 @@ extern "C" {
#endif
----
The latter solution does not work with all C\++ compilers; it was tested on GNU {cpp} compiler only.
The latter solution does not work with all {cpp} compilers; it was tested on GNU {cpp} compiler only.
......@@ -13,7 +13,7 @@ The type aliasing is implemented in the test executor, but it translates this TT
`typedef MyType MyAlternativeName;`
The limitation of the C typedef is that the C\++ compiler cannot distinguish between the original and alias name in polymorphism (i.e. the identically named functions with parameter type `MyType` and `MyAlternativeName` are treated as same). That is, if you define a port type that allows the sending or receiving both of the original and aliased type, the generated {cpp} code cannot be compiled because the Test Port class contains two identical send/receive function.
The limitation of the C typedef is that the {cpp} compiler cannot distinguish between the original and alias name in polymorphism (i.e. the identically named functions with parameter type `MyType` and `MyAlternativeName` are treated as same). That is, if you define a port type that allows the sending or receiving both of the original and aliased type, the generated {cpp} code cannot be compiled because the Test Port class contains two identical send/receive function.
As a work-around to this problem you can repeat the definition of the original type using the alternative name instead of type aliasing. In this case two differently named, but identical classes will be generated and the polymorphism problem will not occur.
......
......@@ -1129,7 +1129,7 @@ All component types are compatible with each empty component type. Empty compone
== Implicit Message Encoding
The TTCN–3 standard <<13-references.adoc#_1, [1]>> does not specify a standard way of data encoding/decoding. TITAN has a common C\++ API for encoding/decoding; to use this API external functions are usually needed. The common solution is to define a TTCN–3 external function and write the {cpp} code containing the API calls. In most cases the {cpp} code explicitly written to an auxiliary {cpp} file contains only simple code patterns which call the encoding/decoding API functions on the specified data. In TITAN there is a TTCN–3 language extension which automatically generates such external functions.
The TTCN–3 standard <<13-references.adoc#_1, [1]>> does not specify a standard way of data encoding/decoding. TITAN has a common {cpp} API for encoding/decoding; to use this API external functions are usually needed. The common solution is to define a TTCN–3 external function and write the {cpp} code containing the API calls. In most cases the {cpp} code explicitly written to an auxiliary {cpp} file contains only simple code patterns which call the encoding/decoding API functions on the specified data. In TITAN there is a TTCN–3 language extension which automatically generates such external functions.
Based on this automatic encoding/decoding mechanism, dual-faced ports are introduced. Dual-faced ports have an external and an internal interface and can automatically transform messages passed through them based on mapping rules defined in TTCN–3 source files. These dual-faced ports eliminate the need for simple port mapping components and thus simplify the test configuration.
......@@ -7229,8 +7229,8 @@ A number of checks are performed during the build to ensure consistency of the T
* The version of the TITAN compiler matches the version of the TITAN runtime
* The platform on which the build is being performed matches the platform of the TITAN compiler
* The compiler used to build the TITAN compiler matches the compiler used to build the TITAN runtime
* Some of this information (in form of C\++ preprocessor macros definitions and instructions) is available to test port writers to express dependency on a particular TITAN version. When a {cpp} file includes a header generated by the TITAN compiler, that header includes the definitions for the TITAN runtime, including version information. These macro dependencies can be used in user-written {cpp} code.
* TTCN3_VERSION is a C/C\++ macro defined by the TITAN runtime headers. It contains an aggregated value of the TITAN major version, minor version and patch level. So, to express that a certain {cpp} file must be compiled together with TITAN R8C, the following code can be used:
* Some of this information (in form of {cpp} preprocessor macros definitions and instructions) is available to test port writers to express dependency on a particular TITAN version. When a {cpp} file includes a header generated by the TITAN compiler, that header includes the definitions for the TITAN runtime, including version information. These macro dependencies can be used in user-written {cpp} code.
* TTCN3_VERSION is a C/{cpp} macro defined by the TITAN runtime headers. It contains an aggregated value of the TITAN major version, minor version and patch level. So, to express that a certain {cpp} file must be compiled together with TITAN R8C, the following code can be used:
+
[source]
----
......
......@@ -144,7 +144,7 @@ Because of the `-T` flag the `Third.ttcn` will be treated as a TTCN-3 file, and
* `-l`
+
Instructs the compiler to generate source file and line information (that is, #line directives) into the output code so that the error messages of the C\++ compiler refer back to the lines of the original TTCN–3 input module. This makes finding the reason of {cpp} error messages easier. This option has effect only in the equivalent {cpp} code of TTCN–3 functions, test cases and control parts and this feature is not provided in other TTCN–3 definitions such as types, constants or templates.WARNING! This is an experimental feature and the {cpp} compiler may report misleading error messages that refer to totally wrong (e.g. non-existent) TTCN–3 line numbers. In these cases please turn off this flag, repeat the compilation and analyze the generated code manually. Without this flag, the compiler also inserts the source code information for the better understanding of {cpp} error messages, but only as {cpp} comments. This option has no impact on the run-time performance of the generated code. The compiler performs full semantic analysis on its entire input; it normally does not generate erroneous {cpp} code. So this option became obsolete and will be removed in future versions.
Instructs the compiler to generate source file and line information (that is, #line directives) into the output code so that the error messages of the {cpp} compiler refer back to the lines of the original TTCN–3 input module. This makes finding the reason of {cpp} error messages easier. This option has effect only in the equivalent {cpp} code of TTCN–3 functions, test cases and control parts and this feature is not provided in other TTCN–3 definitions such as types, constants or templates.WARNING! This is an experimental feature and the {cpp} compiler may report misleading error messages that refer to totally wrong (e.g. non-existent) TTCN–3 line numbers. In these cases please turn off this flag, repeat the compilation and analyze the generated code manually. Without this flag, the compiler also inserts the source code information for the better understanding of {cpp} error messages, but only as {cpp} comments. This option has no impact on the run-time performance of the generated code. The compiler performs full semantic analysis on its entire input; it normally does not generate erroneous {cpp} code. So this option became obsolete and will be removed in future versions.
* `-L`
+
......@@ -762,7 +762,7 @@ The `makefilegen` tool allows the usage of code splitting mechanisms when genera
Let "number" be equal to 4 for this example. We want to split the files into four pieces.
Firstly, TITAN finds the TTCN3 module whose C\++ generated code will be the largest. In this example, it will be 10000 characters (let’s call it MAX). So the largest generated {cpp} module contains 10000 characters.
Firstly, TITAN finds the TTCN3 module whose {cpp} generated code will be the largest. In this example, it will be 10000 characters (let’s call it MAX). So the largest generated {cpp} module contains 10000 characters.
Secondly TITAN calculates the splitting threshold by dividing MAX with "number", so it will be 10000 / 4 = 2500 in this case. TITAN will only split the generated c++ files which are larger than 2500 characters.
......
This diff is collapsed.
......@@ -13,9 +13,9 @@ The main components are the following:
* The *Test Port(s)*, which facilitate the communication between the TTCN–3 Test System and the System Under Test (SUT).
The generated C\++ modules as well as the Test Ports should be compiled to binary object code and linked together with the Base Library using a traditional {cpp} compiler.
The generated {cpp} modules as well as the Test Ports should be compiled to binary object code and linked together with the Base Library using a traditional {cpp} compiler.
All parts, except the protocol specific Test Ports, are included in the binary package of the Test Executor. The Test Executor is a protocol and platform independent tool that can be easily adapted to any kind of protocols by writing the appropriate Test Port. The generated C\++ code is exactly the same on all platforms, provided that the pre-compiled Base Library that matches the operating system and {cpp} compiler is used. The Test Port may use operating system calls or external library functions for sending or receiving messages towards System Under Test so it may become platform dependent.
All parts, except the protocol specific Test Ports, are included in the binary package of the Test Executor. The Test Executor is a protocol and platform independent tool that can be easily adapted to any kind of protocols by writing the appropriate Test Port. The generated {cpp} code is exactly the same on all platforms, provided that the pre-compiled Base Library that matches the operating system and {cpp} compiler is used. The Test Port may use operating system calls or external library functions for sending or receiving messages towards System Under Test so it may become platform dependent.
Writing a Test Port is not an easy task for the first time, but the Compiler alleviates it by generating an empty skeleton for each function to be written. This skeleton is also useful for checking the correctness of an existing test suite because the Executable Test Program can be linked with this empty Test Port. In this case the resulting program actually does nothing, but the successful linking means that no modules or functions are missing from the test suite.
......
......@@ -39,7 +39,7 @@ In this case simply issue the command `*make MyModule.o*` and the two translatio
=== Rules for Modular Test Suites
The compiler supports modular TTCN–3 test suites as well. Each module is translated to a separate C\++ header and source file. These source files can be compiled by the {cpp} compiler one-by-one separately.
The compiler supports modular TTCN–3 test suites as well. Each module is translated to a separate {cpp} header and source file. These source files can be compiled by the {cpp} compiler one-by-one separately.
The importing mechanisms work in the following way. For example, two TTCN-3 modules are present in files `A.ttcn` and `B.ttcn`, respectively. Definitions of module A may be used from module B, so the `import from A all`; statement must be added to module B. The modules A and B *must* be translated by the compiler in one step to `A.cc`, `A.hh`, `B.cc` and `B.hh`. During the compilation from TTCN–3 to {cpp} of module B, the import statement will be translated to `#include "A.hh"`. This statement will be put to the beginning of `B.hh`, so you can refer to any definitions of A in module B. But note that when compiling `B.cc`, `A.hh` must exist and it must be up to date.
......@@ -107,11 +107,11 @@ If the `Makefile` generator ensured that the file is neither a TTCN–3 nor an A
The remaining files (configuration files and so on) will be added to the other files’ section of the `Makefile`. These files do not take part in the build process, but they are added to the archive files created using the `Makefile`.
After the classification, the `Makefile` generator filters out the redundant generated C\++ files. If a given C/{cpp} file was found to be generated from one of the given TTCN–3 or ASN.1 modules, a warning is printed and the file will be dropped from the list of C/{cpp} files. That is, the file will not be added to the list of user source files since it is already a member of the generated sources. This feature is useful if one wants to regenerate the `Makefile` using the shell wildcard `*.cc` while the generated files from the previous compilation are still present.
After the classification, the `Makefile` generator filters out the redundant generated {cpp} files. If a given C/{cpp} file was found to be generated from one of the given TTCN–3 or ASN.1 modules, a warning is printed and the file will be dropped from the list of C/{cpp} files. That is, the file will not be added to the list of user source files since it is already a member of the generated sources. This feature is useful if one wants to regenerate the `Makefile` using the shell wildcard `*.cc` while the generated files from the previous compilation are still present.
In the next step the algorithm tries to complete the list of C/C\++ files by checking the pairs of header and source files. If a C/{cpp} source file was identified and a header file with the same name exists (only the suffix differs) too, the `Makefile` generator will add the header file automatically. This step is performed in the reverse direction too: the `Makefile` generator can find an existing source file based on the header file given to it. Of course a {cpp} source file can exist without a header file or vice versa.
In the next step the algorithm tries to complete the list of C/{cpp} files by checking the pairs of header and source files. If a C/{cpp} source file was identified and a header file with the same name exists (only the suffix differs) too, the `Makefile` generator will add the header file automatically. This step is performed in the reverse direction too: the `Makefile` generator can find an existing source file based on the header file given to it. Of course a {cpp} source file can exist without a header file or vice versa.
The `Makefile` generator continuously checks the uniqueness of files and module names. If the same file was given more than once in the command line the repeated argument is simply ignored and a warning message is displayed. It is not allowed to use two or more different TTCN–3 or ASN.1 files containing modules with the same name because the generated C\++ files would clash. For similar reasons the user C/{cpp} files cannot have identical names even if they are located in different directories.
The `Makefile` generator continuously checks the uniqueness of files and module names. If the same file was given more than once in the command line the repeated argument is simply ignored and a warning message is displayed. It is not allowed to use two or more different TTCN–3 or ASN.1 files containing modules with the same name because the generated {cpp} files would clash. For similar reasons the user C/{cpp} files cannot have identical names even if they are located in different directories.
Finally the `Makefile` is generated based on the resulting data. If the `Makefile` generator finds an existing `Makefile` in its working directory, it will not be overwritten unless the option `-f` is used.
......@@ -147,7 +147,7 @@ The central directories should contain those common modules that do not change f
In addition to the above mentioned ones the following assumptions are used in these `Makefiles`:
* The compiler will generate C\++ files only for those TTCN–3 and ASN.1 modules that are located in the current working directory. The generated {cpp} files of the remaining TTCN–3 and ASN.1 modules should be located in the same directory as the respective module. If a module is located in a directory other than the current working directory and it does not have pre-compiled files a symbolic link must be created in the current working directory, which should point to the file containing the module.
* The compiler will generate {cpp} files only for those TTCN–3 and ASN.1 modules that are located in the current working directory. The generated {cpp} files of the remaining TTCN–3 and ASN.1 modules should be located in the same directory as the respective module. If a module is located in a directory other than the current working directory and it does not have pre-compiled files a symbolic link must be created in the current working directory, which should point to the file containing the module.
* Object and if applicable, shared object files will be created only from those C/{cpp} source files that are located in the current working directory. Object and if applicable, shared object files of the remaining source files should be located in the same directory as the respective source file.
......@@ -163,7 +163,7 @@ Note that when a pre-compiled TTCN–3 or ASN.1 module is taken from a central d
* The module itself when performing the semantic analysis on the local modules importing it.
* The generated C\++ header file when compiling the generated {cpp} files of the importing modules.
* The generated {cpp} header file when compiling the generated {cpp} files of the importing modules.
* The object and if applicable, the shared object file when linking the executable.
......@@ -359,14 +359,14 @@ Removes all generated files (generated {cpp} files, object and TITAN generated s
* `*make compile*`
+
Translates the TTCN–3 and ASN.1 modules to C\++. It is useful when the user wants to carry out the compilation of the generated {cpp} code later. As a result, an empty file named `compile` is created in the working directory. The attributes of this file contain the date and time of the last compilation, which helps the compiler in selective code generation. It is not recommended to change this file manually. The compiler will be invoked only if one or more of the TTCN–3 or ASN.1 modules were modified after that timestamp, otherwise the generated {cpp} files are up to date.
Translates the TTCN–3 and ASN.1 modules to {cpp}. It is useful when the user wants to carry out the compilation of the generated {cpp} code later. As a result, an empty file named `compile` is created in the working directory. The attributes of this file contain the date and time of the last compilation, which helps the compiler in selective code generation. It is not recommended to change this file manually. The compiler will be invoked only if one or more of the TTCN–3 or ASN.1 modules were modified after that timestamp, otherwise the generated {cpp} files are up to date.
* `*make diag*`
+
Lists general information about the environment and the build. This information can be useful to fix build problem by the developers or the support team. The output contains: +
- the compiler related information (titan version, build date, C\\++ version, license information, see command `*"compiler –v"*`), +
- main controller related information (titan version, {cpp} compiler version, build date, license information, see command `*"mctr_cli –v"*`), +
- C\++ compiler information (see command `*"g++ -v"*`), +
- {cpp} compiler information (see command `*"g++ -v"*`), +
- library creator info ( see command `*"ar –v"*`), +
- values of environment variables `$TTCN3_DIR`, ``$ OPENSSL_DIR`, `$XML_DIR`, `$PLATFORM`.
......@@ -463,13 +463,13 @@ This section contains information useful for the experienced users who are using
=== Compiling the Generated {cpp} Code
If the TTCN–3 test suite was successfully translated to C\++, it’s a good idea to check if the generated code contains any errors. The simplest way is to compile it using a {cpp} compiler. Since the generated code refers to the base library, run the following command:
If the TTCN–3 test suite was successfully translated to {cpp}, it’s a good idea to check if the generated code contains any errors. The simplest way is to compile it using a {cpp} compiler. Since the generated code refers to the base library, run the following command:
[source, subs="+quotes"]
*g++ -c -I$TTCN3_DIR/include -Wall MyModule.cc*
In the following, using of an GNU C\++ compiler is assumed. If the TTCN–3 /ASN.1 compiler did not report any errors in the input test suite, the generated {cpp} code must be correct (that is, compile without errors). After certain TTCN–3 warnings (such as unreachable statements) the generated code may trigger similar warnings in the {cpp} compiler.
In the following, using of an GNU {cpp} compiler is assumed. If the TTCN–3 /ASN.1 compiler did not report any errors in the input test suite, the generated {cpp} code must be correct (that is, compile without errors). After certain TTCN–3 warnings (such as unreachable statements) the generated code may trigger similar warnings in the {cpp} compiler.
The generated code has been tested on various versions of GNU C\++ and Sun Workshop {cpp} compilers. However, the code should work with any standard-compliant C\++ compiler since it does not depend on hardware or compiler specific features. If the generated code fails to compile on a supported platform and {cpp} compiler the situation is considered as a compiler bug and a Trouble Report can be issued footnote:[The Trouble Report must include the compiler error message(s), all input files and command line switches of the TTCN–3 /ASN.1 compiler, the platform and the exact version of TITAN TTCN–3 Test Executor and the {cpp} compiler. It is highly appreciated if the user could minimize the input by dropping out irrelevant modules and definitions.].
The generated code has been tested on various versions of GNU {cpp} and Sun Workshop {cpp} compilers. However, the code should work with any standard-compliant {cpp} compiler since it does not depend on hardware or compiler specific features. If the generated code fails to compile on a supported platform and {cpp} compiler the situation is considered as a compiler bug and a Trouble Report can be issued footnote:[The Trouble Report must include the compiler error message(s), all input files and command line switches of the TTCN–3 /ASN.1 compiler, the platform and the exact version of TITAN TTCN–3 Test Executor and the {cpp} compiler. It is highly appreciated if the user could minimize the input by dropping out irrelevant modules and definitions.].
The switch `-c` tells the GNU {cpp} compiler to compile only and not to build an executable because, for example, the `main` function is missing from the generated code. The switch `-I` adds the `$TTCN3_DIR/include` directory to the compiler’s standard include path. The optional argument, `-Wall`, forces the compiler to report all warnings found in its input. This argument can be used in GCC only.
......
......@@ -294,7 +294,7 @@ The script returns different exit codes which can be used by user written softwa
== Strange Behavior of the Executable
If modular test suites are executed, sometimes the executable test program can do strange things, for example, the execution terminates without any reason or the send functions of the Test Port is not called, and so on. This is because out-of-date C\++ header files are used for translating the {cpp} modules, that is, there is a wrong `Makefile`.
If modular test suites are executed, sometimes the executable test program can do strange things, for example, the execution terminates without any reason or the send functions of the Test Port is not called, and so on. This is because out-of-date {cpp} header files are used for translating the {cpp} modules, that is, there is a wrong `Makefile`.
This may happen when the Test Port files are renamed, so the compiler regenerates them. Thus the {cpp} source files generated by the compiler see an empty Test Port header file, but the fully functional Test Port object file is linked to the executable. In this case, the linking will be successful, but during the execution strange things can happen. The reason behind this phenomenon is that the modules consider the raw binary structure of the same {cpp} class different, for example they fetch the virtual function pointer from a wrong place.
......
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