...
 
Commits (19)
......@@ -11,8 +11,8 @@ with Ada.Strings.Unbounded,
GNAT.OS_Lib,
Errors,
Locations,
Ocarina.Namet,
Ocarina.Types,
Namet,
Types,
System.Assertions,
Ocarina.Analyzer,
Ocarina.Backends.Properties,
......@@ -36,8 +36,8 @@ use Ada.Strings.Unbounded,
Ada.Text_IO,
Ada.Characters.Handling,
Locations,
Ocarina.Namet,
Ocarina.Types,
Namet,
Types,
Ocarina,
Ocarina.Analyzer,
Ocarina.Backends.Properties,
......@@ -232,6 +232,25 @@ procedure BuildSupport is
end if;
end;
declare
InstanceOf : constant Name_Id :=
Get_Instance_Of (CI);
begin
if InstanceOf /= No_Name then
C_Set_Instance_Of (Get_Name_String (InstanceOf),
Get_Name_String (InstanceOf)'Length);
end if;
end;
declare
IsComponent : constant Boolean :=
Get_Is_Component_Type (CI);
begin
if IsComponent then
C_Set_Is_Component_Type;
end if;
end;
-- Parse the functional states of this FV
if not Is_Empty (Subcomponents (CI)) then
FV_Subco := First_Node (Subcomponents (CI));
......@@ -801,7 +820,7 @@ procedure BuildSupport is
"programming_properties.aadl" &
"memory_properties.aadl" &
"modeling_properties.aadl" &
"arinc653.aadl" &
"arinc653_properties.aadl" &
"base_types.aadl" &
"data_model.aadl" &
"deployment.aadl";
......
......@@ -5,7 +5,7 @@
with Ada.Text_IO;
with GNAT.OS_Lib;
with Ocarina.Namet;
with Namet;
with Ocarina.Configuration;
with Ocarina.AADL_Values;
with Ocarina.Instances.Queries;
......@@ -19,7 +19,7 @@ package body Buildsupport_Utils is
use Ada.Text_IO;
use GNAT.OS_Lib;
use Ocarina.Namet;
use Namet;
use Ocarina.Instances.Queries;
use Ocarina.ME_AADL.AADL_Instances.Nodes;
use Ocarina.ME_AADL.AADL_Instances.Nutils;
......@@ -221,6 +221,38 @@ package body Buildsupport_Utils is
return Get_String_Property (D, Ellidiss_Tool_Version);
end Get_Ellidiss_Tool_Version;
-------------------------------
-- Get_Instance_Of --
-------------------------------
function Get_Instance_Of (Device : Node_Id) return Name_Id is
Instance_Of : Name_id := No_Name;
begin
if Is_Defined_Property (Device, "taste_iv_properties::instance_of")
then
Instance_Of := Get_String_Property
(Device, Get_String_Name
("taste_iv_properties::instance_of"));
end if;
return Instance_Of;
end Get_Instance_Of;
-------------------------------
-- Get_Is_Component_Type --
-------------------------------
function Get_Is_Component_Type (Device : Node_Id) return Boolean is
Is_Component_Type : Boolean := False;
begin
if Is_Defined_Property (Device, "taste_iv_properties::is_component_type")
then
Is_Component_Type := Get_Boolean_Property
(Device, Get_String_Name
("taste_iv_properties::is_component_type"));
end if;
return Is_Component_Type;
end Get_Is_Component_Type;
------------------------
-- Get_Interface_Name --
------------------------
......
......@@ -4,7 +4,7 @@
-- Set of helper functions for buildsupport
with Ocarina,
Ocarina.Types,
Types,
Ada.Containers.Indefinite_Ordered_Maps;
use Ocarina,
......@@ -12,7 +12,7 @@ use Ocarina,
package Buildsupport_Utils is
use Ocarina.Types;
use Types;
procedure Banner;
......@@ -65,6 +65,10 @@ package Buildsupport_Utils is
function Get_Ellidiss_Tool_Version (D : Node_Id) return Name_Id;
function Get_Instance_Of (Device : Node_Id) return Name_Id;
function Get_Is_Component_Type (Device : Node_Id) return Boolean;
function Get_Interface_Name (D : Node_Id) return Name_Id;
function Get_ASN1_Module_Name (D : Node_Id) return String;
......
......@@ -2,7 +2,7 @@
-- (c) 2015 European Space Agency - maxime.perrotin@esa.int
-- LGPL license, see LICENSE file
with Ocarina.Types; use Ocarina.Types;
with Types; use Types;
package Imported_Routines is
......@@ -190,8 +190,14 @@ package Imported_Routines is
procedure C_Set_Debug_Messages;
procedure C_New_Drivers_Section;
procedure C_End_Drivers_Section;
procedure C_Set_Instance_Of
(component : String;
len : Integer);
procedure C_Set_Is_Component_Type;
private
pragma Import (C, C_Set_Instance_Of, "Set_Instance_Of");
pragma Import (C, C_Set_Is_Component_Type, "Set_Is_Component_Type");
pragma Import (C, C_New_Drivers_Section, "New_Drivers_Section");
pragma Import (C, C_End_Drivers_Section, "End_Drivers_Section");
pragma Import (C, C_Set_PolyORBHI_C, "Set_PolyorbHI_C");
......
......@@ -96,6 +96,16 @@ int ada_gw_preamble(FV * fv)
fv->name);
}
if (true == fv->is_component_type) {
fprintf(ads,
"generic\n");
} else {
if (NULL != fv->instance_of) {
fprintf(ads,
"with %s;\n\n", fv->instance_of);
}
}
fprintf(ads, "package %s is\n", fv->name);
/* Expose each context parameter - pragma export used by SMP2 */
......@@ -332,7 +342,15 @@ void add_RI_to_Ada_gw(Interface * i)
fprintf(ads, "(%s)", ada_params);
}
fprintf(ads, " renames %s;\n\n", i->name);
if (NULL != i->parent_fv->instance_of) {
fprintf(ads,
"\tpackage %s_Instance is new %s (RI%s);\n\n",
i->parent_fv->name,
i->parent_fv->instance_of,
i->name);
}
free(ada_params);
ada_params = NULL;
......
......@@ -703,19 +703,20 @@ void GLUE_C_Backend(FV * fv)
);
}
if (c == fv->language || gui == fv->language || ada == fv->language || vdm == fv->language
|| qgenada == fv->language || qgenc == fv->language
|| rtds == fv->language || cpp == fv->language || opengeode == fv->language) {
Init_C_Glue_Backend(fv);
FOREACH(i, Interface, fv->interfaces, {
GLUE_C_ProvidedInterface(i);
}
);
if (false == fv->is_component_type) {
if (c == fv->language || gui == fv->language || ada == fv->language || vdm == fv->language
|| qgenada == fv->language || qgenc == fv->language
|| rtds == fv->language || cpp == fv->language || opengeode == fv->language) {
Init_C_Glue_Backend(fv);
FOREACH(i, Interface, fv->interfaces, {
GLUE_C_ProvidedInterface(i);
}
);
}
}
/* for all languages except ObjectGeode (sdl) and Blackbox devices, generate invoke_ri.c */
if (sdl != fv->language && blackbox_device != fv->language) {
if (sdl != fv->language && blackbox_device != fv->language && true != fv->is_component_type) {
FOREACH(i, Interface, fv->interfaces, {
GLUE_C_InvokeRI(i);
}
......
......@@ -142,12 +142,22 @@ void Create_script()
/* OpenGEODE-specific: call code generator on the fly */
FOREACH (fv, FV, get_system_ast()->functions, {
if (sdl == fv->language) {
fprintf(script,
if (NULL != fv->instance_of) {
fprintf(script,
"# Generate code for function %s (instance of OpenGEODE function %s)\n"
"cd \"$SKELS\"/%s && "
"opengeode --toAda system_structure.pr ../%s/%s.pr "
"&& rm -f %s.ad* "
"&& cd $OLDPWD\n\n",
fv->name, fv->instance_of, fv->name, fv->instance_of, fv->instance_of, fv->instance_of);
} else {
fprintf(script,
"# Generate code for OpenGEODE function %s\n"
"cd \"$SKELS\"/%s && "
"opengeode --toAda %s.pr system_structure.pr "
"&& cd $OLDPWD\n\n",
fv->name, fv->name, fv->name);
}
}
});
......@@ -243,7 +253,8 @@ void Create_script()
fprintf (script, "--subCPP ");
break;
case sdl:
case ada: fprintf (script, "--subAda ");
case ada: if (fv->is_component_type == true) fprintf (script, "--with-extra-Ada-code ");
else fprintf (script, "--subAda ");
break;
case vhdl: fprintf (script, "--subVHDL ");
break;
......@@ -257,7 +268,8 @@ void Create_script()
break;
}
fprintf (script, "%s", fv->name);
if (fv->is_component_type == true) fprintf (script, "%s", fv->name);
else fprintf (script, "%s", fv->name);
/* ObjectGEODE systems are treated differently from all other languages,
because it directly refers to .pr files, instead of zip files
if (sdl == fv->language) { UNCOMMENT WHEN OPENGEODE FULLY SUPPORTED
......@@ -270,6 +282,9 @@ void Create_script()
if (rtds == fv->language && NULL == fv->zipfile) {
fprintf (script, ":\"$SKELS\"/%s/%s.zip", fv->name, fv->name);
}
else if (true == fv->is_component_type) {
fprintf (script, ":\"$SKELS\"/%s", fv->name);
}
else if (NULL != fv->zipfile) {
fprintf (script, ":\"$SKELS\"/%s", fv->zipfile);
}
......
......@@ -409,7 +409,7 @@ void GLUE_OG_Backend(FV * fv)
{
if (fv->system_ast->context->onlycv)
return;
if (sdl == fv->language) {
if ((sdl == fv->language) && (false == fv->is_component_type)) {
Create_OG_files(fv);
FOREACH(i, Interface, fv->interfaces, {
GLUE_OG_Interface(i);
......
......@@ -511,6 +511,17 @@ void Set_Stack(char *val, size_t len)
build_string(&(system_ast->context->stacksize), val, len);
}
void Set_Instance_Of(char *component, size_t len)
{
assert (0 < len && NULL != fv);
build_string (&(fv->instance_of), component, len);
}
void Set_Is_Component_Type()
{
assert (NULL != fv);
fv->is_component_type = true;
}
/* End of context-related functions */
......@@ -1118,6 +1129,39 @@ Interface *FindInterface(FV * function, char *interface_name)
return result;
}
/* FindParameter of a given Interface */
void CompareParName(Parameter * p, Parameter ** result)
{
if (NULL == p->name || NULL == search_name)
return;
if (!strcmp(p->name, search_name)) {
*result = p;
SetSearchName(NULL);
}
}
Parameter *FindInParameter(Interface *i, char *param_name)
{
Parameter *result = NULL;
SetSearchName(param_name);
FOREACH(p, Parameter, i->in, {
CompareParName(p, &result);})
SetSearchName(NULL);
return result;
}
Parameter *FindOutParameter(Interface * i, char *param_name)
{
Parameter *result = NULL;
SetSearchName(param_name);
FOREACH(p, Parameter, i->out, {
CompareParName(p, &result);})
SetSearchName(NULL);
return result;
}
/* Given a PI (from any function) and a known caller, find the corresponding
* RI in the remote function
*/
......
......@@ -121,7 +121,7 @@ void C_End()
);
}
if (get_context()->gw &&
if (get_context()->gw && (false == fv->is_component_type) &&
(NULL == fv->zipfile || get_context()->glue)) {
GW_SDL_Backend(fv);
GW_Simulink_Backend(fv);
......@@ -135,7 +135,7 @@ void C_End()
}
/* Export to SMP2: generate glue code and Python AST */
if (true == get_context()->smp2) {
if (true == get_context()->smp2 && (false == fv->is_component_type)) {
GLUE_OG_Backend(fv);
GLUE_RTDS_Backend(fv);
GLUE_MiniCV_Backend(fv);
......@@ -173,34 +173,36 @@ void C_End()
* Execute various backends applicable to each FV
*/
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) {
Call_asn2dataModel(fv);
}
if (false == fv->is_component_type) {
/*
* 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) {
Call_asn2dataModel(fv);
}
/* Process all functional states declared in the interface view */
if (get_context()->gw && (NULL == fv->zipfile || get_context()->glue)) {
Process_Context_Parameters(fv);
}
/* Process all functional states declared in the interface view */
if (get_context()->gw && (NULL == fv->zipfile || get_context()->glue)) {
Process_Context_Parameters(fv);
}
/* Process function directives */
if (get_context()->glue || get_context()->test) {
Process_Directives (fv);
}
/* Process function directives */
if (get_context()->glue || get_context()->test) {
Process_Directives (fv);
}
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);
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);
}
}
})
......
......@@ -927,6 +927,8 @@ void Create_FV(FV ** fv)
/* is this function a timer manager? */
(*fv)->timer = false;
(*fv)->timer_list = NULL;
(*fv)->is_component_type = false;
(*fv)->instance_of = NULL;
}
}
......@@ -963,6 +965,9 @@ void Clear_FV(FV * fv)
if (NULL != fv->process) {
fv->process = NULL;
}
if (NULL != fv->instance_of) {
fv->instance_of = NULL;
}
}
......
This diff is collapsed.
......@@ -68,10 +68,16 @@ void Create_New_SDL_Structure(FV * fv)
char *filename = make_string("%s.pr", fv->name);
/* If not already existing, also create an empty system_implementation.pr
* file - includes timer declarations, if any */
if (!file_exists (path, filename)) {
* file - includes timer declarations, if any.
* Do not create in case the function is an instance of a generic function*/
if (!file_exists (path, filename) && (NULL == fv->instance_of)) {
create_file (path, filename, &process);
fprintf (process, "PROCESS %s;\n", fv->name);
if (fv->is_component_type == false) {
fprintf (process, "PROCESS %s;\n", fv->name);
} else {
fprintf (process, "PROCESS type %s;\n", fv->name);
}
if (NULL != fv->timer_list) {
fprintf (process, "/* CIF TEXT (10, 10), (200, 250) */\n");
fprintf (process, "-- Timers defined in the interface view\n"
......@@ -88,8 +94,12 @@ void Create_New_SDL_Structure(FV * fv)
"NEXTSTATE Wait;\n"
"/* CIF STATE (450, 10), (70, 35) */\n"
"STATE Wait;\n"
"ENDSTATE;\n"
"ENDPROCESS;\n");
"ENDSTATE;\n");
if (fv->is_component_type == false) {
fprintf (process, "ENDPROCESS;\n");
} else {
fprintf (process, "ENDPROCESS type;\n");
}
close_file(&process);
}
free(dataview_uniq);
......@@ -199,7 +209,17 @@ void Build_SDL_Connections(FV * fv)
fprintf(f, "\t\t\tFROM %s TO ENV WITH %s;\n", fv->name,
ri_string);
fprintf(f, "\n\t\tCONNECT c and r;\n\n");
fprintf(f, "\t\tPROCESS %s REFERENCED;\n\n", fv->name);
if (fv->is_component_type == false) {
if (fv->instance_of == NULL) {
fprintf(f, "\t\tPROCESS %s REFERENCED;\n\n", fv->name);
} else {
fprintf(f, "\t\tPROCESS %s:%s;\n\n", fv->name, fv->instance_of);
}
} else {
fprintf(f, "\t\tPROCESS type %s;\n\n", fv->name);
}
fprintf(f, "\tENDBLOCK;\n\nENDSYSTEM;");
}
......@@ -238,7 +258,7 @@ void GW_SDL_Interface(Interface * i)
void GW_SDL_Backend(FV * fv)
{
if (fv->system_ast->context->onlycv) return;
if (sdl == fv->language || opengeode == fv->language) {
if ((sdl == fv->language || opengeode == fv->language) && (false == fv->is_component_type)) {
Create_New_SDL_Structure(fv);
FOREACH(i, Interface, fv->interfaces, {
GW_SDL_Interface(i);
......
......@@ -70,6 +70,84 @@ void Interface_Semantic_Check(Interface * i)
}
bool Equal_Params(Parameter * p1, Parameter * p2)
{
bool result=true;
if (!Compare_String (p1->name, p2->name)) {
result=false;
}
if (!Compare_String (p1->type, p2->type)) {
result=false;
}
if (!Compare_ASN1_Filename (p1->asn1_filename, p2->asn1_filename)) {
result=false;
}
if (!Compare_ASN1_Module (p1->asn1_module, p2->asn1_module)) {
result=false;
}
if (p1->basic_type != p2->basic_type) {
result=false;
}
if (p1->encoding != p2->encoding) {
result=false;
}
if (p1->param_direction != p2->param_direction) {
result=false;
}
return result;
}
bool MultiInstance_SDL_Interface_Check(Interface * i, Interface * j)
{
bool result=true;
int in_param_cnt_i = 0;
int in_param_cnt_j = 0;
int out_param_cnt_i = 0;
int out_param_cnt_j = 0;
if (!Compare_Interface (i, j)) {
result=false;
}
if (i->direction != j->direction) {
result=false;
}
FOREACH(p, Parameter, i->in, {
Parameter *inp = FindInParameter (i, p->name);
if (!Equal_Params (p, inp)){
result=false;
}
in_param_cnt_i++;
});
FOREACH(p, Parameter, j->in, {
UNUSED (p);
in_param_cnt_j++;
});
FOREACH(p, Parameter, i->out, {
Parameter *outp = FindOutParameter (i, p->name);
if (!Equal_Params (p, outp)){
result=false;
}
out_param_cnt_i++;
});
FOREACH(p, Parameter, j->out, {
UNUSED (p);
out_param_cnt_j++;
});
if (in_param_cnt_i != in_param_cnt_j) {
result=false;
}
if (out_param_cnt_i != out_param_cnt_j) {
result=false;
}
return result;
}
/* External interface (the one and unique) */
void Function_Semantic_Check(FV * fv)
......@@ -241,6 +319,69 @@ void Function_Semantic_Check(FV * fv)
Interface_Semantic_Check(i);
}
);
/*
* SDL specific checks: is_component_type can only be true for SDL functions.
* instance_of can only point to functions with is_component_type set to true.
*/
if (fv->is_component_type) {
if (sdl != fv->language) {
ERROR
("** Error: Is_Component_Type is True for \"%s\". This is allowed only for SDL functions.\n",
fv->name);
add_error();
}
}
if (NULL != fv->instance_of) {
FV *definition = FindFV (fv->instance_of);
if (definition == NULL) {
ERROR
("** Error: Defining function \"%s\" for \"%s\" not found.\n",
fv->instance_of, fv->name);
add_error();
}
if (false == definition->is_component_type) {
ERROR
("** Error: Is_Component_Type is False for \"%s\". It should be True,\n",
definition->name);
ERROR
(" because function \"%s\" claims that it is an instance of \"%s\".\n",
fv->name, definition->name);
add_error();
}
int fv_intf_cnt = 0;
int definition_intf_cnt = 0;
FOREACH(i, Interface, fv->interfaces, {
Interface *def_i = FindInterface (definition, i->name);
if (def_i == NULL) {
ERROR
("** Error: Interface \"%s\" of instance \"%s\" not found from definition \"%s\".\n",
i->name, fv->name, definition->name);
add_error();
} else {
if (!MultiInstance_SDL_Interface_Check (i, def_i)) {
ERROR
("** Error: Interface \"%s\" of instance \"%s\" not matching with definition \"%s\".\n",
i->name, fv->name, definition->name);
add_error();
}
}
fv_intf_cnt++;
});
FOREACH(i, Interface, definition->interfaces, {
UNUSED (i);
definition_intf_cnt++;
});
if (fv_intf_cnt != definition_intf_cnt) {
ERROR
("** Error: Interface count mismatch between definition \"%s\" and instance \"%s\".\n",
definition->name, fv->name);
add_error();
}
}
}
/* External interface */
......
......@@ -498,7 +498,7 @@ int Init_Process_Backend()
* of all processes */
FOREACH(p, Process, get_system_ast()->processes, {
FOREACH(b, Aplc_binding, p->bindings, {
if (thread_runtime == b->fv->runtime_nature) {
if (thread_runtime == b->fv->runtime_nature && (false == b->fv->is_component_type)) {
fprintf(process, "\twith %s_CV_Thread;\n", b->fv->name);
}
});
......@@ -839,7 +839,7 @@ void GenerateProcessImplementation(Process *p)
p->name, p->name);
}
FOREACH(b, Aplc_binding, p->bindings, {
if (thread_runtime == b->fv->runtime_nature) {
if (thread_runtime == b->fv->runtime_nature && (false == b->fv->is_component_type)) {
DeclareProcessFeatures(b, &p, &ports);
}
});
......@@ -854,12 +854,14 @@ void GenerateProcessImplementation(Process *p)
fprintf(process,"subcomponents\n");
FOREACH(b, Aplc_binding, p->bindings, {
SetThread(b);
if (false == b->fv->is_component_type) SetThread(b);
if (get_context()->polyorb_hi_c) SetProtectedObject(b);
});
FOREACH(b, Aplc_binding, p->bindings, {
if (thread_runtime == b->fv->runtime_nature) ProcessMakeConnections(b, &p);
if (thread_runtime == b->fv->runtime_nature && (false == b->fv->is_component_type)) {
ProcessMakeConnections(b, &p);
}
});
if (get_context()->polyorb_hi_c) {
......@@ -874,7 +876,7 @@ void GenerateProcessImplementation(Process *p)
FOREACH(b, Aplc_binding, p->bindings, {
Protected_Object_Name_list *set_of_protected = NULL;
if (thread_runtime == b->fv->runtime_nature) {
if (thread_runtime == b->fv->runtime_nature && (false == b->fv->is_component_type)) {
if (get_context()->test) {
printf("\n[thread %s]\n", b->fv->name);
}
......
......@@ -5,6 +5,8 @@
#define __C_AST_CONSTRUCTION_H__
Parameter *FindInParameter(Interface *i, char *param_name);
Parameter *FindOutParameter(Interface *i, char *param_name);
Interface *FindInterface(FV *fv,char *interface_name);
Interface *FindCorrespondingRI(FV *remote, Interface *pi);
void CompareIFname(Interface *i,Interface **result);
......@@ -93,6 +95,8 @@ void Set_Native_Encoding();
void Set_Zipfile (char *file, size_t len);
void Set_Root_Node(char *name,size_t len);
void Set_PolyorbHI_C();
void Set_Instance_Of(char *component, size_t len);
void Set_Is_Component_Type();
System *get_system_ast();
void Delete_System_AST();
void C_Init();
......
......@@ -244,6 +244,8 @@ typedef struct t_fv {
char *original_name;
bool timer;
struct t_String_list *timer_list;
bool is_component_type;
char *instance_of;
} FV;
DECLARE_LIST(FV)
......
......@@ -7,6 +7,8 @@
#include "my_types.h"
#include "c_ast_construction.h"
#define UNUSED(x) (void)(x)
#define USE_PO_HI_ADA(fv) (fv->system_ast->context->polyorb_hi_c == 0)
#define USE_PO_HI_C(fv) (fv->system_ast->context->polyorb_hi_c == 1)
......