re PR rtl-optimization/34522 (inefficient code for long long multiply when only low...
[official-gcc.git] / gcc / ada / prj-ext.adb
blob686ca51598936f01a54422b5834aa203ee9ace0a
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- P R J . E X T --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2000-2007, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
26 with Hostparm;
27 with Makeutl; use Makeutl;
28 with Output; use Output;
29 with Osint; use Osint;
30 with Sdefault;
31 with Table;
33 with GNAT.HTable;
35 package body Prj.Ext is
37 Ada_Project_Path : constant String := "ADA_PROJECT_PATH";
38 -- Name of alternate env. variable that contain path name(s) of directories
39 -- where project files may reside. GPR_PROJECT_PATH has precedence over
40 -- ADA_PROJECT_PATH.
42 Gpr_Prj_Path : constant String_Access := Getenv (Gpr_Project_Path);
43 Ada_Prj_Path : constant String_Access := Getenv (Ada_Project_Path);
44 -- The path name(s) of directories where project files may reside.
45 -- May be empty.
47 No_Project_Default_Dir : constant String := "-";
49 Current_Project_Path : String_Access;
50 -- The project path. Initialized by procedure Initialize_Project_Path
51 -- below.
53 procedure Initialize_Project_Path;
54 -- Initialize Current_Project_Path
56 package Htable is new GNAT.HTable.Simple_HTable
57 (Header_Num => Header_Num,
58 Element => Name_Id,
59 No_Element => No_Name,
60 Key => Name_Id,
61 Hash => Hash,
62 Equal => "=");
63 -- External references are stored in this hash table, either by procedure
64 -- Add (directly or through a call to function Check) or by function
65 -- Value_Of when an environment variable is found non empty. Value_Of
66 -- first for external reference in this table, before checking the
67 -- environment. Htable is emptied (reset) by procedure Reset.
69 package Search_Directories is new Table.Table
70 (Table_Component_Type => Name_Id,
71 Table_Index_Type => Natural,
72 Table_Low_Bound => 1,
73 Table_Initial => 4,
74 Table_Increment => 100,
75 Table_Name => "Prj.Ext.Search_Directories");
76 -- The table for the directories specified with -aP switches
78 ---------
79 -- Add --
80 ---------
82 procedure Add
83 (External_Name : String;
84 Value : String)
86 The_Key : Name_Id;
87 The_Value : Name_Id;
88 begin
89 Name_Len := Value'Length;
90 Name_Buffer (1 .. Name_Len) := Value;
91 The_Value := Name_Find;
92 Name_Len := External_Name'Length;
93 Name_Buffer (1 .. Name_Len) := External_Name;
94 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
95 The_Key := Name_Find;
96 Htable.Set (The_Key, The_Value);
97 end Add;
99 -----------
100 ----------------------------------
101 -- Add_Search_Project_Directory --
102 ----------------------------------
104 procedure Add_Search_Project_Directory (Path : String) is
105 begin
106 Name_Len := 0;
107 Add_Str_To_Name_Buffer (Path);
108 Search_Directories.Append (Name_Find);
109 end Add_Search_Project_Directory;
111 -- Check --
112 -----------
114 function Check (Declaration : String) return Boolean is
115 begin
116 for Equal_Pos in Declaration'Range loop
117 if Declaration (Equal_Pos) = '=' then
118 exit when Equal_Pos = Declaration'First;
119 exit when Equal_Pos = Declaration'Last;
121 (External_Name =>
122 Declaration (Declaration'First .. Equal_Pos - 1),
123 Value =>
124 Declaration (Equal_Pos + 1 .. Declaration'Last));
125 return True;
126 end if;
127 end loop;
129 return False;
130 end Check;
132 -----------------------------
133 -- Initialize_Project_Path --
134 -----------------------------
136 procedure Initialize_Project_Path is
137 Add_Default_Dir : Boolean := True;
138 First : Positive;
139 Last : Positive;
140 New_Len : Positive;
141 New_Last : Positive;
142 Prj_Path : String_Access := Gpr_Prj_Path;
144 begin
145 if Gpr_Prj_Path.all /= "" then
147 -- In Ada only mode, warn if both environment variables are defined
149 if Get_Mode = Ada_Only and then Ada_Prj_Path.all /= "" then
150 Write_Line
151 ("Warning: ADA_PROJECT_PATH is not taken into account");
152 Write_Line (" when GPR_PROJECT_PATH is defined");
153 end if;
155 else
156 Prj_Path := Ada_Prj_Path;
157 end if;
159 -- The current directory is always first
161 Name_Len := 1;
162 Name_Buffer (Name_Len) := '.';
164 -- If there are directories in the Search_Directories table, add them
166 for J in 1 .. Search_Directories.Last loop
167 Name_Len := Name_Len + 1;
168 Name_Buffer (Name_Len) := Path_Separator;
169 Add_Str_To_Name_Buffer
170 (Get_Name_String (Search_Directories.Table (J)));
171 end loop;
173 -- If environment variable is defined and not empty, add its content
175 if Prj_Path.all /= "" then
176 Name_Len := Name_Len + 1;
177 Name_Buffer (Name_Len) := Path_Separator;
179 Add_Str_To_Name_Buffer (Prj_Path.all);
180 end if;
182 -- Scan the directory path to see if "-" is one of the directories.
183 -- Remove each occurence of "-" and set Add_Default_Dir to False.
184 -- Also resolve relative paths and symbolic links.
186 First := 3;
187 loop
188 while First <= Name_Len
189 and then (Name_Buffer (First) = Path_Separator)
190 loop
191 First := First + 1;
192 end loop;
194 exit when First > Name_Len;
196 Last := First;
198 while Last < Name_Len
199 and then Name_Buffer (Last + 1) /= Path_Separator
200 loop
201 Last := Last + 1;
202 end loop;
204 -- If the directory is "-", set Add_Default_Dir to False and
205 -- remove from path.
207 if Name_Buffer (First .. Last) = No_Project_Default_Dir then
208 Add_Default_Dir := False;
210 for J in Last + 1 .. Name_Len loop
211 Name_Buffer (J - No_Project_Default_Dir'Length - 1) :=
212 Name_Buffer (J);
213 end loop;
215 Name_Len := Name_Len - No_Project_Default_Dir'Length - 1;
217 -- After removing the '-', go back one character to get the next
218 -- directory correctly.
220 Last := Last - 1;
222 elsif not Hostparm.OpenVMS
223 or else not Is_Absolute_Path (Name_Buffer (First .. Last))
224 then
225 -- On VMS, only expand relative path names, as absolute paths
226 -- may correspond to multi-valued VMS logical names.
228 declare
229 New_Dir : constant String :=
230 Normalize_Pathname (Name_Buffer (First .. Last));
232 begin
233 -- If the absolute path was resolved and is different from
234 -- the original, replace original with the resolved path.
236 if New_Dir /= Name_Buffer (First .. Last)
237 and then New_Dir'Length /= 0
238 then
239 New_Len := Name_Len + New_Dir'Length - (Last - First + 1);
240 New_Last := First + New_Dir'Length - 1;
241 Name_Buffer (New_Last + 1 .. New_Len) :=
242 Name_Buffer (Last + 1 .. Name_Len);
243 Name_Buffer (First .. New_Last) := New_Dir;
244 Name_Len := New_Len;
245 Last := New_Last;
246 end if;
247 end;
248 end if;
250 First := Last + 1;
251 end loop;
253 -- Set the initial value of Current_Project_Path
255 if Add_Default_Dir then
256 declare
257 Prefix : String_Ptr := Sdefault.Search_Dir_Prefix;
258 begin
259 if Prefix = null then
260 Prefix := new String'(Executable_Prefix_Path);
262 if Prefix.all /= "" then
263 if Get_Mode = Ada_Only then
264 Current_Project_Path :=
265 new String'(Name_Buffer (1 .. Name_Len) &
266 Path_Separator &
267 Prefix.all & Directory_Separator & "gnat");
269 else
270 Current_Project_Path :=
271 new String'(Name_Buffer (1 .. Name_Len) &
272 Path_Separator &
273 Prefix.all & Directory_Separator &
274 "share" & Directory_Separator & "gpr");
275 end if;
276 end if;
278 else
279 Current_Project_Path :=
280 new String'(Name_Buffer (1 .. Name_Len) & Path_Separator &
281 Prefix.all &
282 ".." & Directory_Separator &
283 ".." & Directory_Separator &
284 ".." & Directory_Separator & "gnat");
285 end if;
286 end;
287 end if;
289 if Current_Project_Path = null then
290 Current_Project_Path := new String'(Name_Buffer (1 .. Name_Len));
291 end if;
292 end Initialize_Project_Path;
294 ------------------
295 -- Project_Path --
296 ------------------
298 function Project_Path return String is
299 begin
300 if Current_Project_Path = null then
301 Initialize_Project_Path;
302 end if;
304 return Current_Project_Path.all;
305 end Project_Path;
307 -----------
308 -- Reset --
309 -----------
311 procedure Reset is
312 begin
313 Htable.Reset;
314 end Reset;
316 ----------------------
317 -- Set_Project_Path --
318 ----------------------
320 procedure Set_Project_Path (New_Path : String) is
321 begin
322 Free (Current_Project_Path);
323 Current_Project_Path := new String'(New_Path);
324 end Set_Project_Path;
326 --------------
327 -- Value_Of --
328 --------------
330 function Value_Of
331 (External_Name : Name_Id;
332 With_Default : Name_Id := No_Name)
333 return Name_Id
335 The_Value : Name_Id;
336 Name : String := Get_Name_String (External_Name);
338 begin
339 Canonical_Case_File_Name (Name);
340 Name_Len := Name'Length;
341 Name_Buffer (1 .. Name_Len) := Name;
342 The_Value := Htable.Get (Name_Find);
344 if The_Value /= No_Name then
345 return The_Value;
346 end if;
348 -- Find if it is an environment, if it is, put value in the hash table
350 declare
351 Env_Value : String_Access := Getenv (Name);
353 begin
354 if Env_Value /= null and then Env_Value'Length > 0 then
355 Name_Len := Env_Value'Length;
356 Name_Buffer (1 .. Name_Len) := Env_Value.all;
357 The_Value := Name_Find;
358 Htable.Set (External_Name, The_Value);
359 Free (Env_Value);
360 return The_Value;
362 else
363 Free (Env_Value);
364 return With_Default;
365 end if;
366 end;
367 end Value_Of;
369 end Prj.Ext;