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-2003 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 2,  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 COPYING.  If not, write --
19-- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
20-- MA 02111-1307, USA.                                                      --
21--                                                                          --
22-- GNAT was originally developed  by the GNAT team at  New York University. --
23-- Extensive contributions were provided by Ada Core Technologies Inc.      --
24--                                                                          --
25------------------------------------------------------------------------------
26
27with Namet;   use Namet;
28with Osint;   use Osint;
29with Prj.Com; use Prj.Com;
30with Types;   use Types;
31
32with GNAT.HTable;
33with GNAT.OS_Lib; use GNAT.OS_Lib;
34
35package body Prj.Ext is
36
37   package Htable is new GNAT.HTable.Simple_HTable
38     (Header_Num => Header_Num,
39      Element    => Name_Id,
40      No_Element => No_Name,
41      Key        => Name_Id,
42      Hash       => Hash,
43      Equal      => "=");
44   --  External references are stored in this hash table, either by procedure
45   --  Add (directly or through a call to function Check) or by function
46   --  Value_Of when an environment variable is found non empty. Value_Of
47   --  first for external reference in this table, before checking the
48   --  environment. Htable is emptied (reset) by procedure Reset.
49
50   ---------
51   -- Add --
52   ---------
53
54   procedure Add
55     (External_Name : String;
56      Value         : String)
57   is
58      The_Key   : Name_Id;
59      The_Value : Name_Id;
60
61   begin
62      Name_Len := Value'Length;
63      Name_Buffer (1 .. Name_Len) := Value;
64      The_Value := Name_Find;
65      Name_Len := External_Name'Length;
66      Name_Buffer (1 .. Name_Len) := External_Name;
67      Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
68      The_Key := Name_Find;
69      Htable.Set (The_Key, The_Value);
70   end Add;
71
72   -----------
73   -- Check --
74   -----------
75
76   function Check (Declaration : String) return Boolean is
77   begin
78      for Equal_Pos in Declaration'Range loop
79         if Declaration (Equal_Pos) = '=' then
80            exit when Equal_Pos = Declaration'First;
81            exit when Equal_Pos = Declaration'Last;
82            Add
83              (External_Name =>
84                 Declaration (Declaration'First .. Equal_Pos - 1),
85               Value =>
86                 Declaration (Equal_Pos + 1 .. Declaration'Last));
87            return True;
88         end if;
89      end loop;
90
91      return False;
92   end Check;
93
94   -----------
95   -- Reset --
96   -----------
97
98   procedure Reset is
99   begin
100      Htable.Reset;
101   end Reset;
102
103   --------------
104   -- Value_Of --
105   --------------
106
107   function Value_Of
108     (External_Name : Name_Id;
109      With_Default  : Name_Id := No_Name)
110      return          Name_Id
111   is
112      The_Value : Name_Id;
113      Name      : String := Get_Name_String (External_Name);
114
115   begin
116      Canonical_Case_File_Name (Name);
117      Name_Len := Name'Length;
118      Name_Buffer (1 .. Name_Len) := Name;
119      The_Value := Htable.Get (Name_Find);
120
121      if The_Value /= No_Name then
122         return The_Value;
123      end if;
124
125      --  Find if it is an environment.
126      --  If it is, put the value in the hash table.
127
128      declare
129         Env_Value : String_Access := Getenv (Name);
130
131      begin
132         if Env_Value /= null and then Env_Value'Length > 0 then
133            Name_Len := Env_Value'Length;
134            Name_Buffer (1 .. Name_Len) := Env_Value.all;
135            The_Value := Name_Find;
136            Htable.Set (External_Name, The_Value);
137            Free (Env_Value);
138            return The_Value;
139
140         else
141            Free (Env_Value);
142            return With_Default;
143         end if;
144      end;
145   end Value_Of;
146
147end Prj.Ext;
148