Preprocessor Directives
To extend the currently supported preprocessor directives, Embedded Engineer contains a Profile named Embedded Engineer Prerocessor Directives.
This Profile will give you the ability to define preprocessor directives of nearly any kind.
Embedded Engineer will generate/handle Interfaces, Structs, Unions, Enums and Using flagged
with preprocessor directives.
General Concept
Kinds
There are four kind of directives
stand alone
The directives include
, line
, define
, undef
, error
, prama
are stand alone directives and can be use as they are.
opening
if
, ifdef
, ifndef
, elif
, else
are opening directives that need a closing directive connected via a closing with
Dependency.
closing
elfi
, else
, endif
are closing directives that need a preceeding opening directive (connected via a closing with
Dependency)
Directive
This is a generic implementation to support future/custom directives and can be used either way.
Linking
Info
Embedded Engineer also allows sorting/ordering of the directives by using the pursued by
dependency.
For every model element flagged with a directive, either by using the flag Dependency or by settings the FlaggedCodeParts
Tagged Value, the code generation will write the directive and all pursued by
directives write before the code of the model element, followed by the closing with
directive, if one was modelled.
Pseudo Code Example
#Opening Directive
#Pursued by Directive1
#Pursued by Directive2
...
Model Code
#Closing Directive
Example
The following Example shows a class flagged with generic directives.
It also shows how to use the flags
, closing with
and pursued by
Dependency
#Directive1
#Directive3
#Directive4
Class1
{
...
}
#Directive2
- As expected the code generation will generate the
Class1
class, see line 4 to 7. - Since this class is flagged with the
Directive1
line 1 will be the preceeded#Directive1
. Directive1
has aclosing with
Dependency toDirective2
. This will lead to the closing statement in line 8#Directive2
.Directive1
has also apursued by
Dependency toDirective3
and this has in turn apursued by
Dependency toDirective4
.- This will result in the generation of both directives right after line1 in line 2 and 3,
#Directive3
and#Directive4
.
Predefined directive Stereotypes
include
line
define
undef
if
ifdef
ifndef
elif
else
endif
error
pragma
All predefined directives use:
- the Stereotype as the preprocessor instruction
- the Name of the element as the expression/argument.
- the
Incorporation
Tagged Value to specify where the directive should be added. - the
FlaggedCodeParts
Tagged Value to specify which elements shall be flagged with the directive
Generic Directive
The generice Directive
Stereotype was introduced to be able to add custom preprocessor directives/macros without the need to update the Profile itself.
The Directive
will use the Name of the element as the preprocessing instruction and the Expression
Tagged Value as the expression/arguments.
Every stand alone and opening directive contains a Incorporation
Tagged Value to specify where the directive should be added.
Possible values:
Value | Description |
---|---|
Implementation | Will generate Pre-/Suffix in the implementation file (.c File) |
Declaration | Will generate Pre-/Suffix in the declaration file (.h File) |
Both | Will generate Pre-/Suffix in both files (c. and .h File) |
Example
The following example shows how to use a generic Directive
Stereotype to generate an include statement in the .h file.
#include <test.h>
Extended functionality
We found that some cases can't be handled by simple directives. To extend the functionality, we added the following feature:
if
,ifdef
,ifndef
directive names can be multiline and will be written behind the#if
in the code file-
endif
directive names will be written before the#endif
in the code file if they are multilineTip
The name/text of the directive will only be placed before the
#endif
if it is a multiline text
Example
This allows the code generation to create surrounding structutes such as extern "C"
for the flagged
model objects.
#ifdef _cplusplus
extern "C"
{
#endif
typedef struct Class1Struct
{
int a;
} Class1;
void Class1_b(Class1* const me);
#ifdef _cplusplus
}
#endif
Supported model elements
The following model elements can be flagged with a directive
Examples
Flag Usings
#if DEBUG
#include "Class2.h"// Include for 'relation to classifier' 'Class2'
#endif
Flag Elements
-
Open a class diagram.
Create a new
Preprocessor Directives
diagram. -
Drag/drop the class, struct, enum,... you like to flag with the directive, into the diagram
-
Create a preprocessor directive:
-
Use the
Preprocessor Directive
ToolboxOR
-
Add a new class and assign one of the preprocessor directive Stereotypes
-
-
Flag the element where you would like to add the directive
-
Create a
flags
DependencyUse the quick linker or again the
Preprocessor Directive
Toolbox
OR
-
Select the element(s) in the FlaggedCodeParts Tagged Values
-
-
Set the expression accordingly by simply changing the name of the directive
-
Add a closing directive
-
Create a
closing with
Dependency
OR
- Create a Dependency and apply the closing with Stereotype
-
-
Generate the Code
...
#if Debug
typedef int Class1;
/* Operation 'Fnc01' of class 'Class1' */
void Class1_Fnc01(Class1* const me, int i);
#endif
...
Examples
Model: CodeGenerationComponentsTest.eapx
Element: Model.EmbeddedEngineer Components.AnsiC.Structural Elements.PreProcessor Directives.PreProcessor Directives
Use the quick linker or again the Preprocessor Directive
Toolbox
Model: MDCodeGenerationComponentsTest.xml
Element: Model.EmbeddedEngineer Components.AnsiC.Structural Elements.PreProcessor Directives.PreProcessor Directives