opt.ads, [...]: Minor reformatting
[gcc.git] / gcc / ada / prj-ext.adb
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-2009, 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 ------------------------------------------------------------------------------
25
26 with Hostparm;
27 with Makeutl; use Makeutl;
28 with Osint; use Osint;
29 with Sdefault;
30 with Table;
31
32 with GNAT.HTable;
33
34 package body Prj.Ext is
35
36 Ada_Project_Path : constant String := "ADA_PROJECT_PATH";
37 -- Name of alternate env. variable that contain path name(s) of directories
38 -- where project files may reside. GPR_PROJECT_PATH has precedence over
39 -- ADA_PROJECT_PATH.
40
41 Gpr_Prj_Path : constant String_Access := Getenv (Gpr_Project_Path);
42 Ada_Prj_Path : constant String_Access := Getenv (Ada_Project_Path);
43 -- The path name(s) of directories where project files may reside.
44 -- May be empty.
45
46 No_Project_Default_Dir : constant String := "-";
47
48 Current_Project_Path : String_Access;
49 -- The project path. Initialized by procedure Initialize_Project_Path
50 -- below.
51
52 procedure Initialize_Project_Path;
53 -- Initialize Current_Project_Path
54
55 package Htable is new GNAT.HTable.Simple_HTable
56 (Header_Num => Header_Num,
57 Element => Name_Id,
58 No_Element => No_Name,
59 Key => Name_Id,
60 Hash => Hash,
61 Equal => "=");
62 -- External references are stored in this hash table, either by procedure
63 -- Add (directly or through a call to function Check) or by function
64 -- Value_Of when an environment variable is found non empty. Value_Of
65 -- first for external reference in this table, before checking the
66 -- environment. Htable is emptied (reset) by procedure Reset.
67
68 package Search_Directories is new Table.Table
69 (Table_Component_Type => Name_Id,
70 Table_Index_Type => Natural,
71 Table_Low_Bound => 1,
72 Table_Initial => 4,
73 Table_Increment => 100,
74 Table_Name => "Prj.Ext.Search_Directories");
75 -- The table for the directories specified with -aP switches
76
77 ---------
78 -- Add --
79 ---------
80
81 procedure Add
82 (External_Name : String;
83 Value : String)
84 is
85 The_Key : Name_Id;
86 The_Value : Name_Id;
87 begin
88 Name_Len := Value'Length;
89 Name_Buffer (1 .. Name_Len) := Value;
90 The_Value := Name_Find;
91 Name_Len := External_Name'Length;
92 Name_Buffer (1 .. Name_Len) := External_Name;
93 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
94 The_Key := Name_Find;
95 Htable.Set (The_Key, The_Value);
96 end Add;
97
98 -----------
99 ----------------------------------
100 -- Add_Search_Project_Directory --
101 ----------------------------------
102
103 procedure Add_Search_Project_Directory (Path : String) is
104 begin
105 Name_Len := 0;
106 Add_Str_To_Name_Buffer (Path);
107 Search_Directories.Append (Name_Find);
108 end Add_Search_Project_Directory;
109
110 -- Check --
111 -----------
112
113 function Check (Declaration : String) return Boolean is
114 begin
115 for Equal_Pos in Declaration'Range loop
116 if Declaration (Equal_Pos) = '=' then
117 exit when Equal_Pos = Declaration'First;
118 exit when Equal_Pos = Declaration'Last;
119 Add
120 (External_Name =>
121 Declaration (Declaration'First .. Equal_Pos - 1),
122 Value =>
123 Declaration (Equal_Pos + 1 .. Declaration'Last));
124 return True;
125 end if;
126 end loop;
127
128 return False;
129 end Check;
130
131 -----------------------------
132 -- Initialize_Project_Path --
133 -----------------------------
134
135 procedure Initialize_Project_Path is
136 Add_Default_Dir : Boolean := True;
137 First : Positive;
138 Last : Positive;
139 New_Len : Positive;
140 New_Last : Positive;
141
142 begin
143 -- The current directory is always first
144
145 Name_Len := 1;
146 Name_Buffer (Name_Len) := '.';
147
148 -- If there are directories in the Search_Directories table, add them
149
150 for J in 1 .. Search_Directories.Last loop
151 Name_Len := Name_Len + 1;
152 Name_Buffer (Name_Len) := Path_Separator;
153 Add_Str_To_Name_Buffer
154 (Get_Name_String (Search_Directories.Table (J)));
155 end loop;
156
157 -- If environment variable is defined and not empty, add its content
158
159 if Gpr_Prj_Path.all /= "" then
160 Name_Len := Name_Len + 1;
161 Name_Buffer (Name_Len) := Path_Separator;
162 Add_Str_To_Name_Buffer (Gpr_Prj_Path.all);
163 end if;
164
165 if Ada_Prj_Path.all /= "" then
166 Name_Len := Name_Len + 1;
167 Name_Buffer (Name_Len) := Path_Separator;
168 Add_Str_To_Name_Buffer (Ada_Prj_Path.all);
169 end if;
170
171 -- Scan the directory path to see if "-" is one of the directories.
172 -- Remove each occurrence of "-" and set Add_Default_Dir to False.
173 -- Also resolve relative paths and symbolic links.
174
175 First := 3;
176 loop
177 while First <= Name_Len
178 and then (Name_Buffer (First) = Path_Separator)
179 loop
180 First := First + 1;
181 end loop;
182
183 exit when First > Name_Len;
184
185 Last := First;
186
187 while Last < Name_Len
188 and then Name_Buffer (Last + 1) /= Path_Separator
189 loop
190 Last := Last + 1;
191 end loop;
192
193 -- If the directory is "-", set Add_Default_Dir to False and
194 -- remove from path.
195
196 if Name_Buffer (First .. Last) = No_Project_Default_Dir then
197 Add_Default_Dir := False;
198
199 for J in Last + 1 .. Name_Len loop
200 Name_Buffer (J - No_Project_Default_Dir'Length - 1) :=
201 Name_Buffer (J);
202 end loop;
203
204 Name_Len := Name_Len - No_Project_Default_Dir'Length - 1;
205
206 -- After removing the '-', go back one character to get the next
207 -- directory correctly.
208
209 Last := Last - 1;
210
211 elsif not Hostparm.OpenVMS
212 or else not Is_Absolute_Path (Name_Buffer (First .. Last))
213 then
214 -- On VMS, only expand relative path names, as absolute paths
215 -- may correspond to multi-valued VMS logical names.
216
217 declare
218 New_Dir : constant String :=
219 Normalize_Pathname (Name_Buffer (First .. Last));
220
221 begin
222 -- If the absolute path was resolved and is different from
223 -- the original, replace original with the resolved path.
224
225 if New_Dir /= Name_Buffer (First .. Last)
226 and then New_Dir'Length /= 0
227 then
228 New_Len := Name_Len + New_Dir'Length - (Last - First + 1);
229 New_Last := First + New_Dir'Length - 1;
230 Name_Buffer (New_Last + 1 .. New_Len) :=
231 Name_Buffer (Last + 1 .. Name_Len);
232 Name_Buffer (First .. New_Last) := New_Dir;
233 Name_Len := New_Len;
234 Last := New_Last;
235 end if;
236 end;
237 end if;
238
239 First := Last + 1;
240 end loop;
241
242 -- Set the initial value of Current_Project_Path
243
244 if Add_Default_Dir then
245 declare
246 Prefix : String_Ptr := Sdefault.Search_Dir_Prefix;
247
248 begin
249 if Prefix = null then
250 Prefix := new String'(Executable_Prefix_Path);
251
252 if Prefix.all /= "" then
253 Add_Str_To_Name_Buffer
254 (Path_Separator & Prefix.all &
255 "share" & Directory_Separator & "gpr");
256 Add_Str_To_Name_Buffer
257 (Path_Separator & Prefix.all &
258 Directory_Separator & "lib" &
259 Directory_Separator & "gnat");
260 end if;
261
262 else
263 Current_Project_Path :=
264 new String'(Name_Buffer (1 .. Name_Len) & Path_Separator &
265 Prefix.all &
266 ".." & Directory_Separator &
267 ".." & Directory_Separator &
268 ".." & Directory_Separator & "gnat");
269 end if;
270
271 Free (Prefix);
272 end;
273 end if;
274
275 if Current_Project_Path = null then
276 Current_Project_Path := new String'(Name_Buffer (1 .. Name_Len));
277 end if;
278 end Initialize_Project_Path;
279
280 ------------------
281 -- Project_Path --
282 ------------------
283
284 function Project_Path return String is
285 begin
286 if Current_Project_Path = null then
287 Initialize_Project_Path;
288 end if;
289
290 return Current_Project_Path.all;
291 end Project_Path;
292
293 -----------
294 -- Reset --
295 -----------
296
297 procedure Reset is
298 begin
299 Htable.Reset;
300 end Reset;
301
302 ----------------------
303 -- Set_Project_Path --
304 ----------------------
305
306 procedure Set_Project_Path (New_Path : String) is
307 begin
308 Free (Current_Project_Path);
309 Current_Project_Path := new String'(New_Path);
310 end Set_Project_Path;
311
312 --------------
313 -- Value_Of --
314 --------------
315
316 function Value_Of
317 (External_Name : Name_Id;
318 With_Default : Name_Id := No_Name)
319 return Name_Id
320 is
321 The_Value : Name_Id;
322 Name : String := Get_Name_String (External_Name);
323
324 begin
325 Canonical_Case_File_Name (Name);
326 Name_Len := Name'Length;
327 Name_Buffer (1 .. Name_Len) := Name;
328 The_Value := Htable.Get (Name_Find);
329
330 if The_Value /= No_Name then
331 return The_Value;
332 end if;
333
334 -- Find if it is an environment, if it is, put value in the hash table
335
336 declare
337 Env_Value : String_Access := Getenv (Name);
338
339 begin
340 if Env_Value /= null and then Env_Value'Length > 0 then
341 Name_Len := Env_Value'Length;
342 Name_Buffer (1 .. Name_Len) := Env_Value.all;
343 The_Value := Name_Find;
344 Htable.Set (External_Name, The_Value);
345 Free (Env_Value);
346 return The_Value;
347
348 else
349 Free (Env_Value);
350 return With_Default;
351 end if;
352 end;
353 end Value_Of;
354
355 end Prj.Ext;