Code Generator Usage (DATAFLOW Code)

by Marco Wuelser

 

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.

 

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
Dataflow.Generator.App.exe -configdir ./config –SourceFile MyAp.dff –user test
pause

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)

RTOS abstraction layer for Embos real time operating system. (2)

MIDCORE

(1)

RTOS 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.

https://docs.microsoft.com/en-us/visualstudio/test/microsoft-visualstudio-testtools-cppunittestframework-api-reference?view=vs-2019

   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.

 

Parser Configuration

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.

Parser Configuration Parameters

Example Parser Configuration

{
"ParserOptions": {
   "Version": 1,
   "Data": {
     "FrameworkDirectories": ["../Imt.Base","C:\\src\\imt\\Imt.Base"]
   }
}
}

 

Style Configuration

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’.

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                                

 

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.

http://www.doxygen.nl/manual/docblocks.html

QT

The comments are formatted using the Qt style that can be parsed by doxygen.

http://www.doxygen.nl/manual/docblocks.html

 

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$

 

DSL Files

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.

 

Meta File

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.

 

Glossary

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.

Go back