README.md 6.08 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
SKELETON TEMPLATES
==================

This is the place where the templates describe what code shall be generated when the tool is asked to generate function skeletons (done by default).

Adding or modifying the templates does not require recompilation of the tool. It is possible to add support for new languages or generate additional files for the existing languages by just adding new subfolders.

The format of the template file is the one of the _templates-parser_ engine from Adacore. Complete documentation is available online (http://docs.adacore.com/live/wave/aws/html/template_parser/index.html)

How to add or modify a template
Maxime Perrotin's avatar
Maxime Perrotin committed
11
==
12 13 14 15 16 17

You can create your own template files. We will show how the C templates are defined, as if we had to do them from scratch.

Each set of template allows to generate one file corresponding to a build script (e.g. a Makefile) and one file with content related to a TASTE function. For both, you are free to set the name of the file and all its content.
In this example we will create a set of template that generate the _header files_, as part of the C function skeletons.

Maxime Perrotin's avatar
Maxime Perrotin committed
18 19
Create a new folder (any name)
--
20 21 22 23 24 25

```
$ mkdir c-header
$ cd  c-header
```

Maxime Perrotin's avatar
Maxime Perrotin committed
26 27
List the template files
--
28 29 30 31 32 33 34 35 36 37 38 39 40

These files are needed:

```
c-header/
├── function-filename.tmplt    # Name of the file we want to generate
├── function.tmplt             # Main template for the output file
├── interface.tmplt            # Template for one provided or required interface
├── makefile-filename.tmplt    # Name of the file we want to generate for the build script
├── makefile.tmplt             # Content of the build script
└── trigger.tmplt              # Condition that triggers the application of this template
```

Maxime Perrotin's avatar
Maxime Perrotin committed
41 42
Define the trigger
--
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66

The file trigger.tmplt defines the condition that has to be fulfilled for the tool to actually process the templates in the current folder.
It has to return the string TRUE if the condition is met. Any other value means FALSE.

For example, for the C header, the content is the following:

```
@@IF@@ @_Language_@ = "C"
TRUE
@@END_IF@@
```

`@_Language_@` is a template variable. The list of available variables is listed at the top of each template file, for convenience.

If you look at the template for the _body_ file trigger for C, it contains an additional condition:

```
@@IF@@ @_Language_@ = "C" and not @_Filename_Is_Present_@
TRUE
@@END_IF@@
```

Here, we want to generate the file _only if it is not already there_, to prevent overwritting user code.

Maxime Perrotin's avatar
Maxime Perrotin committed
67 68
Define the filenames
--
69

Maxime Perrotin's avatar
Maxime Perrotin committed
70
The `function-filename.tmplt` and `makefile-filename.tmplt` are used to determine the output file name:
71 72 73 74 75 76 77 78 79 80 81 82 83

```
$ cat function-filename.tmplt
@_LOWER:Name_@.h
```

The template engine allows to filter strings in many convenient way. Here we lowercase the function name to return a filename in lowercase.

```
$ cat makefile-filename.tmplt
Makefile
```

Maxime Perrotin's avatar
Maxime Perrotin committed
84 85
Define the content of the function template
--
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128

Many template variables are available as attributes derived from the parsing of the Interface View:

```
@@-- @_Name_@                : The name of the function
@@-- @_Language_@            : The implementation language
@@-- @_List_Of_PIs_@         : List of all Provided Interfaces (just names)
@@-- @_List_Of_RIs_@         : List of all Required Interfaces (just names)
@@-- @_List_Of_Sync_PIs@     : List of synchronous Provided Interfaces
@@-- @_List_Of_Sync_RIs@     : List of synchronous Required Interfaces
@@-- @_List_Of_ASync_PIs@    : List of asynchronous Provided Interfaces
@@-- @_List_Of_ASync_RIs@    : List of asynchronous Required Interfaces
@@-- @_ASN1_Modules_@        : List of ASN.1 Modules names
@@-- @_ASN1_Files_@          : List of ASN.1 Files with path
@@-- @_Timers_@              : List of timers (just names)
@@-- @_Has_Context_@         : Flag, True if there are context parameters
@@-- @_CP_Names_@            : List of Context Parameter names
@@-- @_CP_Types_@            : List of Context Parameter types
@@-- @_Provided_Interfaces_@ : From template: Provided interfaces with params
@@-- @_Required_Interfaces_@ : From template: Required interfaces with params
@@-- @_Property_Names_@      : List of User-defined properties (names)
@@-- @_Property_Values_@     : List of User-defined properties (values)
@@-- @_Is_Type_@             : Flag, True if function is a component type
@@-- @_Instance_Of_@         : Optional name of component type
```

It is possible to render lists of items with automatic indentation, and shape the overall output file based on the output language.

For example this is an extract of the C template:

```
/*
 * DO NOT EDIT THIS FILE, IT WILL BE OVERWRITTEN DURING THE BUILD
 */

#pragma once

#include "dataview-uniq.h"

#ifdef __cplusplus
extern "C" {
#endif

Maxime Perrotin's avatar
Maxime Perrotin committed
129
void @_LOWER:Name_@_startup(void);
130 131 132 133 134 135 136 137 138 139 140 141 142 143

/* Provided interfaces */
@@TABLE@@
@_Provided_Interfaces_@
@@END_TABLE@@

```

Provided and Required interface templates are defined in a separate file and provided to the function template as a list.

This is an extract of `interface.tmplt`:

```
@@IF@@ @_Direction_@ = "PI"
144
void @_LOWER:Parent_Function_@_PI_@_Name_@(
145
@@ELSE@@
146
extern void @_LOWER:Parent_Function_@_RI_@_Name_@(
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
@@END_IF@@
```

When applying this template, the engine will generate:

```
void function_PI_interface_name(
```

or
```
extern void function_RI_interface_name(
```

And this is followed by the list of typed parameters.

Maxime Perrotin's avatar
Maxime Perrotin committed
163 164 165
**IMPORTANT**

In some cases, you may want to share templates (or _part of them_) between several template folders, and avoid copy-pasting the content. For example, the function content in C and in C++ are currently identical (but the file names are different). In that case, you can _include_ one template in another one:
Maxime Perrotin's avatar
Maxime Perrotin committed
166 167 168 169 170 171

```
$ cat cpp-header/function.tmplt
@@INCLUDE@@ ../c-header/function.tmplt
```

Maxime Perrotin's avatar
Maxime Perrotin committed
172 173
Define the template of the buildscript
--
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188

In the case of a Makefile, the content can be:

```
all: compile-linux

clean:
        rm -rf obj

compile-linux:
        mkdir -p obj && cd obj && gcc -c ../src/*.c
```

But it can obviously be much more complex and use the available template variables.

Maxime Perrotin's avatar
Maxime Perrotin committed
189 190
Test it!
--
191

192
If the trigger condition you defined returns TRUE, the template will be executed.