1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2000-2009, Free Software Foundation, Inc. --
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. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with System
.OS_Lib
; use System
.OS_Lib
;
28 with Makeutl
; use Makeutl
;
29 with Osint
; use Osint
;
30 with Prj
.Tree
; use Prj
.Tree
;
33 package body Prj
.Ext
is
35 No_Project_Default_Dir
: constant String := "-";
36 -- Indicator in the project path to indicate that the default search
37 -- directories should not be added to the path
39 Uninitialized_Prefix
: constant String := '#' & Path_Separator
;
40 -- Prefix to indicate that the project path has not been initilized yet.
41 -- Must be two characters long
43 procedure Initialize_Project_Path
(Tree
: Prj
.Tree
.Project_Node_Tree_Ref
);
44 -- Initialize Current_Project_Path
51 (Tree
: Prj
.Tree
.Project_Node_Tree_Ref
;
52 External_Name
: String;
58 Name_Len
:= Value
'Length;
59 Name_Buffer
(1 .. Name_Len
) := Value
;
60 The_Value
:= Name_Find
;
61 Name_Len
:= External_Name
'Length;
62 Name_Buffer
(1 .. Name_Len
) := External_Name
;
63 Canonical_Case_File_Name
(Name_Buffer
(1 .. Name_Len
));
65 Name_To_Name_HTable
.Set
(Tree
.External_References
, The_Key
, The_Value
);
68 ----------------------------------
69 -- Add_Search_Project_Directory --
70 ----------------------------------
72 procedure Add_Search_Project_Directory
73 (Tree
: Prj
.Tree
.Project_Node_Tree_Ref
;
78 if Tree
.Project_Path
= null then
79 Tree
.Project_Path
:= new String'(Uninitialized_Prefix & Path);
81 Tmp := Tree.Project_Path;
82 Tree.Project_Path := new String'(Tmp
.all & Path_Separator
& Path
);
85 end Add_Search_Project_Directory
;
92 (Tree
: Prj
.Tree
.Project_Node_Tree_Ref
;
93 Declaration
: String) return Boolean
96 for Equal_Pos
in Declaration
'Range loop
97 if Declaration
(Equal_Pos
) = '=' then
98 exit when Equal_Pos
= Declaration
'First;
102 Declaration
(Declaration
'First .. Equal_Pos
- 1),
104 Declaration
(Equal_Pos
+ 1 .. Declaration
'Last));
112 -----------------------------
113 -- Initialize_Project_Path --
114 -----------------------------
116 procedure Initialize_Project_Path
(Tree
: Prj
.Tree
.Project_Node_Tree_Ref
) is
117 Add_Default_Dir
: Boolean := True;
123 Ada_Project_Path
: constant String := "ADA_PROJECT_PATH";
124 Gpr_Project_Path
: constant String := "GPR_PROJECT_PATH";
125 -- Name of alternate env. variable that contain path name(s) of
126 -- directories where project files may reside. GPR_PROJECT_PATH has
127 -- precedence over ADA_PROJECT_PATH.
129 Gpr_Prj_Path
: String_Access
:= Getenv
(Gpr_Project_Path
);
130 Ada_Prj_Path
: String_Access
:= Getenv
(Ada_Project_Path
);
131 -- The path name(s) of directories where project files may reside.
135 -- The current directory is always first in the search path. Since the
136 -- Project_Path currently starts with '#:' as a sign that it isn't
137 -- initialized, we simply replace '#' with '.'
139 if Tree
.Project_Path
= null then
140 Tree
.Project_Path
:= new String'('.' & Path_Separator);
142 Tree.Project_Path (Tree.Project_Path'First) := '.';
145 -- Then the reset of the project path (if any) currently contains the
146 -- directories added through Add_Search_Project_Directory
148 -- If environment variables are defined and not empty, add their content
150 if Gpr_Prj_Path.all /= "" then
151 Add_Search_Project_Directory (Tree, Gpr_Prj_Path.all);
156 if Ada_Prj_Path.all /= "" then
157 Add_Search_Project_Directory (Tree, Ada_Prj_Path.all);
162 -- Copy to Name_Buffer, since we will need to manipulate the path
164 Name_Len := Tree.Project_Path'Length;
165 Name_Buffer (1 .. Name_Len) := Tree.Project_Path.all;
167 -- Scan the directory path to see if "-" is one of the directories.
168 -- Remove each occurrence of "-" and set Add_Default_Dir to False.
169 -- Also resolve relative paths and symbolic links.
173 while First <= Name_Len
174 and then (Name_Buffer (First) = Path_Separator)
179 exit when First > Name_Len;
183 while Last < Name_Len
184 and then Name_Buffer (Last + 1) /= Path_Separator
189 -- If the directory is "-", set Add_Default_Dir to False and
192 if Name_Buffer (First .. Last) = No_Project_Default_Dir then
193 Add_Default_Dir := False;
195 for J in Last + 1 .. Name_Len loop
196 Name_Buffer (J - No_Project_Default_Dir'Length - 1) :=
200 Name_Len := Name_Len - No_Project_Default_Dir'Length - 1;
202 -- After removing the '-', go back one character to get the next
203 -- directory correctly.
207 elsif not Hostparm.OpenVMS
208 or else not Is_Absolute_Path (Name_Buffer (First .. Last))
210 -- On VMS, only expand relative path names, as absolute paths
211 -- may correspond to multi-valued VMS logical names.
214 New_Dir : constant String :=
215 Normalize_Pathname (Name_Buffer (First .. Last));
218 -- If the absolute path was resolved and is different from
219 -- the original, replace original with the resolved path.
221 if New_Dir /= Name_Buffer (First .. Last)
222 and then New_Dir'Length /= 0
224 New_Len := Name_Len + New_Dir'Length - (Last - First + 1);
225 New_Last := First + New_Dir'Length - 1;
226 Name_Buffer (New_Last + 1 .. New_Len) :=
227 Name_Buffer (Last + 1 .. Name_Len);
228 Name_Buffer (First .. New_Last) := New_Dir;
238 Free (Tree.Project_Path);
240 -- Set the initial value of Current_Project_Path
242 if Add_Default_Dir then
244 Prefix : String_Ptr := Sdefault.Search_Dir_Prefix;
247 if Prefix = null then
248 Prefix := new String'(Executable_Prefix_Path
);
250 if Prefix
.all /= "" then
251 Add_Str_To_Name_Buffer
252 (Path_Separator
& Prefix
.all &
253 "share" & Directory_Separator
& "gpr");
254 Add_Str_To_Name_Buffer
255 (Path_Separator
& Prefix
.all &
256 Directory_Separator
& "lib" &
257 Directory_Separator
& "gnat");
262 new String'(Name_Buffer (1 .. Name_Len) & Path_Separator &
264 ".." & Directory_Separator &
265 ".." & Directory_Separator &
266 ".." & Directory_Separator & "gnat");
273 if Tree.Project_Path = null then
274 Tree.Project_Path := new String'(Name_Buffer
(1 .. Name_Len
));
276 end Initialize_Project_Path
;
282 function Project_Path
(Tree
: Project_Node_Tree_Ref
) return String is
284 if Tree
.Project_Path
= null
285 or else Tree
.Project_Path
(Tree
.Project_Path
'First) = '#'
287 Initialize_Project_Path
(Tree
);
290 return Tree
.Project_Path
.all;
297 procedure Reset
(Tree
: Prj
.Tree
.Project_Node_Tree_Ref
) is
299 Name_To_Name_HTable
.Reset
(Tree
.External_References
);
302 ----------------------
303 -- Set_Project_Path --
304 ----------------------
306 procedure Set_Project_Path
307 (Tree
: Project_Node_Tree_Ref
;
308 New_Path
: String) is
310 Free
(Tree
.Project_Path
);
311 Tree
.Project_Path
:= new String'(New_Path);
312 end Set_Project_Path;
319 (Tree : Prj.Tree.Project_Node_Tree_Ref;
320 External_Name : Name_Id;
321 With_Default : Name_Id := No_Name)
325 Name : String := Get_Name_String (External_Name);
328 Canonical_Case_File_Name (Name);
329 Name_Len := Name'Length;
330 Name_Buffer (1 .. Name_Len) := Name;
332 Name_To_Name_HTable.Get (Tree.External_References, Name_Find);
334 if The_Value /= No_Name then
338 -- Find if it is an environment, if it is, put value in the hash table
341 Env_Value : String_Access := Getenv (Name);
344 if Env_Value /= null and then Env_Value'Length > 0 then
345 Name_Len := Env_Value'Length;
346 Name_Buffer (1 .. Name_Len) := Env_Value.all;
347 The_Value := Name_Find;
348 Name_To_Name_HTable.Set
349 (Tree.External_References, External_Name, The_Value);