-------------------------------------------------- ------------------------------ -- -- -- OCARINA COMPONENTS -- -- -- -- O C A R I N A . G E N E R A T O R S -- -- -- -- B o d y -- -- -- -- Copyright (C) 2007, GET-Telecom Paris. -- -- -- -- Ocarina is free software; you can redistribute it and/or modify -- -- it under terms of the GNU General Public License as published by the -- -- Free Software Foundation; either version 2, or (at your option) any -- -- later version. Ocarina is distributed in the hope that it will be -- -- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -- -- Public License for more details. You should have received a copy of the -- -- GNU General Public License distributed with Ocarina; see file COPYING. -- -- If not, write to the Free Software Foundation, 51 Franklin Street, Fifth -- -- Floor, Boston, MA 02111-1301, USA. -- -- -- -- As a special exception, if other files instantiate generics from this -- -- unit, or you link this unit with other files to produce an executable, -- -- this unit does not by itself cause the resulting executable to be -- -- covered by the GNU General Public License. This exception does not -- -- however invalidate any other reasons why the executable file might be -- -- covered by the GNU Public License. -- -- -- -- Ocarina is maintained by the Ocarina team -- -- (ocarina-users@listes.enst.fr) -- -- -- ------------------------------------------------------------------------------ with GNAT.OS_Lib; use GNAT.OS_Lib; with GNAT.Directory_Operations; use GNAT.Directory_Operations; with Namet; use Namet; with Output; use Output; with Ocarina.Expander; with Ocarina.Generators.Utils; with Ocarina.Generators.Build_Utils; with Ocarina.Generators.Messages; with Ocarina.Generators.PO_HI_Ada; with Ocarina.Generators.PO_HI_C; with Ocarina.Generators.PO_QoS_Ada; with Ocarina.Generators.Properties; with Ocarina.Generators.Ada_Tree.Nodes; with Ocarina.Generators.Ada_Tree.Nutils; with Ocarina.Generators.Ada_Values; with Ocarina.Generators.C_Tree.Nodes; with Ocarina.Generators.C_Tree.Nutils; with Ocarina.Generators.C_Values; package body Ocarina.Generators is use Ocarina.Expander; use Ocarina.Generators.Utils; use Ocarina.Generators.Messages; type generator_entry is record The_Generator_Access : generator_access; The_Generator_Kind : generator_kind; -- A generator has to know its kind The_Generator_Name : name_id; end record; Null_Generator_Entry : constant generator_entry := (null, invalid_generator, No_Name); Current_Generator : generator_entry := Null_Generator_Entry; -- The latest selected code generator Generator_Table : array (generator_kind) of generator_entry := (others => Null_Generator_Entry); -- The internal table where the information corresponding the -- registered code generator is stored. ---------------------------- -- Current_Generator_Kind -- ---------------------------- function Current_Generator_Kind return generator_kind is begin return Current_Generator.The_Generator_Kind; end Current_Generator_Kind; ------------------- -- Generate_Code -- ------------------- procedure Generate_Code (Distributed_Application_Root : node_id; Options : generator_options := Default_Options) is Instance_Root : node_id; begin -- Instantiation of the AADL tree Instance_Root := Expand_Model (Distributed_Application_Root); -- Abort if the instantiation failed if No (Instance_Root) then Display_Error ("The AADL model cannot be expanded.", Fatal => True); end if; -- At this point, we have a valid AADL architecture instance, -- we can begin the code generation. -- FIXME: Select the code generator according to information -- given in the instance root system. if Current_Generator = Null_Generator_Entry then Display_Error ("No generator has been selected yet", Fatal => True); end if; -- Set the working directory Working_Directory := Options.Working_Directory; -- Call the current generator entry point Current_Generator.The_Generator_Access.all (Instance_Root, Options); end Generate_Code; ---------- -- Init -- ---------- procedure Init is begin Default_Options := (Clean => False, Build => False, Output_Directory => Get_String_Name ("."), Working_Directory => Get_String_Name (Normalize_Pathname (Get_Current_Dir))); Properties.Init; Ada_Tree.Nutils.Initialize; C_Tree.Nutils.Initialize; -- Register the several code generators PO_HI_Ada.Init; PO_QoS_Ada.Init; PO_HI_C.Init; end Init; ----------- -- Reset -- ----------- procedure Reset is begin PO_HI_Ada.Reset; PO_HI_C.Reset; PO_QoS_Ada.Reset; Ada_Tree.Nodes.Entries.Free; Ada_Tree.Nodes.Entries.Init; Ada_Values.Reset; C_Tree.Nodes.Entries.Free; C_Tree.Nodes.Entries.Init; C_Values.Reset; Build_Utils.Reset; Generator_Table := (others => Null_Generator_Entry); end Reset; ------------------------ -- Register_Generator -- ------------------------ procedure Register_Generator (The_Generator_Access : generator_access; The_Generator_Kind : generator_kind; The_Generator_Name : String) is G : generator_entry; begin -- Raise an error if the given information is incomplete if The_Generator_Access = null or else The_Generator_Name = "" then Display_Error ("Incomplete generator information", Fatal => True); end if; -- Raise an error if a generator having the same kind has been -- already registered. if Generator_Table (The_Generator_Kind) /= Null_Generator_Entry then Display_Error (Get_Name_String (Generator_Table (The_Generator_Kind).The_Generator_Name) & ": This generator has already been registered", Fatal => True); end if; G.The_Generator_Access := The_Generator_Access; G.The_Generator_Kind := The_Generator_Kind; Set_Str_To_Name_Buffer (The_Generator_Name); G.The_Generator_Name := Name_Find; Generator_Table (The_Generator_Kind) := G; end Register_Generator; ---------------------- -- Select_Generator -- ---------------------- procedure Select_Generator (The_Generator_Name : String) is Name : name_id; Found : Boolean := False; begin if The_Generator_Name = "" then Display_Error ("Null generator name", Fatal => True); end if; Set_Str_To_Name_Buffer (The_Generator_Name); Name := Name_Find; for I in Generator_Table'range loop if Generator_Table (I).The_Generator_Name = Name then Current_Generator := Generator_Table (I); Found := True; exit; end if; end loop; if not Found then Display_Error (The_Generator_Name & ": Generator not found", Fatal => True); end if; end Select_Generator; ---------------------- -- Select_Generator -- ---------------------- procedure Select_Generator (The_Generator_Kind : generator_kind) is G : constant generator_entry := Generator_Table (The_Generator_Kind); begin if G = Null_Generator_Entry then Display_Error (The_Generator_Kind'img & ": Generator not registered", Fatal => True); end if; Current_Generator := G; end Select_Generator; ---------------------- -- Write_Generators -- ---------------------- procedure Write_Generators (Indent : Natural) is begin for Index in 1 .. Indent loop Write_Char (' '); end loop; Write_Line ("Registered generators:"); for I in Generator_Table'range loop if Generator_Table (I) /= Null_Generator_Entry then for Index in 1 .. Indent + 1 loop Write_Char (' '); end loop; Write_Name (Generator_Table (I).The_Generator_Name); Write_Eol; end if; end loop; end Write_Generators; end Ocarina.Generators;