c_backend.c 7.56 KB
Newer Older
Maxime Perrotin's avatar
Maxime Perrotin committed
1
/* Buildsupport is (c) 2008-2016 European Space Agency
Maxime Perrotin's avatar
Maxime Perrotin committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
 * contact: maxime.perrotin@esa.int
 * License is LGPL, check LICENSE file */
/*
 * C backend for the AADL parser: C Entry point for buildsupport
 *
 *
 * The function C_End() is called by the AADL Parser (buildsupport.adb).
 * It triggers the execution of all the backends:
 *   - Model transformations
 *   - Semantic checks
 *   - Generation of function skeletons
 *   - Generation of glue code
 *   - Generation of the Concurrency view
 *
 * The data structures for the C AST are defined in the file my_types.h
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <errno.h>
#include <sys/stat.h>

#include "my_types.h"
#include "practical_functions.h"
#include "backends.h"
#include "c_ast_construction.h"

/* 
 * Fatal error counter
*/
static int error_count = 0;
void add_error()
{
    error_count++;
}

Maxime Perrotin's avatar
Maxime Perrotin committed
40
/*:
Maxime Perrotin's avatar
Maxime Perrotin committed
41
42
43
44
45
46
47
 * Main function called after the Ada AADL parser has completed.
*/
void C_End()
{
    /* Perform semantic checks of the user input */
    Semantic_Checks();

Maxime Perrotin's avatar
Maxime Perrotin committed
48
49
    /*
     * OpenGEODE support:
Maxime Perrotin's avatar
Maxime Perrotin committed
50
     * Replace SDL language with Ada for building glue code
Maxime Perrotin's avatar
Maxime Perrotin committed
51
52
53
54
55
56
57
58
59
     */
    if (get_context()->glue) {
        FOREACH(fv, FV, get_system_ast()->functions, {
                if (sdl == fv->language) fv->language = ada;
        });
    }

    /* Mark the callers of QGen functions */
    FOREACH(fv, FV, get_system_ast()->functions, {
Maxime Perrotin's avatar
Maxime Perrotin committed
60
61
62
63
64
65
66
67
68
69
70
71
72
        FOREACH(i, Interface, fv->interfaces, {
            if (RI == i->direction) {
                FV         *connected_fv = NULL;
                Interface  *connected_pi = NULL;
                connected_fv = FindFV (i->distant_fv);
                if ((connected_fv != NULL) &&
                         ((qgenada == connected_fv->language) || (qgenc == connected_fv->language))) {
                    i->distant_qgen->language = connected_fv->language;
                    i->distant_qgen->fv_name = connected_fv->name;
                    connected_pi = FindInterface (connected_fv, i->distant_name);
                    if (connected_pi != NULL) {
                        connected_pi->distant_qgen->language = connected_fv->language;
                        connected_pi->distant_qgen->fv_name = fv->name;
Maxime Perrotin's avatar
Maxime Perrotin committed
73
74
                    }
                }
Maxime Perrotin's avatar
Maxime Perrotin committed
75
            }
Maxime Perrotin's avatar
Maxime Perrotin committed
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
        });
    });

    /* Find out if init functions are present in QGen code and save the info */
    FOREACH(fv, FV, get_system_ast()->functions, {
        FOREACH(i, Interface, fv->interfaces, {
            if (i->distant_qgen != NULL) {
                char *qgeninit = NULL;
                if (qgenc == fv->language)
                    Build_QGen_Init(&qgeninit, fv->name, i->name, qgenc);
                else if (qgenada == fv->language)
                    Build_QGen_Init(&qgeninit, fv->name, i->name, qgenada);
                else if (qgenada == i->distant_qgen->language)
                    Build_QGen_Init(&qgeninit, fv->name, i->distant_name, qgenada);
                else if (qgenc == i->distant_qgen->language)
                    Build_QGen_Init(&qgeninit, fv->name, i->distant_name, qgenc);

                if (qgeninit != NULL)
                    i->distant_qgen->qgen_init = qgeninit;
            }
        });
    });

Maxime Perrotin's avatar
Maxime Perrotin committed
99
    /*
Maxime Perrotin's avatar
Maxime Perrotin committed
100
     * If Semantic errors have been found (errors in the user AADL models),
Maxime Perrotin's avatar
Maxime Perrotin committed
101
     * then the application is exited with an error message.
Maxime Perrotin's avatar
Maxime Perrotin committed
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
     */
    if (error_count > 0) {
        fprintf(stderr, "\nFound %d errors.. Aborting...\n", error_count);
        exit(1);
    }

    else {
        /* Generation of the build script */
        Generate_Build_Script();

        /* Skeleton-generation, if -gw flag is set. Done before the preprocesing backend
           which possibly creates additional functions */
        FOREACH(fv, FV, get_system_ast()->functions, {
            if (get_context()->gw && NULL != fv->zipfile && !get_context()->glue) {
                printf ("[Information] No skeleton is generated for function \"%s\"\n"
                        "              because source code is provided in file \"%s\"\n"
                        "              (as specified in the interface view)\n\n",
                        fv->name,
                        fv->zipfile
                        );
            }

Maxime Perrotin's avatar
Maxime Perrotin committed
124
            if (get_context()->gw &&
Maxime Perrotin's avatar
Maxime Perrotin committed
125
126
127
128
                (NULL == fv->zipfile || get_context()->glue)) {
                    GW_SDL_Backend(fv);
                    GW_Simulink_Backend(fv);
                    GW_C_Backend(fv);
Maxime Perrotin's avatar
Maxime Perrotin committed
129
                    GW_VDM_Backend(fv);
Maxime Perrotin's avatar
Maxime Perrotin committed
130
                    GW_VHDL_Backend(fv);
Maxime Perrotin's avatar
Maxime Perrotin committed
131
132
133
134
135
136
                    GW_Ada_Backend(fv);
                    GW_SCADE_Backend(fv);
                    GW_RTDS_Backend(fv);
                    GW_Driver_Backend(fv);
            }

Maxime Perrotin's avatar
Maxime Perrotin committed
137
            /* Export to SMP2: generate glue code and Python AST */
Maxime Perrotin's avatar
Maxime Perrotin committed
138
139
140
141
142
143
144
145
146
147
148
            if (true == get_context()->smp2) {
                GLUE_OG_Backend(fv);
                GLUE_RTDS_Backend(fv);
                GLUE_MiniCV_Backend(fv);
                GLUE_C_Backend(fv);
                Generate_Python_AST(get_system_ast(), NULL);

            }
        })


Maxime Perrotin's avatar
Maxime Perrotin committed
149
        /*
Maxime Perrotin's avatar
Maxime Perrotin committed
150
         * Perform the first part of the Vertical transformation (-glue flag):
Maxime Perrotin's avatar
Maxime Perrotin committed
151
         * Various model tranformations of the interface view
Maxime Perrotin's avatar
Maxime Perrotin committed
152
153
154
155
156
157
158
159
160
         */
        if (get_context()->glue) {
            Preprocessing_Backend(get_system_ast());
        }

        /*
         * Debug mode (userflag -test) : dump the result of the transformation
         * TODO: generate an AADL model (equivalent to the Concurrency View)
         */
Maxime Perrotin's avatar
Maxime Perrotin committed
161
        if (get_system_ast()->context->test) {
Maxime Perrotin's avatar
Maxime Perrotin committed
162
            Dump_model(get_system_ast());
Maxime Perrotin's avatar
Maxime Perrotin committed
163
        }
Maxime Perrotin's avatar
Maxime Perrotin committed
164

Maxime Perrotin's avatar
Maxime Perrotin committed
165
        /*
Maxime Perrotin's avatar
Maxime Perrotin committed
166
167
         * Execute various backends applicable to each FV
         */
Maxime Perrotin's avatar
Maxime Perrotin committed
168
169
170
171
172
173
174
        FOREACH(fv, FV, get_system_ast()->functions, {
            /*
             * Call 'asn2dataModel' if glue code is not required
             * (to avoid slowing down the orchestrator, which is
             * the only place where the glue code is requested
             */
            if (get_context()->gw && !get_context()->glue && NULL == fv->zipfile) {
Maxime Perrotin's avatar
Maxime Perrotin committed
175
                Call_asn2dataModel(fv);
Maxime Perrotin's avatar
Maxime Perrotin committed
176
            }
Maxime Perrotin's avatar
Maxime Perrotin committed
177

Maxime Perrotin's avatar
Maxime Perrotin committed
178
179
180
181
            /* Process all functional states declared in the interface view */
            if (get_context()->gw && (NULL == fv->zipfile || get_context()->glue)) {
                Process_Context_Parameters(fv);
            }
Maxime Perrotin's avatar
Maxime Perrotin committed
182
183
184
185
186

            /* Process function directives */
            if (get_context()->glue || get_context()->test) {
                Process_Directives (fv);
            }
Maxime Perrotin's avatar
Maxime Perrotin committed
187

Maxime Perrotin's avatar
Maxime Perrotin committed
188
189
190
191
192
193
194
195
196
197
198
199
200
            if (get_context()->glue) {
                GLUE_OG_Backend(fv);
                GLUE_RTDS_Backend(fv);
                GLUE_MiniCV_Backend(fv);
                GLUE_C_Backend(fv);
                GLUE_GUI_Backend(fv);
                GLUE_Ada_Wrappers_Backend(fv);
                GLUE_C_Wrappers_Backend(fv); 
                GLUE_VT_Backend(fv);
            }
        })

        /*
Maxime Perrotin's avatar
Maxime Perrotin committed
201
         * Perform the second part of the Vertical transformation:
Maxime Perrotin's avatar
Maxime Perrotin committed
202
203
204
205
206
207
208
209
210
211
212
213
214
215
         * Generate driver configuration
         * Generate the full concurrency view (process.aadl et al.)
         * Additionnally create an AADL file of the concurrency view
         * for display only in TASTE-IV
         */
            if (get_context()->glue) {
                FOREACH (process, Process, get_system_ast()->processes, {
                    Process_Driver_Configuration (process);
                })

                Generate_Full_ConcurrencyView((get_system_ast()->processes),
                                             (get_system_ast()->name));
                AADL_CV_Unparser ();
            }
Maxime Perrotin's avatar
Maxime Perrotin committed
216

Maxime Perrotin's avatar
Maxime Perrotin committed
217
218
219
220
221
        /* Generation of system configuration used by C_ASN1_Types.h */
        System_Config(get_system_ast());

    }
}