2015-09-28 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / ada / prj-ext.adb
blob5f134008b1cec0d496edbe15f03022aa05a78eb9
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-2013, 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 ------------------------------------------------------------------------------
26 with Osint; use Osint;
28 with Ada.Unchecked_Deallocation;
30 package body Prj.Ext is
32 ----------------
33 -- Initialize --
34 ----------------
36 procedure Initialize
37 (Self : out External_References;
38 Copy_From : External_References := No_External_Refs)
40 N : Name_To_Name_Ptr;
41 N2 : Name_To_Name_Ptr;
42 begin
43 if Self.Refs = null then
44 Self.Refs := new Name_To_Name_HTable.Instance;
46 if Copy_From.Refs /= null then
47 N := Name_To_Name_HTable.Get_First (Copy_From.Refs.all);
48 while N /= null loop
49 N2 := new Name_To_Name'
50 (Key => N.Key,
51 Value => N.Value,
52 Source => N.Source,
53 Next => null);
54 Name_To_Name_HTable.Set (Self.Refs.all, N2);
55 N := Name_To_Name_HTable.Get_Next (Copy_From.Refs.all);
56 end loop;
57 end if;
58 end if;
59 end Initialize;
61 ---------
62 -- Add --
63 ---------
65 procedure Add
66 (Self : External_References;
67 External_Name : String;
68 Value : String;
69 Source : External_Source := External_Source'First;
70 Silent : Boolean := False)
72 Key : Name_Id;
73 N : Name_To_Name_Ptr;
75 begin
76 -- For external attribute, set the environment variable
78 if Source = From_External_Attribute and then External_Name /= "" then
79 declare
80 Env_Var : String_Access := Getenv (External_Name);
82 begin
83 if Env_Var = null or else Env_Var.all = "" then
84 Setenv (Name => External_Name, Value => Value);
86 if not Silent then
87 Debug_Output
88 ("Environment variable """ & External_Name
89 & """ = """ & Value & '"');
90 end if;
92 elsif not Silent then
93 Debug_Output
94 ("Not overriding existing environment variable """
95 & External_Name & """, value is """ & Env_Var.all & '"');
96 end if;
98 Free (Env_Var);
99 end;
100 end if;
102 Name_Len := External_Name'Length;
103 Name_Buffer (1 .. Name_Len) := External_Name;
104 Canonical_Case_Env_Var_Name (Name_Buffer (1 .. Name_Len));
105 Key := Name_Find;
107 -- Check whether the value is already defined, to properly respect the
108 -- overriding order.
110 if Source /= External_Source'First then
111 N := Name_To_Name_HTable.Get (Self.Refs.all, Key);
113 if N /= null then
114 if External_Source'Pos (N.Source) <
115 External_Source'Pos (Source)
116 then
117 if not Silent then
118 Debug_Output
119 ("Not overridding existing external reference '"
120 & External_Name & "', value was defined in "
121 & N.Source'Img);
122 end if;
124 return;
125 end if;
126 end if;
127 end if;
129 Name_Len := Value'Length;
130 Name_Buffer (1 .. Name_Len) := Value;
131 N := new Name_To_Name'
132 (Key => Key,
133 Source => Source,
134 Value => Name_Find,
135 Next => null);
137 if not Silent then
138 Debug_Output ("Add external (" & External_Name & ") is", N.Value);
139 end if;
141 Name_To_Name_HTable.Set (Self.Refs.all, N);
142 end Add;
144 -----------
145 -- Check --
146 -----------
148 function Check
149 (Self : External_References;
150 Declaration : String) return Boolean
152 begin
153 for Equal_Pos in Declaration'Range loop
154 if Declaration (Equal_Pos) = '=' then
155 exit when Equal_Pos = Declaration'First;
157 (Self => Self,
158 External_Name =>
159 Declaration (Declaration'First .. Equal_Pos - 1),
160 Value =>
161 Declaration (Equal_Pos + 1 .. Declaration'Last),
162 Source => From_Command_Line);
163 return True;
164 end if;
165 end loop;
167 return False;
168 end Check;
170 -----------
171 -- Reset --
172 -----------
174 procedure Reset (Self : External_References) is
175 begin
176 if Self.Refs /= null then
177 Debug_Output ("Reset external references");
178 Name_To_Name_HTable.Reset (Self.Refs.all);
179 end if;
180 end Reset;
182 --------------
183 -- Value_Of --
184 --------------
186 function Value_Of
187 (Self : External_References;
188 External_Name : Name_Id;
189 With_Default : Name_Id := No_Name)
190 return Name_Id
192 Value : Name_To_Name_Ptr;
193 Val : Name_Id;
194 Name : String := Get_Name_String (External_Name);
196 begin
197 Canonical_Case_Env_Var_Name (Name);
199 if Self.Refs /= null then
200 Name_Len := Name'Length;
201 Name_Buffer (1 .. Name_Len) := Name;
202 Value := Name_To_Name_HTable.Get (Self.Refs.all, Name_Find);
204 if Value /= null then
205 Debug_Output ("Value_Of (" & Name & ") is in cache", Value.Value);
206 return Value.Value;
207 end if;
208 end if;
210 -- Find if it is an environment, if it is, put value in the hash table
212 declare
213 Env_Value : String_Access := Getenv (Name);
215 begin
216 if Env_Value /= null and then Env_Value'Length > 0 then
217 Name_Len := Env_Value'Length;
218 Name_Buffer (1 .. Name_Len) := Env_Value.all;
219 Val := Name_Find;
221 if Current_Verbosity = High then
222 Debug_Output ("Value_Of (" & Name & ") is", Val);
223 end if;
225 if Self.Refs /= null then
226 Value := new Name_To_Name'
227 (Key => External_Name,
228 Value => Val,
229 Source => From_Environment,
230 Next => null);
231 Name_To_Name_HTable.Set (Self.Refs.all, Value);
232 end if;
234 Free (Env_Value);
235 return Val;
237 else
238 if Current_Verbosity = High then
239 Debug_Output
240 ("Value_Of (" & Name & ") is default", With_Default);
241 end if;
243 Free (Env_Value);
244 return With_Default;
245 end if;
246 end;
247 end Value_Of;
249 ----------
250 -- Free --
251 ----------
253 procedure Free (Self : in out External_References) is
254 procedure Unchecked_Free is new Ada.Unchecked_Deallocation
255 (Name_To_Name_HTable.Instance, Instance_Access);
256 begin
257 if Self.Refs /= null then
258 Reset (Self);
259 Unchecked_Free (Self.Refs);
260 end if;
261 end Free;
263 --------------
264 -- Set_Next --
265 --------------
267 procedure Set_Next (E : Name_To_Name_Ptr; Next : Name_To_Name_Ptr) is
268 begin
269 E.Next := Next;
270 end Set_Next;
272 ----------
273 -- Next --
274 ----------
276 function Next (E : Name_To_Name_Ptr) return Name_To_Name_Ptr is
277 begin
278 return E.Next;
279 end Next;
281 -------------
282 -- Get_Key --
283 -------------
285 function Get_Key (E : Name_To_Name_Ptr) return Name_Id is
286 begin
287 return E.Key;
288 end Get_Key;
290 end Prj.Ext;