Explaining the DATAFLOW Code Generator Functionalities
This Guide Article has been written for Version 2.1 of the DATAFLOW Software. For Previous Releases use the version selection in the navigation bar at the top of this page.
Introduction
Purpose and Scope
This document describes the functionality of the DATAFLOW Code generator. This includes basic functionality, configuration and the command line interface.
The document has been written for developers that want to generate code using the generator by writing the DSL files by hand as well as for developers of the DATAFLOW Designer software. Please refer to the Tech Note for DATAFLOW Designer [1] if the generator is used in conjunction with that software.
It is assumed that the reader of the documentation is familiar with the DATAFLOW Architecture and terms such as Active Part, Protocols and the DATAFLOW Runtime, which are explained in [2].
Referenced Versions
The Tech Note has been written based on the following versions:
DATAFLOW Code Generator: Version 2.2.1
Conventions used in this document
Command line: All command line examples are written with a mono space font and are highlighted with a gray background:
$ DffStudio.App.Generator.exe [arguments]
Syntax: All syntax DSL and configuration examples are written with a mono space font and are highlighted with a green background:
import "LegacyAPC.dff"
startupController (root:Legacy) {
}
There are few special characters used in the syntax sections:
Usage |
Notation |
Alternation |
| |
Special sequence |
< … > |
Notes: Important remarks are highlighted with a blue background:
NOTE This is an example note. |
Document Overview
This document contains the following parts:
2 Overview Explains the concepts of the DATAFLOW Code Generator.
3 Basic Functionality Explains the functionality of the DATAFLOW Code Generator.
4 Installation Explains the installation of the code generator.
5 Usage Contains step by step explanation of common use scenarios.
Overview
The DATAFLOW Code Generator is a command line utility that generates source code for types[1] and components[2] from the DATAFLOW DSL[3] Language. Using the generator allows the developer to focus on implementation at the level of component behavior instead of writing containers, connecting channels and serializing and de-serializing protocols. Because the generated code does not contain the typical errors made by a developer writing those classes by hand, it also reduces the risk of errors in the software.
Separation of generated code from user code
The generator generates two types of source code files:
- Auto-Generated files. These files will always be overwritten upon generation. The user MUST NOT change these files in any way.
- Handler files. These files are generated once for the user to fill in the behavior of the class. The generator will not overwrite existing handler files if it is not forced to do so in the generator configuration (see below).
Namespaces
The generator will create a folder for each namespace and place the generated classes and tests inside it.
For the root namespace, no folder is created when C++ code is generated. The creation of the root namespace folder can be forced in the generator configuration (see below).
In the configuration, the root namespace can be defined. The DSL syntax makes it possible to define a sub namespace for every generated type and component.
- This feature has not been validated for the current release. Use it at your own risk.
Verification of the code
The generator has been validated by DATAFLOW Software to ensure that a given DSL input will always result in the same generated source code. DATAFLOW Software cannot guarantee that the toolchain used to compile and link the source code will not produce any issues.
All generated code fulfills all known static code analysis requirements (e.g., MISRA C++).
Basic Functionality
The generator is able to generate protocols with the required identifiers and enumerations. It also generates Active Parts, Active Containers, Active Interrupts and startup controllers. All of those are explained in the following chapters.
Protocol
The generator is able to generate protocols. A protocol is a class with a number of fields that can be serialized to a byte stream and also de-serialized from a received byte stream. The generated class implements the Serializable interface from the Imt.Base library.
This makes it possible to send messages over any serial communication channel. It is also required to send messages in the DATAFLOW runtime. All generated protocol implementations are byte compatible over all generated languages. This means a message serialized with one language and de-serialized with another language using the same protocol contains the same fields as before serialization.
NOTE Every protocol must have an unique identifier assigned (see below). |
Protocol Generation
Protocol Fields
A protocol consists of fields. Each field can have one of the following basic types:
Type |
Bytes |
Default |
Min |
Max |
Description |
int8 |
1 |
0 |
–(28) / 2 |
((28) / 2) - 1 |
|
int16 |
2 |
0 |
–(216) / 2 |
((216) / 2) - 1 |
|
int32 |
4 |
0 |
–(232) / 2 |
((232) / 2) - 1 |
|
int64 |
8 |
0 |
–(264) / 2 |
((264) / 2) - 1 |
|
uint8 |
1 |
0U |
0 |
28 - 1 |
|
uint16 |
2 |
0U |
0 |
216 - 1 |
Default for identifier (DATAFLOW Runtime) |
uint32 |
4 |
0U |
0 |
232 - 1 |
|
uint64 |
8 |
0U |
0 |
264 - 1 |
|
bool |
1 |
false |
0 |
1 |
false, 1 - true |
char |
1 |
0U |
0 |
255 |
|
float32 |
4 |
0.0F |
3.4E +/- 38 (7 digits) |
|
single-precision 32-bit IEEE 754 floating point |
float64 |
8 |
0.0 |
1.7E +/- 308 (15 digits) |
|
double-precision 64-bit IEEE 754 floating point |
enum |
1-4 |
0 |
- |
- |
Size is based on type used for the enum Default: int32 = 4 bytes |
string |
* |
- |
- |
- |
Size is based on the number of characters in the string (no terminator) |
protocol |
* |
- |
- |
- |
Size is based on the used Protocol |
Protocol Fields
There is no limit on the number of nesting levels created when the protocol field is used. Be aware that the size of the resulting protocol may exceed the maximum message size defined in the DATAFLOW Runtime. Also note that protocols do not support recursion. The generation of a custom controller, where the field values can be given as arguments, must be limited in the generator configuration. If the number of fields exceeds the CustomCtorMaxArgs parameter, no such constructor is generated (there is only a default and a copy constructor). |
Any field can also be declared as an array instead of a scalar value. This includes enums and nested protocols.
Identifier
The generator generates constants for the protocol identifiers, which are used to identify the sent message type in the byte stream in order for the receiver to know which protocol must be used to de-serialize the received message.
Identifier Generation
Signals
The generator also supports signals. These are identifiers with no protocol assigned to them.
They are used in the DATAFLOW runtime to send a message with no fields by passing NULL as a second argument to the write method on a PortOutput in the Imt.Base.Dff.ActiveParts library.
Enumeration
For each defined enumeration, a type safe enumeration with range constants is generated. This makes it possible to iterate over the values and get the minimal and maximum values. Enumerations can be used directly in the code or as fields in protocols.
Enumeration Generation
Active Part
For each Active Part defined, the following is generated:
- main class
- interface
- handler
- unit test
Active Part Generation
Main class
The main class instantiates all output ports and timers that have been defined. It also implements the generated interface (see below) and creates the instance of the handler. The defined name, priority, stack size and time slice are also passed to the runtime in the constructor.
Interface
The interface contains a type safe send method for every protocol assigned to a port. This method will send the message over the correct port using the correct identifier.
For ports with no protocol, a generic send method is created that takes a protocol identifier and a serializable interface. A getter method is created for every timer so that the handler or any of its children can access them.
handler
The handler contains an empty method for every protocol assigned to the input port and for every timer event. It receives a reference to the interface as a constructor parameter. The developer should implement the behavior of the Active Part in the handler methods. It is also possible to add additional classes like state machines and pass the interface to them.
Since V2.1, the handler can also be replaced with C style functions. These are assigned to certain events and will then be called by the main class when this event occurs. The generated interface is passed as an argument to these methods.
Unit Test
The generated test makes sure that the priority of the Active Part is set as defined.
Tests for behavior must be either added to this file or provided in a separate file.
If the tests are added to the same file the generator should not overwrite existing test classes. This can be achieved by NOT setting the following command line argument: OverwriteTests:
(See also 5.1).
Active Interrupt
For each Active Interrupt defined, the following is generated:
- main class
- interface
- handler
- unit test
Interrupt Active Part Generation
Main class
The main class instantiates all output ports that have been defined. It also implements the generated interface (see below) and creates the instance of the handler. The interrupt handler methods are also created with the defined name. A static instance of the class is created so that it can be accessed from the handler. The implementation will call applicationIsrEntry, the handler method and applicationIsrExit of the DATAFLOW runtime.
Interface
The interface contains a type safe send method for every protocol assigned to a port. This method will send the message over the correct port using the correct identifier.
For ports with no protocol, a generic send method is created that takes a protocol identifier and a serializable interface.
Handler
The handler contains an empty method that is called whenever the interrupt occurs. It also receives a reference to the interface as constructor parameter. The developer should implement the behavior of the interrupt Active Part in the handler methods.
Unit Test
The generated test makes sure that generated interrupt handler calls the enter/exit interrupt methods of the runtime.
Tests for behavior must be either added to this file or provided in a separate file.
If the tests are added to the same file the generator should not overwrite existing test classes. This can be achieved by NOT setting the following command line argument: OverwriteTests: (See also 5.1).
Active Part Container
For each Active Part container defined, the following is generated:
- main class
- unit test
Active Container Generator
Main class
The main class instantiates all children of the container (other containers, Active Parts and interrupt Active Parts). It also contains references to the port of those children so that they can be accessed from outside of the container. All channels between children of the container are created and connected.
Unit Test
The test verifies that
- all channels are connected as defined
- all connectors reference the defined port
- Each child is initialized on initialization of the container
- Each child is started on start of the container
Startup Controller
For each startup controller defined, the following is generated:
- main class
Startup Controller Generator
Main class
The main class contains the application main method. There must not be more than one startup controller per application.
The generated startup controller performs the following:
- Register assertion handlers for ASSERT_EX and ASSERT_DEBUG
- Initialize static Application class (from BSP)
- Instantiate given root APC
- Call Application.run and pass root APC instance.
- Trigger ASSERT_EX when run exits (must not happen).
Supported Languages
The current Code-Generator version supports the languages listed in the table below. Please note that not every feature is available for every language in the current version. If required by a certain project, additional features or languages can be added in newer versions.
Feature |
C++ |
C++ 11 |
C++ 14 |
Generate Protocols |
X |
X |
X |
Generate Software Components |
X |
X |
X |
Generate Startup Code |
X |
X |
X |
Generate Unit Tests |
X |
X |
X |
Trailing Return Types (optional) |
|
X |
X |
Use nullptr instead of NULL |
|
X |
X |
Use enum class |
|
X |
X |
Use auto for local variables |
|
X |
X |
Private unimplemented copy operators and default constructors. |
X |
|
|
Delete copy operators and constructors. |
|
X |
X |
Supported Features by Language
Installation
The DATAFLOW Code Generator is part of the DATAFLOW Designer installation explained in the DATAFLOW Designer Tech Note [1].
Release Notes
The up-to-date release notes for all released generator versions can be found in [4].
Licensing
The DATAFLOW Code Generator requires a DATAFLOW License with enabled code generation option. When the generator is used from within DATAFLOW Designer, the same license is used for the generator as well.
If the generator is used on the command line, the user must make sure that he signs in with a valid DATAFLOW user first.
Usage
The Generator is usually called directly from DATAFLOW Designer. If it is used from the command line, then it is recommended to create a batch file. This file calls the Generator and passes one or more DSL files and the configuration directory to be used.
@ECHO OFF |
This batch file can then be configured as a pre-build process in your favorite IDE.
CLI Arguments
The code generator is controlled using a command line interface (CLI). The following table shows all supported arguments. The arguments are case insensitive.
Argument |
Description |
-Help |
Prints a help message with all arguments and then exits. |
-Version |
Prints the version of the Code Generator and then exits. |
-SignIn <user> <password> <environment> |
Signs in a valid DATAFLOW user. |
-SignOut |
Signs the current user out. |
-SourceFile [path] |
One or more DSL input files. |
-ConfigDir [path] |
Path to the configuration folder from which the configuration files are read (see below). |
-CmdFormat [dataflow|standalone] |
standalone – Generator produces user friendly CLI output DATAFLOW – Generator produces parser friendly output for integration in DATAFLOW Designer. |
-OverwriteHandlers |
Overwrites all existing handler classes with user-specific code. See Chapter 2.1 for details. |
-OverwriteTests |
Overwrites all existing unit test files. See Chapter 2.1 for details. |
-User [name] |
Username to be injected into the generated file header. |
CLI Arguments
Example output with no arguments
$ ./DffStudio.App.Generator.exe
DffStudio.App.Generator - Version 2.1.1.0
Usage: DffStudio.App.Generator[arguments]
Arguments:
-Help Displays this message and exits.
-Version Displays the version and exits.
-SourceFile [path] Defines the input file (mandatory).
-ConfigDir [path] Defines the config directory (optional, defaults
to working directory).
-CmdFormat [dataflow|standalone] Defines the output format (optional,
defaults to standalone).
-OverwriteHandlers Overwrites APHandler files.
-OverwriteTests Overwrites UnitTest files.
-Verbose Enables additional output
-SignIn [Email] [Password] [Server] Signs in to execute DATAFLOW Generator.
-SignOut Signs out the current user from all dataflow applications.
-User The username that is used to overwrite the
logged-in user’s e-mail address.
Configuration
The configuration is read from the given configuration folder or from the working directory, if not specified. The following configuration files are supported:
- Generator configuration
- Parser configuration
- Style configuration
- File header templates
Generator Configuration
The generator configuration controls the code generation. Changes to those parameters will lead to a change of functionality in the generated code. For all omitted parameters, the default value given below is used.
File: generator.json
Version: 4
Parameter |
Type |
Default |
Remarks |
Language |
Enum |
CPP98 |
An unsupported value is interpreted as the default value. |
Platform |
Enum |
WIN32 |
An unsupported value is interpreted as the default value. |
Runtime |
Enum |
WIN32 |
An unsupported value is interpreted as the default value. |
RuntimeVersion |
Version |
2.4 |
An unsupported value is interpreted as the default value. |
RootNamespace |
Namespace |
‘dataflow’ |
See ‘Namespaces’. |
ComponentNamespace |
Namespace |
‘’ |
See ‘Namespaces’. |
TypeNamespace |
Namespace |
‘’ |
See ‘Namespaces’. |
GenerateSrc |
Bool |
True |
See ‘Generate Flags’. |
GenerateTests |
Bool |
True |
See ‘Generate Flags’. |
RootPathSrc |
Path |
‘App’ |
See ‘File Paths’. |
RootPathTests |
Path |
‘Unittest’ |
See ‘File Paths’. |
RootPathMeta |
Path |
‘..\meta’ |
See ‘File Paths’. |
ReadOnly |
Bool |
False |
All generated files are set to read only in the file system. This does not affect handler files. |
CustomCtorMaxArgs |
UInt |
5 |
See protocol generation. |
TestCategoryProtocol |
String |
Software Unit |
See ‘Test Categories’. |
TestCategoryAP |
String |
Software Unit |
See ‘Test Categories’. |
TestCategoryAPC |
String |
Software Integration |
See ‘Test Categories’. |
TestCategoryAPIrq |
String |
Software Unit |
See ‘Test Categories’. |
CppExportTypesToGlobalNamespace |
Bool |
True |
Makes it possible to disable any declarations that are used in header files. |
CppFolderForRootNamespace |
Bool |
False |
See file paths. |
CppTestFramework |
Enum |
MICROSOFT_UNIT_ TEST_FRAMEWORK |
An unsupported value is interpreted as the default value. |
Cpp11TrailingReturnType |
Bool |
False |
Uses the trailing return type for methods in C++11 or newer. |
Generator Configuration Parameters
Example of a Generator Configuration
{
"GeneratorOptions": {
"Version": 4,
"Data": {
"Language": "CPP98",
"Platform": "STM32_F103_HD",
"Runtime": "ARM_CORTEX_M3",
"RuntimeVersion": "2.5",
"RootNamespace": "dataflow.example",
"ComponentNamespace": "components",
"TypeNamespace": "protocols",
"GenerateTests": true,
"RootPathSrc": "src/MyApp/App",
"RootPathTests": "src/MyApp/Unittest",
"CppFolderForRootNamespace": true,
"CustomCtorMaxArgs": 3
}
}
}
Language
The following values are supported for the Language parameter:
Value |
Effect |
Remarks |
CPP98 |
C++ 98 Code is generated according to SO/IEC 14882:1998 |
Affects all generated files |
CPP11 |
C++ 11 Code is generated according to SO/IEC 14882:2011 |
Affects all generated files (2) |
CPP14 |
C++ 14 Code is generated according to SO/IEC 14882:2014 |
Affects all generated files (2) |
This parameter can also be printed in the file header. See ‘File Header Templates’.
Additional languages may be added for future versions.
Platform
The following values are supported for the Platform parameter:
Value |
Effect |
Remarks |
AM3354 |
(1) |
Bare metal HAL for TI AM3354 (ARM Cortex-A8 (2) |
EMBOS |
(1) |
ROS abstraction layer for Embos real time operating system. (2) |
MIDCORE |
(1) |
ROS abstraction layer for Midcore real time operating system. (2) |
NIOS2_CORE |
(1) |
Bare metal HAL for Intel/Altera NIOSII Core. (2) |
QNX |
(1) |
OS abstraction layer for QNX operating system. |
STM32_F030 |
(1) |
Bare metal HAL for STM32F030 (ARM Cortex-M0) |
STM32_F103_MD |
(1) |
Bare metal HAL for STM32F103 (ARM Cortex-M3) Medium Density Variant |
STM32_F103_HD |
(1) |
Bare metal HAL for STM32F103 (ARM Cortex-M3) High Density Variant |
STM32_F767 |
(1) |
Bare metal HAL for STM32F767 (ARM Cortex-M7) |
WEC7 |
(1) |
OS abstraction layer for Windows Embedded Compact 7 operating system. (2) |
WIN32 |
(1) |
OS abstraction layer for 32bit Windows operation system. |
1) Startup controller is adapted to platform.
2) This feature has not been validated for the current release. Use it at your own risk.
This parameter can also be printed in the file header, see ‘File Header Templates’.
Additional platforms may be added for future versions.
Runtime
The following values are supported for the Runtime parameter:
Value |
Effect |
Remarks |
ARM_CORTEX_A8 |
(1) |
Bare metal runtime for ARM Cortex-A8 architecture. (2) |
ARM_CORTEX_A9 |
(1) |
Bare metal runtime for ARM Cortex-A9 architecture. (2) |
ARM_CORTEX_M0 |
(1) |
Bare metal runtime for ARM Cortex-M0 architecture. |
ARM_CORTEX_M3 |
(1) |
Bare metal runtime for ARM Cortex-M3 architecture. |
ARM_CORTEX_M7 |
(1) |
Bare metal runtime for ARM Cortex-M7 architecture. |
EMBOS |
(1) |
RTOS runtime to run on Embos RTOS. |
MIDCORE |
(1) |
RTOS runtime to run on Midcore RTOS. (2) |
NIOS2 |
(1) |
Bare metal runtime for Intel/Altera NISO2 soft core. (2) |
QNX |
(1) |
OS Runtime for QNX operation system. (2) |
WEC7 |
(1) |
OS Runtime for Windows Embedded Compact 7 operation system. (2) |
WIN32 |
(1) |
OS Runtime for 32 Bit Windows operation system. |
1) Startup controller is adapted to runtime type.
2) This feature has not been validated for the current release. Use it at your own risk.
This parameter can also be printed in the file header. See ‘File Header Templates’.
Additional runtime types may be added for future versions.
- RuntimeVersion
The RuntimeVersion parameter must define the major version of the supported runtime in the format ‘X.Y’. This will affect the generation of the startup controller. This parameter can also be printed in the file header. See ‘File Header Templates’.
- Namespaces
The generator configuration allows you to define the namespace for all generated types and components. Each component can also add a sub namespace in its DSL description.
The final namespace of a component is defined as follows:
RootNamespace + ComponentNamespace + DSL Namespace
The final namespace of a type is defined as follows:
RootNamespace + TypeNamespace + DSL Namespace
- Generate Flags
The generator only generates source files (for both types and components) when the GenerateSrc parameter is set to true.
The generator only generates unit test files (for both types and components) when the GenerateTests parameter is set to true.
- File Paths
The generator will place each generated file at the configured location. The path can be configured individually for source, test and meta files.
The path for a source file is defined as follows:
RootPathSrc + Full Namespace (see above)
The path for a test file is defined as follows:
RootPathTests + Full Namespace (see above)
The path for a meta file is defined as follows:
RootPathMeta
NOTE: For C++, the first part of the root namespace is not used in the path unless CppFolderForRootNamespace is set to true. |
- C++ Test Framework
Defines the unit test framework for all generated C++ unit tests.
The following values are supported for the CppTestFramework parameter:
Value |
Effect |
Remarks |
MICROSOFT_UNIT_ TEST_FRAMEWORK |
(1) |
Tests will run on the MSTest framework V1.3 from Microsoft. |
1) All C++ unit tests are generated for the given unit test framework.
- Test Categories
If supported by the configured test framework (see above), each generated unit test will be added to the given category using an attribute or similar mechanic of the test framework. The category can be specified for each generated artifact independently using the parameters TestCategoryProtocol, TestCategoryAP, TestCategoryAPC and TestCategoryAPIrq.
- C++ Specific configuration
When the Language is set to C++11 or newer, the Cpp11TrailingReturnType parameter will enable the generation of trailing return types in the form:
auto method(int8_t arg) -> int32_t;
If set to false, the C++98 style is used:
int32_t method(int8_t arg);
Functions with the return type void are not affected.
The parser configuration controls the DSL parser. For all omitted parameters, the default value given below is used.
File: parser.json
Version: 1
Parameter |
Type |
Default |
Remarks |
FrameworkDirectories |
Path List |
Empty |
Allows for importing DSL files from other projects. |
Table 5 - Parser Configuration Parameters
Example Parser Configuration
{ "ParserOptions": { "Version": 1, "Data": { "FrameworkDirectories": ["../Imt.Base","C:\\src\\imt\\Imt.Base"] } } } |
The generator configuration controls the generated coding style. Changes of those parameters will not change the functionality in the generated code. For all omitted parameters, the default value given below is used.
File: style.json
Version: 3
Parameter |
Type |
Default |
Remarks |
BraceStyle |
Enum |
KR |
See ‘Brace Style’. |
LineEndings |
Enum |
WIN |
See ‘Line Endings’. |
IndentWithTabs |
Bool |
False |
See ‘Indentations’. |
IndentCount |
UInt |
4 |
See ‘Indentations’. |
IndentAccessSpecifiers |
UInt |
0 |
See ‘Indentations’. |
IndentBraces |
UInt |
0 |
See ‘Indentations’. |
IndentBlockContents |
UInt |
1 |
See ‘Indentations’. |
IndentCaseContents |
UInt |
1 |
See ‘Indentations’. |
IndentCaseLabel |
UInt |
1 |
See ‘Indentations’. |
IndentClassContents |
UInt |
1 |
See ‘Indentations’. |
IndentInitializerLists |
UInt |
1 |
See ‘Indentations’. |
IndentNamespaceContents |
UInt |
0 |
See ‘Indentations’. |
AlignEnumValues |
Bool |
False |
Aligns all enumerator values on the same line for generated enums. See ‘Indentations’. |
BracePadding |
Flags |
BEFORE_OPEN AFTER_CLOSE |
See ‘Padding Flags’. |
BracketPadding |
Flags |
INSIDE_AFTER |
See ‘Padding Flags’. |
ParenthesesPadding |
Flags |
INSIDE_AFTER |
See ‘Padding Flags’. |
KeywordPadding |
Flags |
INSIDE_BEFORE INSIDE_AFTER |
See ‘Padding Flags’. |
OperatorPadding |
Flags |
INSIDE_BEFORE INSIDE_AFTER |
See ‘Padding Flags’. |
InitializerPadding |
Flags |
BEFORE_OPEN INSIDE_AFTER |
See ‘Padding Flags’. |
HeaderFileHeaderTemplate |
File Path |
‘header.tmpl’ |
See ‘File Header Templates. |
SourceFileHeaderTemplate |
File Path |
‘source.tmpl’ |
See ‘File Header Templates. |
TestFileHeaderTemplate |
File Path |
‘test.tmpl’ |
See ‘File Header Templates. |
CppDocStyle |
Enum |
JAVADOC |
See ‘Documentation Style’. |
CppStaticCheckExcludes |
Enum |
NONE |
See ‘Static Check Excludes. |
CppForceNewlineAfterInitializerList |
Bool |
False |
See ‘Brace Style’. |
Table 6 - Style Configuration Parameters
Example Style Configuration
{ "StyleOptions": { "Version": 3, "Data": { "BraceStyle": "IMT", "IndentWithTabs": true, "IndentCount": 2, "HeaderFileHeaderTemplate": "./header.tmpl", "SourceFileHeaderTemplate": "./header.tmpl", "TestFileHeaderTemplate": "./header.tmpl", "CppDocStyle": "JAVADOC" } } } |
- Brace Style
The following values are supported for the BraceStyle parameter:
Value |
Effect |
Remarks |
ALLMAN |
Opening and closing brace on new line |
|
|
|
|
KR |
Opening brace on same line, closing brace on new line. |
Bare metal runtime for ARM Cortex-M3 architecture. |
IMT |
Like KR, but opening brace after if and else and else if on new line. |
Bare metal runtime for ARM Cortex-M0 architecture. |
Example ALLMAN
boid method(int a) { if (a == 1) { doA(); } else { doB(); } } |
Example KR
boid method(int a) { if (a == 1) { doA(); } else { doB(); } } |
Example IMT
boid method(int a) { if (a == 1) { doA(); } else { doB(); } } |
When CppForceNewlineAfterInitializerList is set to true, the opening brace after a constructor initializer list is placed on a new line while ignoring the BraceStyle parameter.
Example
BraceStyle KR, CppForceNewlineAfterInitializerList False
DeviceCommandProtocol::DeviceCommandProtocol(void) : m_boolean(false), m_character(0U) { // Nothing to do. } |
BraceStyle KR, CppForceNewlineAfterInitializerList True
DeviceCommandProtocol::DeviceCommandProtocol(void) : m_boolean(false), m_character(0U) { // Nothing to do. } |
- Line Endings
The following values are supported for the LineEnding parameter:
Value |
Effect |
Remarks |
WIN |
Line endings with <CR><LF> |
ASCII 0x0D 0x0A |
UNIX |
Line endings with <LF> |
ASCII 0x0A |
- Indentations
The code generator will write IndentCount number of spaces (ASCII 0x20) for each indention level. If IndentWithTabs is set to true, the same number of tabs (ASCII 0x0x11) will be used instead.
The number of indent levels can be configured independently for several cases:
IndentAccessSpecifiers will indent all access specifiers in C++ classes.
IndentBraces will indent braces x (x can be set by the user) times. This will not affect the contents of a block formed by the braces.
IndentBlockContents will indent the content of blocks x times. This will not affect the contents of namespaces or classes because there is a specific parameter for that.
IndentClassContents will indent the content of classes x times.
IndentCaseContents will indent the content of a case in a switch case statement x times. Note that a block inside a case is also indented with IndentBlockContents.
IndentCaseLabels will indent the case label in a switch case statement x times.
IndentNamespaceContents will indent the content of a namespace x times.
IndentInitializerLists will indent the constructor initializer list x times.
Examples
IndentCount 1
IndentWithTabs True
IndentBraceContents 0
IndentBraces: 0
IndentNamespaceContents 1
IndentCaseContents 1
IndentCaseLabels 0¨
namespace { <tab>void Unit01AP::execute(const uint16_t protocolIdentifier, Deserializer& deserializer) { <tab>switch(protocolIdentifier) { <tab>case RuntimeProtocolIdentifiers::TIMER: { <tab><tab>RuntimeTimerEvent timerEventArgs(deserializer); <tab><tab>handleTimer(timerEventArgs); <tab><tab>} <tab>break; <tab>default: <tab><tab>// Ignores all other protocols <tab><tab>ASSERT_DEBUG1(false, "Unknown protocol in Unit01AP."); <tab><tab>break; <tab>} <tab>} } |
IndentCount 2
IndentWithTabs False
IndentBraceContents 1
IndentBraces: 0
IndentNamespaceContents 0
IndentCaseContents 0
IndentCaseLabels 0
namespace { void Unit01AP::execute(const uint16_t protocolIdentifier, Deserializer& deserializer) { ˽˽switch(protocolIdentifier) { ˽˽case RuntimeProtocolIdentifiers::TIMER: { ˽˽˽˽RuntimeTimerEvent timerEventArgs(deserializer); ˽˽˽˽handleTimer(timerEventArgs); ˽˽} ˽˽break; ˽˽default: ˽˽// Ignores all other protocols ˽˽ASSERT_DEBUG1(false, "Unknown protocol in Unit01AP."); ˽˽break; ˽˽} } } |
IndentCount 2
IndentWithTabs False
IndentBraceContents 2
IndentCaseContents 0
IndentCaseLabels 1
void Unit01AP::execute(const uint16_t protocolIdentifier, Deserializer& deserializer) { ˽˽˽˽switch(protocolIdentifier) { ˽˽˽˽˽˽case RuntimeProtocolIdentifiers::TIMER: { ˽˽˽˽˽˽˽˽˽˽RuntimeTimerEvent timerEventArgs(deserializer); ˽˽˽˽˽˽˽˽˽˽handleTimer(timerEventArgs); ˽˽˽˽˽˽} ˽˽˽˽˽˽break; ˽˽˽˽˽˽default: ˽˽˽˽˽˽// Ignores all other protocols ˽˽˽˽˽˽ASSERT_DEBUG1(false, "Unknown protocol in Unit01AP."); ˽˽˽˽˽˽break; ˽˽˽˽} } |
IndentCount 2
IndentWithTabs False
IndentBraceContents 1
IndentCaseContents 1
IndentCaseLabels 1
void Unit01AP::execute(const uint16_t protocolIdentifier, Deserializer& deserializer) {
˽˽switch(protocolIdentifier) {
˽˽˽˽case RuntimeProtocolIdentifiers::TIMER: {
˽˽˽˽˽˽RuntimeTimerEvent timerEventArgs(deserializer);
˽˽˽˽˽˽handleTimer(timerEventArgs);
˽˽˽˽}
˽˽˽˽break;
˽˽˽˽default:
˽˽˽˽˽˽// Ignores all other protocols
˽˽˽˽˽˽ASSERT_DEBUG1(false, "Unknown protocol in Unit01AP.");
˽˽˽˽˽˽break;
˽˽}
}
- Padding Flags
The number and placement of spaces inside of braces, brackets and parentheses is controlled using the padding flags BracePadding, PracketPadding and ParenthesePadding.
The following flags are supported:
Value |
Effect |
Example (1) |
‘’ |
No spaces are added at all |
void method(int a,int b){ |
BEFORE_OPEN |
Before the opening character |
void method˽(int a,int b){ |
AFTER_OPEN |
After the opening character |
void method(˽int a,int b){ |
BEFORE_CLOSE |
Before the closing character |
void method(int a,int b˽){ |
AFTER_CLOSE |
After the closing character |
void method(int a,int b)˽{ |
INSIDE_BEFORE |
Before each coma separated entry except the first one. |
void method(int a, ˽int b){ |
INSIDE_AFTER |
After each coma separated entry except the last one. |
void method(int a˽,int b){ |
- The example is given for parentheses, but it will work the same way for the other paddings.
For operators and keywords, only the INSIDE_BEFORE and INSIDE_AFTER has an effect.
The flags can be combined, and there will be no more than one space at one of the possible locations.
Example
ParenthesePadding AFTER_OPEN,INSIDE_BEFORE,INSIDE_AFTER
void method(˽int a˽,˽int b˽,˽int c){ |
- Documentation Style
The following values are supported for the CppDocStyle parameter:
Value |
Effect |
Remarks |
JAVADOC |
The comments are formatted using the Javadoc style that can be parsed by doxygen. |
|
QT |
The comments are formatted using the Qt style that can be parsed by doxygen. |
Example JAVADOC
/** * Concise description up to the first point. * Description of detail, e.g., description of algorithm * on several lines. * @param inParam1 Description of the respective parameter. * @param inParam2 Description of the respective parameter. * @param inParamn Description of the respective parameter. * @return (description of the return value) * @exception (description of the exception) * @see (optional reference to other functions or documents) */ |
Example QT
//! A normal member taking two arguments and returning an integer value. /*! \param a an integer argument. \param s a constant character pointer. \return The test results \sa QTstyle_Test(), ~QTstyle_Test(), testMeToo() and publicVar() */ |
- Static Check Excludes
The following values are supported for the CppStaticCheckExcludes parameter:
Value |
Effect |
Remarks |
NONE |
No excludes for static code analysis tools will be generated. |
|
PC_LINT_9L |
Excludes for the PC-Lint static code analysis tool, version 9L will be generated. |
|
- File Header Templates
The generator allows the definition of header templates (see Style Configuration). These are ASCII files with placeholders that are replaced by the values from the generator.
For all C++ Header files, the file from HeaderFileHeaderTemplate is used.
For all C++ Source files, the file from SourceFileHeaderTemplate is used.
For all C++ Unit Test files, the file from TestFileHeaderTemplate is used.
The following placeholders are supported:
Placeholder |
Replaced with |
Remarks |
$INPUT_FILE$ |
Input DSL File name without path |
See ‘CLI Arguments’ |
$BUILDER_TIMESTAMP$ |
Build timestamp |
Format: yyyy-MM-dd HH:mm:ss |
$BUILDER_VERSION$ |
Generator version |
Format: x.y.z.b |
$BUILDER_USER$ |
User string passed on the command line |
See ‘CLI Arguments’ |
$GENERATOR_LANGUAGE$ |
Language parameter |
See ‘Generator Configuration’. |
$GENERATOR_PLATFORM$ |
Platform parameter |
See ‘Generator Configuration’. |
$GENERATOR_RUNTIME$ |
Runtime parameter |
See ‘Generator Configuration’. |
$GENERATOR_RUNTIME_VERSION$ |
RuntimeVersion parameter |
See ‘Generator Configuration’. |
Example of a File Header Template
(c) IMT - Information Management Technology AG, CH-9470 Buchs, www.imt.ch. SW guideline: Tech Note for Coding Guidelines Version. 1.6
Generated by DffGenerator Generated from $INPUT_FILE$ by $BUILDER_USER$ |
The generator uses version 2 of the DATAFLOW DSL. The complete syntax is specified in [3] and will not be duplicated in this document. This document can be provided by IMT AG if required.
The generator writes a meta file for each generated artifact parsed from DSL. This file contains details on the generated files and the full path. This is used for integration in DATAFLOW Designer or other tools.
Term |
Description |
Remarks |
AP |
Active Part |
|
APC |
Active Container |
|
APIRQ |
Active Interrupt |
|
DFF |
Data Flow Framework |
|
DSL |
Domain-Specific Language |
|
IRQ |
Interrupt Request |
|
[1] Types is a short form for Protocol and Enumeration
[2] Components is a short form for Active Part, Active Container and Active Interrupt
[3] Domain-specific-Language
Required Module: DATAFLOW Code
This Article has been written based on V2.1.1 of the DATAFLOW software.
Latest update 2023-05-31 by WUM.
Comments
0 comments
Please sign in to leave a comment.