Explaining the DATAFLOW Code Generator Functionalities

by Marco Wuelser

 

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:

  1. Auto-Generated files. These files will always be overwritten upon generation. The user MUST NOT change these files in any way.
  2. 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
[length]

*

-

-

-

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

DffStudio.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)

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.

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.

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

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                                

 

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

 

 

 

This Article has been written based on V2.2.1 of the DATAFLOW Code Generator software. 
Latest update 2022-04-09 by WUM.

Required Module: DATAFLOW Code

Go back