|
4 | 4 | -- |
5 | 5 |
|
6 | 6 | with Ada.Characters.Handling; use Ada.Characters.Handling; |
| 7 | +with Ada.Characters.Latin_1; |
| 8 | +with Ada.Containers; |
7 | 9 | with Ada.Directories; use Ada.Directories; |
8 | 10 | with Ada.Strings; use Ada.Strings; |
9 | 11 | with Ada.Strings.Fixed; use Ada.Strings.Fixed; |
@@ -80,6 +82,88 @@ package body Gnatcheck.Compiler is |
80 | 82 | -- This function treats the provided path as case-insensitive on Windows |
81 | 83 | -- systems. |
82 | 84 |
|
| 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 | + |
83 | 167 | --------------------------------------------------------- |
84 | 168 | -- Data structures and routines for restriction checks -- |
85 | 169 | --------------------------------------------------------- |
@@ -1552,26 +1636,12 @@ package body Gnatcheck.Compiler is |
1552 | 1636 | -------------------------------- |
1553 | 1637 |
|
1554 | 1638 | function Should_Use_Codepeer_Target return Boolean is |
1555 | | - Regular_Gnatls : String_Access := Locate_Exec_On_Path ("gnatls"); |
| 1639 | + use Ada.Containers; |
1556 | 1640 | 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 ("codepeer") |
| 1644 | + or else Available_Targets.Contains ("gnatsas")); |
1575 | 1645 | end Should_Use_Codepeer_Target; |
1576 | 1646 |
|
1577 | 1647 | ------------------- |
|
0 commit comments