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