44--
55
66with Ada.Characters.Handling ; use Ada.Characters.Handling;
7+ with Ada.Characters.Latin_1 ;
8+ with Ada.Containers ;
79with Ada.Directories ; use Ada.Directories;
810with Ada.Strings ; use Ada.Strings;
911with Ada.Strings.Fixed ; use Ada.Strings.Fixed;
@@ -80,6 +82,88 @@ package body Gnatcheck.Compiler is
8082 -- This function treats the provided path as case-insensitive on Windows
8183 -- systems.
8284
85+ -- -------------------------------
86+ -- Target information fetching --
87+ -- -------------------------------
88+
89+ function Get_Available_Targets return String_Sets.Set;
90+ -- Call the ``gprconfig`` tool to list all currently available targets. If
91+ -- you want the list of available targets when GNATcheck has been started,
92+ -- use the ``Available_Targets`` global to avoid useless calls.
93+
94+ function Get_Available_Targets return String_Sets.Set is
95+ Res : String_Sets.Set;
96+ GPRConfig_Exec : String_Access := Locate_Exec_On_Path (" gprconfig" );
97+ Args : Argument_List (1 .. 2 );
98+ Return_Code : Integer := -1 ;
99+ Output_File : File_Descriptor;
100+ Output_File_Name : String_Access;
101+ Output_File_Content : String_Access;
102+ Split_Content : String_Vector;
103+ begin
104+ -- If no regular "gprconfig" has been found, look for the gnatsas one
105+ if GPRConfig_Exec = null then
106+ GPRConfig_Exec := Locate_Exec_On_Path (" gnatsas-gprconfig" );
107+
108+ -- If the gnatsas "gprconfig" is not available, look for the codepeer
109+ -- one (for retro-compatibility purposes).
110+ if GPRConfig_Exec = null then
111+ GPRConfig_Exec := Locate_Exec_On_Path (" codepeer-gprconfig" );
112+
113+ -- If the result is still null, raise a fatal error. We cannot
114+ -- continue the analysis execution.
115+ if GPRConfig_Exec = null then
116+ Error (" cannot locate gprconfig executable" );
117+ raise Fatal_Error;
118+ end if ;
119+ end if ;
120+ end if ;
121+
122+ -- Create the temporary file to get the "gprbuild" output
123+ Create_Temp_Output_File (Output_File, Output_File_Name);
124+
125+ -- Prepare the argument list
126+ Args (1 ) := new String'(" --show-targets" );
127+ Args (2 ) := new String'(" --config=Ada" );
128+
129+ -- Spawn "gprconfig" to fetch the list of available targets
130+ Spawn
131+ (Program_Name => GPRConfig_Exec.all ,
132+ Args => Args,
133+ Output_File_Descriptor => Output_File,
134+ Return_Code => Return_Code,
135+ Err_To_Out => False);
136+
137+ -- Parse the output to fill the result
138+ Output_File_Content := Read_File (Output_File_Name.all );
139+ Split_Content :=
140+ Split
141+ (Output_File_Content.all ,
142+ Ada.Characters.Latin_1.LF,
143+ Trim_Elems => True);
144+ for I in Split_Content.First_Index + 1 .. Split_Content.Last_Index loop
145+ if Split_Content (I) /= " " then
146+ Res.Include (Split_Content (I));
147+ end if ;
148+ end loop ;
149+
150+ -- Release allocated resources and delete the temporary file
151+ Close (Output_File);
152+ Delete_File (Output_File_Name.all );
153+ Free (GPRConfig_Exec);
154+ Free (Output_File_Name);
155+ Free (Output_File_Content);
156+ for I in Args'Range loop
157+ Free (Args (I));
158+ end loop ;
159+
160+ -- Finally return the set of available targets
161+ return Res;
162+ end Get_Available_Targets ;
163+
164+ Available_Targets : constant String_Sets.Set := Get_Available_Targets;
165+ -- Cache containing all available targets when GNATcheck has been started.
166+
83167 -- -------------------------------------------------------
84168 -- Data structures and routines for restriction checks --
85169 -- -------------------------------------------------------
@@ -1552,35 +1636,22 @@ package body Gnatcheck.Compiler is
15521636 -- ------------------------------
15531637
15541638 function Should_Use_Codepeer_Target return Boolean is
1555- Regular_Gnatls : String_Access := Locate_Exec_On_Path ( " gnatls " ) ;
1639+ use Ada.Containers ;
15561640 begin
1557- -- If we could find a regular gnatls, it means there is a native
1558- -- toolchain, that takes precedence over a potential codepeer toolchain.
1559- if Regular_Gnatls /= null then
1560- Free (Regular_Gnatls);
1561- return False;
1562- end if ;
1563-
1564- -- If we couldn't, look for a codepeer toolchain.
1565- declare
1566- Gnatls : String_Access := Locate_Exec_On_Path (" codepeer-gnatls" );
1567- begin
1568- if Gnatls /= null then
1569- Free (Gnatls);
1570- return True;
1571- end if ;
1572- end ;
1573-
1574- return False;
1641+ return
1642+ Available_Targets.Length = 1
1643+ and then (Available_Targets.Contains (" gnatsas" )
1644+ or else Available_Targets.Contains (" codepeer" ));
15751645 end Should_Use_Codepeer_Target ;
15761646
15771647 -- -----------------
15781648 -- GPRbuild_Exec --
15791649 -- -----------------
15801650
15811651 function GPRbuild_Exec return String is
1652+ use Ada.Strings.Unbounded;
15821653 begin
1583- if Should_Use_Codepeer_Target then
1654+ if Target = " gnatsas " or else Target = " codepeer " then
15841655 return " codepeer-gprbuild" ;
15851656 else
15861657 return " gprbuild" ;
@@ -1686,9 +1757,6 @@ package body Gnatcheck.Compiler is
16861757 if Target /= Null_Unbounded_String then
16871758 Num_Args := @ + 1 ;
16881759 Args (Num_Args) := new String'(" --target=" & To_String (Target));
1689- elsif Should_Use_Codepeer_Target then
1690- Num_Args := @ + 1 ;
1691- Args (Num_Args) := new String'(" --target=codepeer" );
16921760 end if ;
16931761 else
16941762 -- Target and runtime will be taken from config project anyway
@@ -1711,8 +1779,7 @@ package body Gnatcheck.Compiler is
17111779
17121780 for Dir of Arg.Rules_Dirs.Get loop
17131781 Num_Args := @ + 1 ;
1714- Args (Num_Args) :=
1715- new String'(" --rules-dir=" & Ada.Strings.Unbounded.To_String (Dir));
1782+ Args (Num_Args) := new String'(" --rules-dir=" & To_String (Dir));
17161783 end loop ;
17171784
17181785 Num_Args := @ + 1 ;
@@ -1816,6 +1883,7 @@ package body Gnatcheck.Compiler is
18161883 Args : Argument_List (1 .. 128 + Integer (Last_Source));
18171884 Num_Args : Integer := 0 ;
18181885
1886+ use Ada.Strings.Unbounded;
18191887 begin
18201888 if GPRbuild = null then
18211889 Error (" cannot locate gprbuild executable" );
@@ -1833,9 +1901,9 @@ package body Gnatcheck.Compiler is
18331901 Args (8 ) := new String'(" --restricted-to-languages=ada" );
18341902 Num_Args := 8 ;
18351903
1836- if Should_Use_Codepeer_Target then
1904+ if Target /= Null_Unbounded_String then
18371905 Num_Args := @ + 1 ;
1838- Args (Num_Args) := new String'(" --target=codepeer " );
1906+ Args (Num_Args) := new String'(" --target=" & To_String (Target) );
18391907 end if ;
18401908
18411909 if Arg.Jobs.Get > 1 then
0 commit comments