3psoccon.ads, [...]: Files added.
[gcc.git] / gcc / ada / prj.adb
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- P R J --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2001-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
27 with Ada.Characters.Handling; use Ada.Characters.Handling;
28
29 with Namet; use Namet;
30 with Osint; use Osint;
31 with Prj.Attr;
32 with Prj.Com;
33 with Prj.Env;
34 with Prj.Err; use Prj.Err;
35 with Scans; use Scans;
36 with Snames; use Snames;
37
38 with GNAT.OS_Lib; use GNAT.OS_Lib;
39
40 package body Prj is
41
42 The_Empty_String : Name_Id;
43
44 Ada_Language : constant Name_Id := Name_Ada;
45
46 subtype Known_Casing is Casing_Type range All_Upper_Case .. Mixed_Case;
47
48 The_Casing_Images : constant array (Known_Casing) of String_Access :=
49 (All_Lower_Case => new String'("lowercase"),
50 All_Upper_Case => new String'("UPPERCASE"),
51 Mixed_Case => new String'("MixedCase"));
52
53 Initialized : Boolean := False;
54
55 Standard_Dot_Replacement : constant Name_Id :=
56 First_Name_Id + Character'Pos ('-');
57
58 Std_Naming_Data : Naming_Data :=
59 (Current_Language => No_Name,
60 Dot_Replacement => Standard_Dot_Replacement,
61 Dot_Repl_Loc => No_Location,
62 Casing => All_Lower_Case,
63 Spec_Suffix => No_Array_Element,
64 Current_Spec_Suffix => No_Name,
65 Spec_Suffix_Loc => No_Location,
66 Body_Suffix => No_Array_Element,
67 Current_Body_Suffix => No_Name,
68 Body_Suffix_Loc => No_Location,
69 Separate_Suffix => No_Name,
70 Sep_Suffix_Loc => No_Location,
71 Specs => No_Array_Element,
72 Bodies => No_Array_Element,
73 Specification_Exceptions => No_Array_Element,
74 Implementation_Exceptions => No_Array_Element);
75
76 Project_Empty : constant Project_Data :=
77 (First_Referred_By => No_Project,
78 Name => No_Name,
79 Path_Name => No_Name,
80 Display_Path_Name => No_Name,
81 Location => No_Location,
82 Mains => Nil_String,
83 Directory => No_Name,
84 Display_Directory => No_Name,
85 Dir_Path => null,
86 Library => False,
87 Library_Dir => No_Name,
88 Display_Library_Dir => No_Name,
89 Library_Src_Dir => No_Name,
90 Display_Library_Src_Dir => No_Name,
91 Library_Name => No_Name,
92 Library_Kind => Static,
93 Lib_Internal_Name => No_Name,
94 Lib_Elaboration => False,
95 Standalone_Library => False,
96 Lib_Interface_ALIs => Nil_String,
97 Lib_Auto_Init => False,
98 Sources_Present => True,
99 Sources => Nil_String,
100 Source_Dirs => Nil_String,
101 Known_Order_Of_Source_Dirs => True,
102 Object_Directory => No_Name,
103 Display_Object_Dir => No_Name,
104 Exec_Directory => No_Name,
105 Display_Exec_Dir => No_Name,
106 Extends => No_Project,
107 Extended_By => No_Project,
108 Naming => Std_Naming_Data,
109 Decl => No_Declarations,
110 Imported_Projects => Empty_Project_List,
111 Ada_Include_Path => null,
112 Ada_Objects_Path => null,
113 Include_Path_File => No_Name,
114 Objects_Path_File_With_Libs => No_Name,
115 Objects_Path_File_Without_Libs => No_Name,
116 Config_File_Name => No_Name,
117 Config_File_Temp => False,
118 Config_Checked => False,
119 Language_Independent_Checked => False,
120 Checked => False,
121 Seen => False,
122 Flag1 => False,
123 Flag2 => False,
124 Depth => 0);
125
126 -------------------
127 -- Add_To_Buffer --
128 -------------------
129
130 procedure Add_To_Buffer (S : String) is
131 begin
132 -- If Buffer is too small, double its size
133
134 if Buffer_Last + S'Length > Buffer'Last then
135 declare
136 New_Buffer : constant String_Access :=
137 new String (1 .. 2 * Buffer'Last);
138
139 begin
140 New_Buffer (1 .. Buffer_Last) := Buffer (1 .. Buffer_Last);
141 Free (Buffer);
142 Buffer := New_Buffer;
143 end;
144 end if;
145
146 Buffer (Buffer_Last + 1 .. Buffer_Last + S'Length) := S;
147 Buffer_Last := Buffer_Last + S'Length;
148 end Add_To_Buffer;
149
150 -------------------
151 -- Empty_Project --
152 -------------------
153
154 function Empty_Project return Project_Data is
155 begin
156 Initialize;
157 return Project_Empty;
158 end Empty_Project;
159
160 ------------------
161 -- Empty_String --
162 ------------------
163
164 function Empty_String return Name_Id is
165 begin
166 return The_Empty_String;
167 end Empty_String;
168
169 ------------
170 -- Expect --
171 ------------
172
173 procedure Expect (The_Token : Token_Type; Token_Image : String) is
174 begin
175 if Token /= The_Token then
176 Error_Msg (Token_Image & " expected", Token_Ptr);
177 end if;
178 end Expect;
179
180 --------------------------------
181 -- For_Every_Project_Imported --
182 --------------------------------
183
184 procedure For_Every_Project_Imported
185 (By : Project_Id;
186 With_State : in out State)
187 is
188
189 procedure Check (Project : Project_Id);
190 -- Check if a project has already been seen.
191 -- If not seen, mark it as seen, call Action,
192 -- and check all its imported projects.
193
194 procedure Check (Project : Project_Id) is
195 List : Project_List;
196
197 begin
198 if not Projects.Table (Project).Seen then
199 Projects.Table (Project).Seen := True;
200 Action (Project, With_State);
201
202 List := Projects.Table (Project).Imported_Projects;
203 while List /= Empty_Project_List loop
204 Check (Project_Lists.Table (List).Project);
205 List := Project_Lists.Table (List).Next;
206 end loop;
207 end if;
208 end Check;
209
210 begin
211 for Project in Projects.First .. Projects.Last loop
212 Projects.Table (Project).Seen := False;
213 end loop;
214
215 Check (Project => By);
216 end For_Every_Project_Imported;
217
218 -----------
219 -- Image --
220 -----------
221
222 function Image (Casing : Casing_Type) return String is
223 begin
224 return The_Casing_Images (Casing).all;
225 end Image;
226
227 ----------------
228 -- Initialize --
229 ----------------
230
231 procedure Initialize is
232 begin
233 if not Initialized then
234 Initialized := True;
235 Name_Len := 0;
236 The_Empty_String := Name_Find;
237 Empty_Name := The_Empty_String;
238 Name_Len := 4;
239 Name_Buffer (1 .. 4) := ".ads";
240 Default_Ada_Spec_Suffix := Name_Find;
241 Name_Len := 4;
242 Name_Buffer (1 .. 4) := ".adb";
243 Default_Ada_Body_Suffix := Name_Find;
244 Name_Len := 1;
245 Name_Buffer (1) := '/';
246 Slash := Name_Find;
247 Std_Naming_Data.Current_Spec_Suffix := Default_Ada_Spec_Suffix;
248 Std_Naming_Data.Current_Body_Suffix := Default_Ada_Body_Suffix;
249 Std_Naming_Data.Separate_Suffix := Default_Ada_Body_Suffix;
250 Register_Default_Naming_Scheme
251 (Language => Ada_Language,
252 Default_Spec_Suffix => Default_Ada_Spec_Suffix,
253 Default_Body_Suffix => Default_Ada_Body_Suffix);
254 Prj.Env.Initialize;
255 Prj.Attr.Initialize;
256 Set_Name_Table_Byte (Name_Project, Token_Type'Pos (Tok_Project));
257 Set_Name_Table_Byte (Name_Extends, Token_Type'Pos (Tok_Extends));
258 Set_Name_Table_Byte (Name_External, Token_Type'Pos (Tok_External));
259 end if;
260 end Initialize;
261
262 ------------------------------------
263 -- Register_Default_Naming_Scheme --
264 ------------------------------------
265
266 procedure Register_Default_Naming_Scheme
267 (Language : Name_Id;
268 Default_Spec_Suffix : Name_Id;
269 Default_Body_Suffix : Name_Id)
270 is
271 Lang : Name_Id;
272 Suffix : Array_Element_Id;
273 Found : Boolean := False;
274 Element : Array_Element;
275
276 begin
277 -- Get the language name in small letters
278
279 Get_Name_String (Language);
280 Name_Buffer (1 .. Name_Len) := To_Lower (Name_Buffer (1 .. Name_Len));
281 Lang := Name_Find;
282
283 Suffix := Std_Naming_Data.Spec_Suffix;
284 Found := False;
285
286 -- Look for an element of the spec sufix array indexed by the language
287 -- name. If one is found, put the default value.
288
289 while Suffix /= No_Array_Element and then not Found loop
290 Element := Array_Elements.Table (Suffix);
291
292 if Element.Index = Lang then
293 Found := True;
294 Element.Value.Value := Default_Spec_Suffix;
295 Array_Elements.Table (Suffix) := Element;
296
297 else
298 Suffix := Element.Next;
299 end if;
300 end loop;
301
302 -- If none can be found, create a new one.
303
304 if not Found then
305 Element :=
306 (Index => Lang,
307 Index_Case_Sensitive => False,
308 Value => (Kind => Single,
309 Location => No_Location,
310 Default => False,
311 Value => Default_Spec_Suffix),
312 Next => Std_Naming_Data.Spec_Suffix);
313 Array_Elements.Increment_Last;
314 Array_Elements.Table (Array_Elements.Last) := Element;
315 Std_Naming_Data.Spec_Suffix := Array_Elements.Last;
316 end if;
317
318 Suffix := Std_Naming_Data.Body_Suffix;
319 Found := False;
320
321 -- Look for an element of the body sufix array indexed by the language
322 -- name. If one is found, put the default value.
323
324 while Suffix /= No_Array_Element and then not Found loop
325 Element := Array_Elements.Table (Suffix);
326
327 if Element.Index = Lang then
328 Found := True;
329 Element.Value.Value := Default_Body_Suffix;
330 Array_Elements.Table (Suffix) := Element;
331
332 else
333 Suffix := Element.Next;
334 end if;
335 end loop;
336
337 -- If none can be found, create a new one.
338
339 if not Found then
340 Element :=
341 (Index => Lang,
342 Index_Case_Sensitive => False,
343 Value => (Kind => Single,
344 Location => No_Location,
345 Default => False,
346 Value => Default_Body_Suffix),
347 Next => Std_Naming_Data.Body_Suffix);
348 Array_Elements.Increment_Last;
349 Array_Elements.Table (Array_Elements.Last) := Element;
350 Std_Naming_Data.Body_Suffix := Array_Elements.Last;
351 end if;
352 end Register_Default_Naming_Scheme;
353
354 ------------
355 -- Reset --
356 ------------
357
358 procedure Reset is
359 begin
360 Projects.Init;
361 Project_Lists.Init;
362 Packages.Init;
363 Arrays.Init;
364 Variable_Elements.Init;
365 String_Elements.Init;
366 Prj.Com.Units.Init;
367 Prj.Com.Units_Htable.Reset;
368 end Reset;
369
370 ------------------------
371 -- Same_Naming_Scheme --
372 ------------------------
373
374 function Same_Naming_Scheme
375 (Left, Right : Naming_Data)
376 return Boolean
377 is
378 begin
379 return Left.Dot_Replacement = Right.Dot_Replacement
380 and then Left.Casing = Right.Casing
381 and then Left.Current_Spec_Suffix = Right.Current_Spec_Suffix
382 and then Left.Current_Body_Suffix = Right.Current_Body_Suffix
383 and then Left.Separate_Suffix = Right.Separate_Suffix;
384 end Same_Naming_Scheme;
385
386 ----------
387 -- Scan --
388 ----------
389
390 procedure Scan is
391 begin
392 Scanner.Scan;
393 end Scan;
394
395 --------------------------
396 -- Standard_Naming_Data --
397 --------------------------
398
399 function Standard_Naming_Data return Naming_Data is
400 begin
401 Initialize;
402 return Std_Naming_Data;
403 end Standard_Naming_Data;
404
405 -----------
406 -- Value --
407 -----------
408
409 function Value (Image : String) return Casing_Type is
410 begin
411 for Casing in The_Casing_Images'Range loop
412 if To_Lower (Image) = To_Lower (The_Casing_Images (Casing).all) then
413 return Casing;
414 end if;
415 end loop;
416
417 raise Constraint_Error;
418 end Value;
419
420 begin
421 -- Make sure that the standard project file extension is compatible
422 -- with canonical case file naming.
423
424 Canonical_Case_File_Name (Project_File_Extension);
425 end Prj;