Commit aaba0f46 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Work on supporting component types

parent 9877d563
......@@ -5,10 +5,12 @@
with System.Assertions,
Ada.Exceptions,
Ada.IO_Exceptions,
Ada.Text_IO,
Ada.Directories,
Ada.Strings.Equal_Case_Insensitive,
Ada.Containers,
Ada.Environment_Variables,
Ada.Characters.Handling, -- Contains "To_Lower"
GNAT.Command_Line,
Errors,
......@@ -19,6 +21,7 @@ with System.Assertions,
Ocarina.Files,
Ocarina.Parser,
Ocarina.FE_AADL.Parser,
Ocarina.Options,
TASTE.Backend,
TASTE.Backend.Build_Script,
TASTE.Backend.Code_Generators,
......@@ -42,36 +45,116 @@ use Ocarina.ME_AADL.AADL_Tree.Nutils;
package body TASTE.AADL_Parser is
function Initialize return Taste_Configuration is
File_Name : Name_Id;
File_Descr : Location;
Cfg : Taste_Configuration;
package Env renames Ada.Environment_Variables;
procedure Find_Shared_Libraries (Model : out TASTE_Model) is
-- Look for shared component types and update the list of AADL files
-- to be parsed together with interface and deployment views
Shared_Types : constant String :=
Env.Value (Name => "TASTE_SHARED_TYPES",
Default => "/home/taste/tool-inst/share/SharedTypes");
-- To iterate on folders:
ST : Search_Type;
Current : Directory_Entry_Type;
-- To iterate on AADL files:
-- AADL_ST : Search_Type;
-- AADL_Current : Directory_Entry_Type;
begin
-- Enable the "-y" flag from Ocarina to load and parse automatically the
-- dependencies (WITH ...) of the AADL model.
Ocarina.Options.Auto_Load_AADL_Files := True;
Model.Configuration.Shared_Lib_Dir := US (Shared_Types);
Start_Search (Search => ST,
Pattern => "",
Directory => Shared_Types,
Filter => (Directory => True, others => False));
if not More_Entries (ST) then
Put_Info ("No shared components found");
end if;
while More_Entries (ST) loop
Get_Next_Entry (ST, Current);
if Base_Name (Full_Name (Current)) = "" then
-- Ignore "." and ".." folders
goto Next_Component;
end if;
-- Add folder to Ocarina include path (equivalent to -I)
Ocarina.Options.Add_Library_Path (Full_Name (Current) & "/");
-- The model keeps a list of shared types for the backends
Model.Configuration.Shared_Types.Append
(Base_Name (Full_Name (Current)));
Put_Info ("Added " & Full_Name (Current) & " to Include path");
-- Search for AADL files in the subfolders
-- Start_Search
-- (Search => AADL_ST,
-- Pattern => "*.aadl",
-- Directory => Full_Name (Current),
-- Filter => (Ordinary_File => True, others => False));
--
-- if not More_Entries (AADL_ST) then
-- Put_Info ("No AADL file in " & Full_Name (Current));
-- end if;
--
-- while More_Entries (AADL_ST) loop
-- Get_Next_Entry (AADL_ST, AADL_Current);
-- -- Add everything for the parser
-- if Base_Name (Full_Name (AADL_Current)) /= "DataView" then
-- Put_Info ("Found shared type: " & Full_Name (AADL_Current));
-- Interface_AADL_Lib.Append (Full_Name (AADL_Current));
-- Deployment_AADL_Lib.Append (Full_Name (AADL_Current));
-- -- Store the list of shared types in the configuration
-- Model.Configuration.Shared_Types.Append
-- (Base_Name (Full_Name (AADL_Current)));
-- end if;
-- end loop;
<<Next_Component>>
end loop;
exception
when Ada.IO_Exceptions.Name_Error =>
raise AADL_Parser_Error
with "Shared library folder not found: " & Shared_Types;
end Find_Shared_Libraries;
procedure Initialize (Model : out TASTE_Model) is
File_Name : Name_Id;
File_Descr : Location;
use String_Holders;
begin
Banner;
-- Parse arguments before initializing Ocarina, otherwise Ocarina eats
-- some arguments (all file parameters).
Parse_Command_Line (Cfg);
Parse_Command_Line (Model.Configuration);
Initialize_Ocarina;
AADL_Language := Get_String_Name ("aadl");
if Cfg.Interface_View.Is_Empty and not Cfg.Check_Data_View then
if Model.Configuration.Interface_View.Is_Empty
and not Model.Configuration.Check_Data_View
then
-- Use "InterfaceView.aadl" by default, if nothing else is specified
-- and if the tool is not only called to check the data view
-- Cfg.Interface_View := Default_Interface_View'Access;
Cfg.Interface_View := To_Holder (Default_Interface_View);
Model.Configuration.Interface_View :=
To_Holder (Default_Interface_View);
end if;
Find_Shared_Libraries (Model);
-- An interface view is expected, look for it and parse it
if not Cfg.Interface_View.Is_Empty then
Set_Str_To_Name_Buffer (Cfg.Interface_View.Element);
if not Model.Configuration.Interface_View.Is_Empty then
Set_Str_To_Name_Buffer (Model.Configuration.Interface_View.Element);
File_Name := Ocarina.Files.Search_File (Name_Find);
if File_Name = No_Name then
raise AADL_Parser_Error
with "Interface View file not found : "
& Cfg.Interface_View.Element;
& Model.Configuration.Interface_View.Element;
end if;
File_Descr := Ocarina.Files.Load_File (File_Name);
......@@ -94,20 +177,21 @@ package body TASTE.AADL_Parser is
end if;
end if;
if Cfg.Glue then
if Model.Configuration.Glue then
-- Look for a deployment view (or DeploymentView.aadl by default)
-- if the glue generation is requested. Not needed for skeletons.
if Cfg.Deployment_View.Is_Empty then
Cfg.Deployment_View := To_Holder (Default_Deployment_View);
if Model.Configuration.Deployment_View.Is_Empty then
Model.Configuration.Deployment_View :=
To_Holder (Default_Deployment_View);
end if;
Set_Str_To_Name_Buffer (Cfg.Deployment_View.Element);
Set_Str_To_Name_Buffer (Model.Configuration.Deployment_View.Element);
File_Name := Ocarina.Files.Search_File (Name_Find);
if File_Name = No_Name then
raise AADL_Parser_Error
with "Deployment View file not found : "
& Cfg.Deployment_View.Element;
& Model.Configuration.Deployment_View.Element;
end if;
File_Descr := Ocarina.Files.Load_File (File_Name);
......@@ -119,45 +203,48 @@ package body TASTE.AADL_Parser is
end if;
end if;
for Each of Cfg.Other_Files loop
for Each of Model.Configuration.Other_Files loop
-- Add other files to the Interface and (if any) deployment roots
-- (List of files specified in the command line)
Set_Str_To_Name_Buffer (Each);
File_Name := Ocarina.Files.Search_File (Name_Find);
if File_Name = No_Name then
raise AADL_Parser_Error with "File not found: " & Each;
end if;
File_Descr := Ocarina.Files.Load_File (File_Name);
Interface_Root := Ocarina.Parser.Parse
(AADL_Language, Interface_Root, File_Descr);
if Deployment_Root /= No_Node then
Deployment_Root := Ocarina.Parser.Parse
(AADL_Language, Deployment_Root, File_Descr);
end if;
end loop;
if not Cfg.Data_View.Is_Empty then
Set_Str_To_Name_Buffer (Cfg.Data_View.Element);
if not Model.Configuration.Data_View.Is_Empty then
Set_Str_To_Name_Buffer (Model.Configuration.Data_View.Element);
File_Name := Ocarina.Files.Search_File (Name_Find);
if File_Name = No_Name then
raise AADL_Parser_Error
with "Could not find " & Cfg.Data_View.Element;
with "Could not find " & Model.Configuration.Data_View.Element;
end if;
else
-- Try with default name (DataView.aadl)
Set_Str_To_Name_Buffer (Default_Data_View);
File_Name := Ocarina.Files.Search_File (Name_Find);
if File_Name /= No_Name then
Cfg.Data_View := To_Holder (Default_Data_View);
elsif Cfg.Check_Data_View then
Model.Configuration.Data_View := To_Holder (Default_Data_View);
elsif Model.Configuration.Check_Data_View then
-- No dataview found, while user asked explicitly for a check
raise AADL_Parser_Error with "Could not find DataView.aadl";
end if;
end if;
if File_Name /= No_Name then
Put_Info ("Parsing " & Cfg.Data_View.Element);
Put_Info ("Parsing " & Model.Configuration.Data_View.Element);
File_Descr := Ocarina.Files.Load_File (File_Name);
......@@ -194,14 +281,13 @@ package body TASTE.AADL_Parser is
"Error parsing ConcurrencyView_Properties.aadl";
end if;
end if;
return Cfg;
end Initialize;
function Parse_Project return TASTE_Model is
Result : TASTE_Model;
use Deployment_View_Holders;
begin
Result.Configuration := Initialize;
Initialize (Model => Result);
if Interface_Root /= No_Node then
-- Parse Interface and Deployment View
......
......@@ -68,7 +68,7 @@ package TASTE.AADL_Parser is
procedure Generate_Code (Model : TASTE_Model);
private
function Initialize return Taste_Configuration;
procedure Initialize (Model : out TASTE_Model);
-- Perform various processing on a function. Return a map of possibly
-- created new functions, to be added to the new Model
......
......@@ -91,15 +91,17 @@ package body TASTE.Backend.Code_Generators is
for Each of Languages loop
Unique_Languages := Unique_Languages & To_String (Each);
end loop;
Content_Set := +Assoc ("Function_Names", Functions_Tag)
& Assoc ("Language", Language_Tag)
& Assoc ("Is_Type", Is_Type_Tag)
& Assoc ("CP_Files", All_CP_Files)
& Assoc ("Has_Context_Param", Has_Context_Param_Tag)
& Assoc ("Unique_Languages", Unique_Languages)
& Assoc ("ASN1_Files", Get_ASN1_File_List)
& Assoc ("ACN_Files", Get_ACN_File_List)
& Assoc ("ASN1_Modules", Get_Module_List);
Content_Set := Model.Configuration.To_Template
& Assoc ("Function_Names", Functions_Tag)
& Assoc ("Language", Language_Tag)
& Assoc ("Is_Type", Is_Type_Tag)
& Assoc ("CP_Files", All_CP_Files)
& Assoc ("Has_Context_Param", Has_Context_Param_Tag)
& Assoc ("Unique_Languages", Unique_Languages)
& Assoc ("ASN1_Files", Get_ASN1_File_List)
& Assoc ("ACN_Files", Get_ACN_File_List)
& Assoc ("ASN1_Modules", Get_Module_List);
Put_Debug ("Generating global Makefile");
Create (File => Output_File,
Mode => Out_File,
......@@ -157,7 +159,31 @@ package body TASTE.Backend.Code_Generators is
Put_Line (Output_File, CP_Text);
Close (Output_File);
All_CP_Files :=
All_CP_Files & ("../" & Output_Lang & To_String (CP_File_Dash));
All_CP_Files & ("../" & Output_Lang & To_String (CP_File_Dash));
-- If the function is an instance of a function that is in the
-- library of shared types, we must add its CP here, using the
-- path to the installed library (known from Model.Configuration)
if F.Instance_Of.Has_Value
and then not Model.Interface_View.Flat_Functions.Contains
(To_String (F.Instance_Of.Unsafe_Just))
then
declare
Parent : constant String :=
To_Lower (To_String (F.Instance_Of.Unsafe_Just));
Parent_Dash : Unbounded_String;
begin
for C of Parent loop
Parent_Dash := Parent_Dash & (if C = '_'
then '-'
else C);
end loop;
All_CP_Files := All_CP_Files
& (Model.Configuration.Shared_Lib_Dir
& "/" & Parent & "/" & Parent & "/" & Language_Spelling (F)
& "/" & "Context-" & Parent_Dash & ".asn");
end;
end if;
end if;
exception
when E : End_Error
......@@ -411,6 +437,8 @@ package body TASTE.Backend.Code_Generators is
end loop;
return Result : constant Translate_Set :=
+Assoc ("Name", F.Name)
& Assoc ("Is_Type", F.Is_Type)
& Assoc ("Instance_Of", F.Instance_Of.Value_Or (US ("")))
& Assoc ("Sort_Set", Unique_Sorts)
& Assoc ("Module_Set", Corr_Module)
& Assoc ("CP_Name", Names)
......
......@@ -9,22 +9,25 @@ package TASTE.Backend is
Backend_Error : exception;
function Map_Language (Language : String) return String is
(if Language = "ada" then "Ada"
elsif Language = "c" then "C"
elsif Language = "blackbox_device" then "Blackbox_C"
elsif Language = "gui" then "GUI"
elsif Language = "cpp" then "CPP"
elsif Language = "rtds" then "RTDS"
elsif Language = "sdl" then "SDL"
elsif Language = "sdl_opengeode" then "SDL"
elsif Language = "simulink" then "SIMULINK"
elsif Language = "qgenc" then "QGenC"
elsif Language = "qgenada" then "QGenAda"
elsif Language = "system_c" then "System_C"
elsif Language = "vdm" then "VDM"
elsif Language = "vhdl" then "VHDL"
elsif Language = "vhdl_brave" then "VHDL_BRAVE"
elsif Language = "micropython" then "MicroPython"
else Language);
function Language_Spelling (Func : Taste_Terminal_Function) return String is
(if Func.Language = "ada" then "Ada"
elsif Func.Language = "c" then "C"
elsif Func.Language = "blackbox_device" then "Blackbox_C"
elsif Func.Language = "gui" then "GUI"
elsif Func.Language = "cpp" then "CPP"
elsif Func.Language = "rtds" then "RTDS"
elsif Func.Language = "sdl" then "SDL"
elsif Func.Language = "sdl_opengeode" then "SDL"
elsif Func.Language = "simulink" then "SIMULINK"
elsif Func.Language = "qgenc" then "QGenC"
elsif Func.Language = "qgenada" then "QGenAda"
elsif Func.Language = "system_c" then "System_C"
elsif Func.Language = "vdm" then "VDM"
elsif Func.Language = "vhdl" then "VHDL"
elsif Func.Language = "vhdl_brave" then "VHDL_BRAVE"
elsif Func.Language = "micropython" then "MicroPython"
else To_String (Func.Language));
(Map_Language (To_String (Func.Language)));
end TASTE.Backend;
......@@ -228,6 +228,7 @@ package body TASTE.Concurrency_View is
Block_Names,
Block_Languages,
Block_Instance_Of,
Block_Is_Shared_Type,
Block_FPGAConf : Vector_Tag;
Blocks : Unbounded_String;
Part_Threads : Unbounded_String;
......@@ -398,6 +399,14 @@ package body TASTE.Concurrency_View is
Block_Instance_Of := Block_Instance_Of
& B.Ref_Function.Instance_Of.Value_Or (US (""));
-- Check if the function type for this instance is in the
-- list of shared library folders instead of in the model
Block_Is_Shared_Type := Block_Is_Shared_Type
& (B.Ref_Function.Instance_Of.Has_Value and then
CV.Configuration.Shared_Types.Contains
(To_String
(B.Ref_Function.Instance_Of.Unsafe_Just)));
for TASTE_property of B.Ref_Function.User_Properties loop
Property_Names := Property_Names & TASTE_property.Name;
Property_Values := Property_Values
......@@ -475,11 +484,10 @@ package body TASTE.Concurrency_View is
end loop;
-- Association includes Name, Coverage, CPU Info, etc.
-- (see taste-deployment_view.ads for the complete list)
Partition_Assoc := Join_Sets (Partition.Deployment_Partition
.To_Template,
Drivers_To_Template
(CV.Nodes (Node_Name)
.Deployment_Node.Drivers))
Partition_Assoc :=
Join_Sets (Partition.Deployment_Partition.To_Template,
Drivers_To_Template
(CV.Nodes (Node_Name).Deployment_Node.Drivers))
& Assoc ("Threads", Part_Threads)
& Assoc ("Thread_Names", Thread_Names)
& Assoc ("Thread_Has_Param", Thread_Has_Param)
......@@ -488,6 +496,7 @@ package body TASTE.Concurrency_View is
& Assoc ("Block_Names", Block_Names)
& Assoc ("Block_Languages", Block_Languages)
& Assoc ("Block_Instance_Of", Block_Instance_Of)
& Assoc ("Block_Is_Shared_Type", Block_Is_Shared_Type)
& Assoc ("Block_FPGAConf", Block_FPGAConf)
& Assoc ("In_Port_Names", Input_Port_Names)
& Assoc ("In_Port_Thread_Name", Input_Port_Thread_Name)
......
......@@ -333,12 +333,17 @@ package body TASTE.Parser_Utils is
end To_Template_Tag;
function To_Template (Config : Taste_Configuration) return Translate_Set is
Vec : Tag;
Vec,
Shared_Libs : Tag;
begin
for Each of Config.Other_Files loop
Vec := Vec & Each;
end loop;
for Each of Config.Shared_Types loop
Shared_Libs := Shared_Libs & Each;
end loop;
return (+Assoc ("Interface_View", Config.Interface_View.Element)
& Assoc ("Deployment_View",
(if Config.Deployment_View.Is_Empty
......@@ -356,7 +361,9 @@ package body TASTE.Parser_Utils is
& Assoc ("Debug_Flag", Config.Debug_Flag)
& Assoc ("No_Stdlib_Flag", Config.No_Stdlib)
& Assoc ("Timer_Resolution", Config.Timer_Resolution)
& Assoc ("Other_Files", Vec));
& Assoc ("Shared_Lib_Dir", Config.Shared_Lib_Dir)
& Assoc ("Shared_Types", Shared_Libs)
& Assoc ("Other_Files", Vec));
end To_Template;
procedure Debug_Dump (Config : Taste_Configuration; Output : File_Type) is
......
......@@ -192,6 +192,8 @@ package TASTE.Parser_Utils is
No_Stdlib : aliased Boolean := False;
Generate_Doc : aliased Boolean := False;
Other_Files : String_Vectors.Vector;
Shared_Lib_Dir : Unbounded_String;
Shared_Types : String_Vectors.Vector;
end record;
function To_Template (Config : Taste_Configuration) return Translate_Set;
......
......@@ -169,10 +169,16 @@ package body TASTE.Semantic_Check is
end;
exception
when Constraint_Error =>
-- if call to Element did not return anything
raise Semantic_Error with "Function not found : "
& To_String (Each.Instance_Of.Unsafe_Just) & " (specified"
& " as type of function " & To_String (Each.Name) & ")";
-- if the component type is not in the model,
-- it may not be an error: it could be a shared type
if not Model.Configuration.Shared_Types.Contains
(To_String (Each.Instance_Of.Unsafe_Just))
then
raise Semantic_Error with "Function not found : "
& To_String (Each.Instance_Of.Unsafe_Just)
& " (specified as type of function "
& To_String (Each.Name) & ")";
end if;
end;
end if;
end loop;
......
@@-- The up to date list of tags available for this template is available here:
@@-- https://taste.tuxfamily.org/wiki/index.php?title=Kazoo_Templates_Documentation#templates.2Fconcurrency_view.2Fsub.2Fsystem.tmplt
@@-- If you are using vim, go over the URL and pres gx in to follow the link
@@--
@@-- The following tags are available in this template:
@@--
@@-- @_Nodes_@ : Code generated for the nodes
......@@ -23,6 +27,9 @@ properties
"../../@_Deployment_View_@",
"../dataview/dataview_aadlv2.aadl",
"system.aadl",
@@TABLE@@
-- "@_Shared_Lib_Dir_@/@_Shared_Types_@/@_Shared_Types_@.aadl",
@@END_TABLE@@
@@IF@@ not @_No_Stdlib_Flag_@
"ocarina_components.aadl",
@@END_IF@@
......
......@@ -11,12 +11,12 @@
Context-@_REPLACE_ALL(_/-):LOWER:Name_@ DEFINITIONS ::=
BEGIN
IMPORTS
@@IF@@ @_Instance_Of_@ = ""
@@INLINE( )(\n )(;\n)@@
@@TABLE@@
@_REPLACE_ALL(_/-):Sort_Set_@ FROM @_REPLACE_ALL(_/-):Module_Set_@
@@END_TABLE@@
@@END_INLINE@@
-- Group all context parameters of this function in a record
Context-@_REPLACE_ALL(_/-):LOWER:Name_@ ::= SEQUENCE {
@@INLINE( )(,\n )(\n)@@
......@@ -28,6 +28,12 @@ Context-@_REPLACE_ALL(_/-):LOWER:Name_@ ::= SEQUENCE {
-- Declare a constant with the values set by the user in the interface view
@_REPLACE_ALL(_/-):LOWER:Name_@-ctxt Context-@_REPLACE_ALL(_/-):LOWER:Name_@ ::= {
@@ELSE@@
Context-@_LOWER:REPLACE_ALL(_/-):Instance_Of_@ FROM Context-@_LOWER:REPLACE_ALL(_/-):Instance_Of_@;
@_REPLACE_ALL(_/-):LOWER:Name_@-ctxt Context-@_LOWER:REPLACE_ALL(_/-):Instance_Of_@ ::= {
@@END_IF@@
@@INLINE( )(,\n )(\n)@@
@@TABLE@@
@_REPLACE_ALL(_/-):LOWER:CP_Name_@ @_REPLACE_ALL(_/-):CP_Value_@
......
@@-- The up to date list of tags available for this template is available here:
@@-- https://taste.tuxfamily.org/wiki/index.php?title=Kazoo_Templates_Documentation#templates.2Fskeletons.2Fmakefile.tmplt
@@-- If you are using vim, go over the URL and pres gx in to follow the link
@@-- The following tags are available in this template (maybe not up to date):
@@--
@@-- @_Function_Names_@ : Combined table: list of fuction names...
@@-- @_Language_@ : ... and corresponding implementation language
@@-- @_Is_Type_@ : ... and flag if it is a function type
@@-- @_Has_Context_Param_@ : ... and flag to indicate if function has context parameters
@@-- @_CP_Files_@ : List of all context parameters ASN.1 files
@@-- @_Unique_Languages_@ : List of all languages used in the system
@@-- @_ASN1_Files_@ : List of all ASN.1 files
@@-- @_ACN_Files_@ : List of all ACN files
@@-- @_ASN1_Modules_@ : List of all ASN.1 modules
# MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
MAKEFILE_PATH := $(lastword $(MAKEFILE_LIST))
OUTDIR := $(dir $(MAKEFILE_PATH))
......@@ -84,10 +74,7 @@ air: aadl2glueC build/system_config.h ${DATAVIEW_PATH}/built build/deploymentvie
# Rule to invoke Ocarina (generation of POHI middleware code)
build/deploymentview_final/Makefile: build/main.aadl ${DATAVIEW_AADLV2} ../ConcurrencyView_Properties.aadl
# patching the cv properties is not needed anymore, as kazoo parses
# natively the ConcurrencyView_Properties.aadl file now
#taste-patch-cv-properties.py build/system.aadl ../ConcurrencyView_Properties.aadl
cd build && ocarina -x main.aadl
cd build ; ocarina -x main.aadl
@@-- ConcurrencyView_Properties is normally always present (even if empty) as
@@-- it is generated by the GUIs... Just in case it is not there, create it.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment