blob: 118534b7c33e8a2d7c501453cee4884acdab2ec1 [file] [log] [blame]
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- P R J . E X T --
-- --
-- B o d y --
-- --
-- Copyright (C) 2000-2004 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 2, 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 COPYING. If not, write --
-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
-- MA 02111-1307, USA. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
with Namet; use Namet;
with Osint; use Osint;
with Sdefault;
with Types; use Types;
with GNAT.HTable;
with GNAT.OS_Lib; use GNAT.OS_Lib;
package body Prj.Ext is
Ada_Project_Path : constant String := "ADA_PROJECT_PATH";
-- Name of the env. variable that contains path name(s) of directories
-- where project files may reside.
Prj_Path : constant String_Access := Getenv (Ada_Project_Path);
-- The path name(s) of directories where project files may reside.
-- May be empty.
No_Project_Default_Dir : constant String := "-";
Current_Project_Path : String_Access;
-- The project path; initialized during elaboration of package
-- Contains at least the current working directory.
package Htable is new GNAT.HTable.Simple_HTable
(Header_Num => Header_Num,
Element => Name_Id,
No_Element => No_Name,
Key => Name_Id,
Hash => Hash,
Equal => "=");
-- External references are stored in this hash table, either by procedure
-- Add (directly or through a call to function Check) or by function
-- Value_Of when an environment variable is found non empty. Value_Of
-- first for external reference in this table, before checking the
-- environment. Htable is emptied (reset) by procedure Reset.
---------
-- Add --
---------
procedure Add
(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;
Htable.Set (The_Key, The_Value);
end Add;
-----------
-- Check --
-----------
function Check (Declaration : String) return Boolean is
begin
for Equal_Pos in Declaration'Range loop
if Declaration (Equal_Pos) = '=' then
exit when Equal_Pos = Declaration'First;
exit when Equal_Pos = Declaration'Last;
Add
(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;
------------------
-- Project_Path --
------------------
function Project_Path return String is
begin
return Current_Project_Path.all;
end Project_Path;
-----------
-- Reset --
-----------
procedure Reset is
begin
Htable.Reset;
end Reset;
----------------------
-- Set_Project_Path --
----------------------
procedure Set_Project_Path (New_Path : String) is
begin
Free (Current_Project_Path);
Current_Project_Path := new String'(New_Path);
end Set_Project_Path;
--------------
-- Value_Of --
--------------
function Value_Of
(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 := Htable.Get (Name_Find);
if The_Value /= No_Name then
return The_Value;
end if;
-- Find if it is an environment.
-- If it is, put the 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;
Htable.Set (External_Name, The_Value);
Free (Env_Value);
return The_Value;
else
Free (Env_Value);
return With_Default;
end if;
end;
end Value_Of;
begin
-- Initialize Current_Project_Path during package elaboration
declare
Add_Default_Dir : Boolean := True;
First : Positive;
Last : Positive;
begin
-- The current directory is always first
Name_Len := 1;
Name_Buffer (Name_Len) := '.';
-- If env. var. is defined and not empty, add its content
if Prj_Path.all /= "" then
Name_Len := Name_Len + 1;
Name_Buffer (Name_Len) := Path_Separator;
Add_Str_To_Name_Buffer (Prj_Path.all);
-- Scan the directory path to see if "-" is one of the directories.
-- Remove each occurence of "-" and set Add_Default_Dir to False.
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;
end if;
First := Last + 1;
end loop;
end if;
-- Set the initial value of Current_Project_Path
if Add_Default_Dir then
Current_Project_Path :=
new String'(Name_Buffer (1 .. Name_Len) & Path_Separator &
Sdefault.Search_Dir_Prefix.all & ".." &
Directory_Separator & ".." & Directory_Separator &
".." & Directory_Separator & "gnat");
else
Current_Project_Path := new String'(Name_Buffer (1 .. Name_Len));
end if;
end;
end Prj.Ext;