rt_gccstream/gcc/ada/prj-ext.adb

364 lines
12 KiB
Ada

------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- P R J . E X T --
-- --
-- B o d y --
-- --
-- Copyright (C) 2000-2009, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 3, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNAT; see file COPYING3. If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
with System.OS_Lib; use System.OS_Lib;
with Hostparm;
with Makeutl; use Makeutl;
with Opt;
with Osint; use Osint;
with Prj.Tree; use Prj.Tree;
with Sdefault;
package body Prj.Ext is
No_Project_Default_Dir : constant String := "-";
-- Indicator in the project path to indicate that the default search
-- directories should not be added to the path
Uninitialized_Prefix : constant String := '#' & Path_Separator;
-- Prefix to indicate that the project path has not been initilized yet.
-- Must be two characters long
procedure Initialize_Project_Path (Tree : Prj.Tree.Project_Node_Tree_Ref);
-- Initialize Current_Project_Path
---------
-- Add --
---------
procedure Add
(Tree : Prj.Tree.Project_Node_Tree_Ref;
External_Name : String;
Value : String)
is
The_Key : Name_Id;
The_Value : Name_Id;
begin
Name_Len := Value'Length;
Name_Buffer (1 .. Name_Len) := Value;
The_Value := Name_Find;
Name_Len := External_Name'Length;
Name_Buffer (1 .. Name_Len) := External_Name;
Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
The_Key := Name_Find;
Name_To_Name_HTable.Set (Tree.External_References, The_Key, The_Value);
end Add;
----------------------------------
-- Add_Search_Project_Directory --
----------------------------------
procedure Add_Search_Project_Directory
(Tree : Prj.Tree.Project_Node_Tree_Ref;
Path : String)
is
Tmp : String_Access;
begin
if Tree.Project_Path = null then
Tree.Project_Path := new String'(Uninitialized_Prefix & Path);
else
Tmp := Tree.Project_Path;
Tree.Project_Path := new String'(Tmp.all & Path_Separator & Path);
Free (Tmp);
end if;
end Add_Search_Project_Directory;
-----------
-- Check --
-----------
function Check
(Tree : Prj.Tree.Project_Node_Tree_Ref;
Declaration : String) return Boolean
is
begin
for Equal_Pos in Declaration'Range loop
if Declaration (Equal_Pos) = '=' then
exit when Equal_Pos = Declaration'First;
Add
(Tree => Tree,
External_Name =>
Declaration (Declaration'First .. Equal_Pos - 1),
Value =>
Declaration (Equal_Pos + 1 .. Declaration'Last));
return True;
end if;
end loop;
return False;
end Check;
-----------------------------
-- Initialize_Project_Path --
-----------------------------
procedure Initialize_Project_Path (Tree : Prj.Tree.Project_Node_Tree_Ref) is
Add_Default_Dir : Boolean := True;
First : Positive;
Last : Positive;
New_Len : Positive;
New_Last : Positive;
Ada_Project_Path : constant String := "ADA_PROJECT_PATH";
Gpr_Project_Path : constant String := "GPR_PROJECT_PATH";
-- Name of alternate env. variable that contain path name(s) of
-- directories where project files may reside. GPR_PROJECT_PATH has
-- precedence over ADA_PROJECT_PATH.
Gpr_Prj_Path : String_Access := Getenv (Gpr_Project_Path);
Ada_Prj_Path : String_Access := Getenv (Ada_Project_Path);
-- The path name(s) of directories where project files may reside.
-- May be empty.
begin
-- The current directory is always first in the search path. Since the
-- Project_Path currently starts with '#:' as a sign that it isn't
-- initialized, we simply replace '#' with '.'
if Tree.Project_Path = null then
Tree.Project_Path := new String'('.' & Path_Separator);
else
Tree.Project_Path (Tree.Project_Path'First) := '.';
end if;
-- Then the reset of the project path (if any) currently contains the
-- directories added through Add_Search_Project_Directory
-- If environment variables are defined and not empty, add their content
if Gpr_Prj_Path.all /= "" then
Add_Search_Project_Directory (Tree, Gpr_Prj_Path.all);
end if;
Free (Gpr_Prj_Path);
if Ada_Prj_Path.all /= "" then
Add_Search_Project_Directory (Tree, Ada_Prj_Path.all);
end if;
Free (Ada_Prj_Path);
-- Copy to Name_Buffer, since we will need to manipulate the path
Name_Len := Tree.Project_Path'Length;
Name_Buffer (1 .. Name_Len) := Tree.Project_Path.all;
-- Scan the directory path to see if "-" is one of the directories.
-- Remove each occurrence of "-" and set Add_Default_Dir to False.
-- Also resolve relative paths and symbolic links.
First := 3;
loop
while First <= Name_Len
and then (Name_Buffer (First) = Path_Separator)
loop
First := First + 1;
end loop;
exit when First > Name_Len;
Last := First;
while Last < Name_Len
and then Name_Buffer (Last + 1) /= Path_Separator
loop
Last := Last + 1;
end loop;
-- If the directory is "-", set Add_Default_Dir to False and
-- remove from path.
if Name_Buffer (First .. Last) = No_Project_Default_Dir then
Add_Default_Dir := False;
for J in Last + 1 .. Name_Len loop
Name_Buffer (J - No_Project_Default_Dir'Length - 1) :=
Name_Buffer (J);
end loop;
Name_Len := Name_Len - No_Project_Default_Dir'Length - 1;
-- After removing the '-', go back one character to get the next
-- directory correctly.
Last := Last - 1;
elsif not Hostparm.OpenVMS
or else not Is_Absolute_Path (Name_Buffer (First .. Last))
then
-- On VMS, only expand relative path names, as absolute paths
-- may correspond to multi-valued VMS logical names.
declare
New_Dir : constant String :=
Normalize_Pathname
(Name_Buffer (First .. Last),
Resolve_Links => Opt.Follow_Links_For_Dirs);
begin
-- If the absolute path was resolved and is different from
-- the original, replace original with the resolved path.
if New_Dir /= Name_Buffer (First .. Last)
and then New_Dir'Length /= 0
then
New_Len := Name_Len + New_Dir'Length - (Last - First + 1);
New_Last := First + New_Dir'Length - 1;
Name_Buffer (New_Last + 1 .. New_Len) :=
Name_Buffer (Last + 1 .. Name_Len);
Name_Buffer (First .. New_Last) := New_Dir;
Name_Len := New_Len;
Last := New_Last;
end if;
end;
end if;
First := Last + 1;
end loop;
Free (Tree.Project_Path);
-- Set the initial value of Current_Project_Path
if Add_Default_Dir then
declare
Prefix : String_Ptr := Sdefault.Search_Dir_Prefix;
begin
if Prefix = null then
Prefix := new String'(Executable_Prefix_Path);
if Prefix.all /= "" then
Add_Str_To_Name_Buffer
(Path_Separator & Prefix.all &
"share" & Directory_Separator & "gpr");
Add_Str_To_Name_Buffer
(Path_Separator & Prefix.all &
Directory_Separator & "lib" &
Directory_Separator & "gnat");
end if;
else
Tree.Project_Path :=
new String'(Name_Buffer (1 .. Name_Len) & Path_Separator &
Prefix.all &
".." & Directory_Separator &
".." & Directory_Separator &
".." & Directory_Separator & "gnat");
end if;
Free (Prefix);
end;
end if;
if Tree.Project_Path = null then
Tree.Project_Path := new String'(Name_Buffer (1 .. Name_Len));
end if;
end Initialize_Project_Path;
------------------
-- Project_Path --
------------------
function Project_Path (Tree : Project_Node_Tree_Ref) return String is
begin
if Tree.Project_Path = null
or else Tree.Project_Path (Tree.Project_Path'First) = '#'
then
Initialize_Project_Path (Tree);
end if;
return Tree.Project_Path.all;
end Project_Path;
-----------
-- Reset --
-----------
procedure Reset (Tree : Prj.Tree.Project_Node_Tree_Ref) is
begin
Name_To_Name_HTable.Reset (Tree.External_References);
end Reset;
----------------------
-- Set_Project_Path --
----------------------
procedure Set_Project_Path
(Tree : Project_Node_Tree_Ref;
New_Path : String) is
begin
Free (Tree.Project_Path);
Tree.Project_Path := new String'(New_Path);
end Set_Project_Path;
--------------
-- Value_Of --
--------------
function Value_Of
(Tree : Prj.Tree.Project_Node_Tree_Ref;
External_Name : Name_Id;
With_Default : Name_Id := No_Name)
return Name_Id
is
The_Value : Name_Id;
Name : String := Get_Name_String (External_Name);
begin
Canonical_Case_File_Name (Name);
Name_Len := Name'Length;
Name_Buffer (1 .. Name_Len) := Name;
The_Value :=
Name_To_Name_HTable.Get (Tree.External_References, Name_Find);
if The_Value /= No_Name then
return The_Value;
end if;
-- Find if it is an environment, if it is, put value in the hash table
declare
Env_Value : String_Access := Getenv (Name);
begin
if Env_Value /= null and then Env_Value'Length > 0 then
Name_Len := Env_Value'Length;
Name_Buffer (1 .. Name_Len) := Env_Value.all;
The_Value := Name_Find;
Name_To_Name_HTable.Set
(Tree.External_References, External_Name, The_Value);
Free (Env_Value);
return The_Value;
else
Free (Env_Value);
return With_Default;
end if;
end;
end Value_Of;
end Prj.Ext;