Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / gcc / ada / prj.adb
blob602d3a5c550a3dd0e05e6856b6bf9778f9d05e49
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- P R J --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2001-2004 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 ------------------------------------------------------------------------------
27 with Ada.Characters.Handling; use Ada.Characters.Handling;
29 with Namet; use Namet;
30 with Output; use Output;
31 with Osint; use Osint;
32 with Prj.Attr;
33 with Prj.Com;
34 with Prj.Env;
35 with Prj.Err; use Prj.Err;
36 with Scans; use Scans;
37 with Snames; use Snames;
38 with Uintp; use Uintp;
40 with GNAT.Case_Util; use GNAT.Case_Util;
41 with GNAT.OS_Lib; use GNAT.OS_Lib;
43 package body Prj is
45 The_Empty_String : Name_Id;
47 Name_C_Plus_Plus : Name_Id;
49 subtype Known_Casing is Casing_Type range All_Upper_Case .. Mixed_Case;
51 The_Casing_Images : constant array (Known_Casing) of String_Access :=
52 (All_Lower_Case => new String'("lowercase"),
53 All_Upper_Case => new String'("UPPERCASE"),
54 Mixed_Case => new String'("MixedCase"));
56 Initialized : Boolean := False;
58 Standard_Dot_Replacement : constant Name_Id :=
59 First_Name_Id + Character'Pos ('-');
61 Std_Naming_Data : Naming_Data :=
62 (Dot_Replacement => Standard_Dot_Replacement,
63 Dot_Repl_Loc => No_Location,
64 Casing => All_Lower_Case,
65 Spec_Suffix => No_Array_Element,
66 Ada_Spec_Suffix => No_Name,
67 Spec_Suffix_Loc => No_Location,
68 Impl_Suffixes => No_Impl_Suffixes,
69 Supp_Suffixes => No_Supp_Language_Index,
70 Body_Suffix => No_Array_Element,
71 Ada_Body_Suffix => No_Name,
72 Body_Suffix_Loc => No_Location,
73 Separate_Suffix => No_Name,
74 Sep_Suffix_Loc => No_Location,
75 Specs => No_Array_Element,
76 Bodies => No_Array_Element,
77 Specification_Exceptions => No_Array_Element,
78 Implementation_Exceptions => No_Array_Element);
80 Project_Empty : constant Project_Data :=
81 (Externally_Built => False,
82 Languages => No_Languages,
83 Supp_Languages => No_Supp_Language_Index,
84 First_Referred_By => No_Project,
85 Name => No_Name,
86 Path_Name => No_Name,
87 Display_Path_Name => No_Name,
88 Virtual => False,
89 Location => No_Location,
90 Mains => Nil_String,
91 Directory => No_Name,
92 Display_Directory => No_Name,
93 Dir_Path => null,
94 Library => False,
95 Library_Dir => No_Name,
96 Display_Library_Dir => No_Name,
97 Library_Src_Dir => No_Name,
98 Display_Library_Src_Dir => No_Name,
99 Library_Name => No_Name,
100 Library_Kind => Static,
101 Lib_Internal_Name => No_Name,
102 Standalone_Library => False,
103 Lib_Interface_ALIs => Nil_String,
104 Lib_Auto_Init => False,
105 Symbol_Data => No_Symbols,
106 Ada_Sources_Present => True,
107 Other_Sources_Present => True,
108 Sources => Nil_String,
109 First_Other_Source => No_Other_Source,
110 Last_Other_Source => No_Other_Source,
111 Imported_Directories_Switches => null,
112 Include_Path => null,
113 Include_Data_Set => False,
114 Source_Dirs => Nil_String,
115 Known_Order_Of_Source_Dirs => True,
116 Object_Directory => No_Name,
117 Display_Object_Dir => No_Name,
118 Exec_Directory => No_Name,
119 Display_Exec_Dir => No_Name,
120 Extends => No_Project,
121 Extended_By => No_Project,
122 Naming => Std_Naming_Data,
123 First_Language_Processing => Default_First_Language_Processing_Data,
124 Supp_Language_Processing => No_Supp_Language_Index,
125 Default_Linker => No_Name,
126 Default_Linker_Path => No_Name,
127 Decl => No_Declarations,
128 Imported_Projects => Empty_Project_List,
129 Ada_Include_Path => null,
130 Ada_Objects_Path => null,
131 Include_Path_File => No_Name,
132 Objects_Path_File_With_Libs => No_Name,
133 Objects_Path_File_Without_Libs => No_Name,
134 Config_File_Name => No_Name,
135 Config_File_Temp => False,
136 Config_Checked => False,
137 Language_Independent_Checked => False,
138 Checked => False,
139 Seen => False,
140 Need_To_Build_Lib => False,
141 Depth => 0,
142 Unkept_Comments => False);
144 -----------------------
145 -- Add_Language_Name --
146 -----------------------
148 procedure Add_Language_Name (Name : Name_Id) is
149 begin
150 Last_Language_Index := Last_Language_Index + 1;
151 Language_Indexes.Set (Name, Last_Language_Index);
152 Language_Names.Increment_Last;
153 Language_Names.Table (Last_Language_Index) := Name;
154 end Add_Language_Name;
156 -------------------
157 -- Add_To_Buffer --
158 -------------------
160 procedure Add_To_Buffer (S : String) is
161 begin
162 -- If Buffer is too small, double its size
164 if Buffer_Last + S'Length > Buffer'Last then
165 declare
166 New_Buffer : constant String_Access :=
167 new String (1 .. 2 * Buffer'Last);
169 begin
170 New_Buffer (1 .. Buffer_Last) := Buffer (1 .. Buffer_Last);
171 Free (Buffer);
172 Buffer := New_Buffer;
173 end;
174 end if;
176 Buffer (Buffer_Last + 1 .. Buffer_Last + S'Length) := S;
177 Buffer_Last := Buffer_Last + S'Length;
178 end Add_To_Buffer;
180 ---------------------------
181 -- Display_Language_Name --
182 ---------------------------
184 procedure Display_Language_Name (Language : Language_Index) is
185 begin
186 Get_Name_String (Language_Names.Table (Language));
187 To_Upper (Name_Buffer (1 .. 1));
188 Write_Str (Name_Buffer (1 .. Name_Len));
189 end Display_Language_Name;
191 -------------------
192 -- Empty_Project --
193 -------------------
195 function Empty_Project return Project_Data is
196 begin
197 Prj.Initialize;
198 return Project_Empty;
199 end Empty_Project;
201 ------------------
202 -- Empty_String --
203 ------------------
205 function Empty_String return Name_Id is
206 begin
207 return The_Empty_String;
208 end Empty_String;
210 ------------
211 -- Expect --
212 ------------
214 procedure Expect (The_Token : Token_Type; Token_Image : String) is
215 begin
216 if Token /= The_Token then
217 Error_Msg (Token_Image & " expected", Token_Ptr);
218 end if;
219 end Expect;
221 --------------------------------
222 -- For_Every_Project_Imported --
223 --------------------------------
225 procedure For_Every_Project_Imported
226 (By : Project_Id;
227 With_State : in out State)
230 procedure Check (Project : Project_Id);
231 -- Check if a project has already been seen. If not seen, mark it as
232 -- Seen, Call Action, and check all its imported projects.
234 -----------
235 -- Check --
236 -----------
238 procedure Check (Project : Project_Id) is
239 List : Project_List;
241 begin
242 if not Projects.Table (Project).Seen then
243 Projects.Table (Project).Seen := True;
244 Action (Project, With_State);
246 List := Projects.Table (Project).Imported_Projects;
247 while List /= Empty_Project_List loop
248 Check (Project_Lists.Table (List).Project);
249 List := Project_Lists.Table (List).Next;
250 end loop;
251 end if;
252 end Check;
254 -- Start of procecessing for For_Every_Project_Imported
256 begin
257 for Project in Projects.First .. Projects.Last loop
258 Projects.Table (Project).Seen := False;
259 end loop;
261 Check (Project => By);
262 end For_Every_Project_Imported;
264 ----------
265 -- Hash --
266 ----------
268 function Hash (Name : Name_Id) return Header_Num is
269 begin
270 return Hash (Get_Name_String (Name));
271 end Hash;
273 -----------
274 -- Image --
275 -----------
277 function Image (Casing : Casing_Type) return String is
278 begin
279 return The_Casing_Images (Casing).all;
280 end Image;
282 ----------------
283 -- Initialize --
284 ----------------
286 procedure Initialize is
287 begin
288 if not Initialized then
289 Initialized := True;
290 Uintp.Initialize;
291 Name_Len := 0;
292 The_Empty_String := Name_Find;
293 Empty_Name := The_Empty_String;
294 Name_Len := 4;
295 Name_Buffer (1 .. 4) := ".ads";
296 Default_Ada_Spec_Suffix := Name_Find;
297 Name_Len := 4;
298 Name_Buffer (1 .. 4) := ".adb";
299 Default_Ada_Body_Suffix := Name_Find;
300 Name_Len := 1;
301 Name_Buffer (1) := '/';
302 Slash := Name_Find;
303 Name_Len := 3;
304 Name_Buffer (1 .. 3) := "c++";
305 Name_C_Plus_Plus := Name_Find;
307 Std_Naming_Data.Ada_Spec_Suffix := Default_Ada_Spec_Suffix;
308 Std_Naming_Data.Ada_Body_Suffix := Default_Ada_Body_Suffix;
309 Std_Naming_Data.Separate_Suffix := Default_Ada_Body_Suffix;
310 Register_Default_Naming_Scheme
311 (Language => Name_Ada,
312 Default_Spec_Suffix => Default_Ada_Spec_Suffix,
313 Default_Body_Suffix => Default_Ada_Body_Suffix);
314 Prj.Env.Initialize;
315 Prj.Attr.Initialize;
316 Set_Name_Table_Byte (Name_Project, Token_Type'Pos (Tok_Project));
317 Set_Name_Table_Byte (Name_Extends, Token_Type'Pos (Tok_Extends));
318 Set_Name_Table_Byte (Name_External, Token_Type'Pos (Tok_External));
320 Language_Indexes.Reset;
321 Last_Language_Index := No_Language_Index;
322 Language_Names.Init;
323 Add_Language_Name (Name_Ada);
324 Add_Language_Name (Name_C);
325 Add_Language_Name (Name_C_Plus_Plus);
326 end if;
327 end Initialize;
329 ----------------
330 -- Is_Present --
331 ----------------
333 function Is_Present
334 (Language : Language_Index;
335 In_Project : Project_Data) return Boolean
337 begin
338 case Language is
339 when No_Language_Index =>
340 return False;
342 when First_Language_Indexes =>
343 return In_Project.Languages (Language);
345 when others =>
346 declare
347 Supp : Supp_Language;
348 Supp_Index : Supp_Language_Index := In_Project.Supp_Languages;
350 begin
351 while Supp_Index /= No_Supp_Language_Index loop
352 Supp := Present_Languages.Table (Supp_Index);
354 if Supp.Index = Language then
355 return Supp.Present;
356 end if;
358 Supp_Index := Supp.Next;
359 end loop;
361 return False;
362 end;
363 end case;
364 end Is_Present;
366 ---------------------------------
367 -- Language_Processing_Data_Of --
368 ---------------------------------
370 function Language_Processing_Data_Of
371 (Language : Language_Index;
372 In_Project : Project_Data) return Language_Processing_Data
374 begin
375 case Language is
376 when No_Language_Index =>
377 return Default_Language_Processing_Data;
379 when First_Language_Indexes =>
380 return In_Project.First_Language_Processing (Language);
382 when others =>
383 declare
384 Supp : Supp_Language_Data;
385 Supp_Index : Supp_Language_Index :=
386 In_Project.Supp_Language_Processing;
388 begin
389 while Supp_Index /= No_Supp_Language_Index loop
390 Supp := Supp_Languages.Table (Supp_Index);
392 if Supp.Index = Language then
393 return Supp.Data;
394 end if;
396 Supp_Index := Supp.Next;
397 end loop;
399 return Default_Language_Processing_Data;
400 end;
401 end case;
402 end Language_Processing_Data_Of;
404 ------------------------------------
405 -- Register_Default_Naming_Scheme --
406 ------------------------------------
408 procedure Register_Default_Naming_Scheme
409 (Language : Name_Id;
410 Default_Spec_Suffix : Name_Id;
411 Default_Body_Suffix : Name_Id)
413 Lang : Name_Id;
414 Suffix : Array_Element_Id;
415 Found : Boolean := False;
416 Element : Array_Element;
418 begin
419 -- Get the language name in small letters
421 Get_Name_String (Language);
422 Name_Buffer (1 .. Name_Len) := To_Lower (Name_Buffer (1 .. Name_Len));
423 Lang := Name_Find;
425 Suffix := Std_Naming_Data.Spec_Suffix;
426 Found := False;
428 -- Look for an element of the spec sufix array indexed by the language
429 -- name. If one is found, put the default value.
431 while Suffix /= No_Array_Element and then not Found loop
432 Element := Array_Elements.Table (Suffix);
434 if Element.Index = Lang then
435 Found := True;
436 Element.Value.Value := Default_Spec_Suffix;
437 Array_Elements.Table (Suffix) := Element;
439 else
440 Suffix := Element.Next;
441 end if;
442 end loop;
444 -- If none can be found, create a new one.
446 if not Found then
447 Element :=
448 (Index => Lang,
449 Src_Index => 0,
450 Index_Case_Sensitive => False,
451 Value => (Project => No_Project,
452 Kind => Single,
453 Location => No_Location,
454 Default => False,
455 Value => Default_Spec_Suffix,
456 Index => 0),
457 Next => Std_Naming_Data.Spec_Suffix);
458 Array_Elements.Increment_Last;
459 Array_Elements.Table (Array_Elements.Last) := Element;
460 Std_Naming_Data.Spec_Suffix := Array_Elements.Last;
461 end if;
463 Suffix := Std_Naming_Data.Body_Suffix;
464 Found := False;
466 -- Look for an element of the body sufix array indexed by the language
467 -- name. If one is found, put the default value.
469 while Suffix /= No_Array_Element and then not Found loop
470 Element := Array_Elements.Table (Suffix);
472 if Element.Index = Lang then
473 Found := True;
474 Element.Value.Value := Default_Body_Suffix;
475 Array_Elements.Table (Suffix) := Element;
477 else
478 Suffix := Element.Next;
479 end if;
480 end loop;
482 -- If none can be found, create a new one.
484 if not Found then
485 Element :=
486 (Index => Lang,
487 Src_Index => 0,
488 Index_Case_Sensitive => False,
489 Value => (Project => No_Project,
490 Kind => Single,
491 Location => No_Location,
492 Default => False,
493 Value => Default_Body_Suffix,
494 Index => 0),
495 Next => Std_Naming_Data.Body_Suffix);
496 Array_Elements.Increment_Last;
497 Array_Elements.Table (Array_Elements.Last) := Element;
498 Std_Naming_Data.Body_Suffix := Array_Elements.Last;
499 end if;
500 end Register_Default_Naming_Scheme;
502 -----------
503 -- Reset --
504 -----------
506 procedure Reset is
507 begin
508 Projects.Init;
509 Project_Lists.Init;
510 Packages.Init;
511 Arrays.Init;
512 Variable_Elements.Init;
513 String_Elements.Init;
514 Prj.Com.Units.Init;
515 Prj.Com.Units_Htable.Reset;
516 Prj.Com.Files_Htable.Reset;
517 end Reset;
519 ------------------------
520 -- Same_Naming_Scheme --
521 ------------------------
523 function Same_Naming_Scheme
524 (Left, Right : Naming_Data) return Boolean
526 begin
527 return Left.Dot_Replacement = Right.Dot_Replacement
528 and then Left.Casing = Right.Casing
529 and then Left.Ada_Spec_Suffix = Right.Ada_Spec_Suffix
530 and then Left.Ada_Body_Suffix = Right.Ada_Body_Suffix
531 and then Left.Separate_Suffix = Right.Separate_Suffix;
532 end Same_Naming_Scheme;
534 ---------
535 -- Set --
536 ---------
538 procedure Set
539 (Language : Language_Index;
540 Present : Boolean;
541 In_Project : in out Project_Data)
543 begin
544 case Language is
545 when No_Language_Index =>
546 null;
548 when First_Language_Indexes =>
549 In_Project.Languages (Language) := Present;
551 when others =>
552 declare
553 Supp : Supp_Language;
554 Supp_Index : Supp_Language_Index := In_Project.Supp_Languages;
556 begin
557 while Supp_Index /= No_Supp_Language_Index loop
558 Supp := Present_Languages.Table (Supp_Index);
560 if Supp.Index = Language then
561 Present_Languages.Table (Supp_Index).Present := Present;
562 return;
563 end if;
565 Supp_Index := Supp.Next;
566 end loop;
568 Supp := (Index => Language, Present => Present,
569 Next => In_Project.Supp_Languages);
570 Present_Languages.Increment_Last;
571 Supp_Index := Present_Languages.Last;
572 Present_Languages.Table (Supp_Index) := Supp;
573 In_Project.Supp_Languages := Supp_Index;
574 end;
575 end case;
576 end Set;
578 procedure Set
579 (Language_Processing : in Language_Processing_Data;
580 For_Language : Language_Index;
581 In_Project : in out Project_Data)
583 begin
584 case For_Language is
585 when No_Language_Index =>
586 null;
588 when First_Language_Indexes =>
589 In_Project.First_Language_Processing (For_Language) :=
590 Language_Processing;
592 when others =>
593 declare
594 Supp : Supp_Language_Data;
595 Supp_Index : Supp_Language_Index :=
596 In_Project.Supp_Language_Processing;
598 begin
599 while Supp_Index /= No_Supp_Language_Index loop
600 Supp := Supp_Languages.Table (Supp_Index);
602 if Supp.Index = For_Language then
603 Supp_Languages.Table (Supp_Index).Data :=
604 Language_Processing;
605 return;
606 end if;
608 Supp_Index := Supp.Next;
609 end loop;
611 Supp := (Index => For_Language, Data => Language_Processing,
612 Next => In_Project.Supp_Language_Processing);
613 Supp_Languages.Increment_Last;
614 Supp_Index := Supp_Languages.Last;
615 Supp_Languages.Table (Supp_Index) := Supp;
616 In_Project.Supp_Language_Processing := Supp_Index;
617 end;
618 end case;
619 end Set;
621 procedure Set
622 (Suffix : Name_Id;
623 For_Language : Language_Index;
624 In_Project : in out Project_Data)
626 begin
627 case For_Language is
628 when No_Language_Index =>
629 null;
631 when First_Language_Indexes =>
632 In_Project.Naming.Impl_Suffixes (For_Language) := Suffix;
634 when others =>
635 declare
636 Supp : Supp_Suffix;
637 Supp_Index : Supp_Language_Index :=
638 In_Project.Naming.Supp_Suffixes;
640 begin
641 while Supp_Index /= No_Supp_Language_Index loop
642 Supp := Supp_Suffix_Table.Table (Supp_Index);
644 if Supp.Index = For_Language then
645 Supp_Suffix_Table.Table (Supp_Index).Suffix := Suffix;
646 return;
647 end if;
649 Supp_Index := Supp.Next;
650 end loop;
652 Supp := (Index => For_Language, Suffix => Suffix,
653 Next => In_Project.Naming.Supp_Suffixes);
654 Supp_Suffix_Table.Increment_Last;
655 Supp_Index := Supp_Suffix_Table.Last;
656 Supp_Suffix_Table.Table (Supp_Index) := Supp;
657 In_Project.Naming.Supp_Suffixes := Supp_Index;
658 end;
659 end case;
660 end Set;
663 --------------------------
664 -- Standard_Naming_Data --
665 --------------------------
667 function Standard_Naming_Data return Naming_Data is
668 begin
669 Prj.Initialize;
670 return Std_Naming_Data;
671 end Standard_Naming_Data;
673 ---------------
674 -- Suffix_Of --
675 ---------------
677 function Suffix_Of
678 (Language : Language_Index;
679 In_Project : Project_Data) return Name_Id
681 begin
682 case Language is
683 when No_Language_Index =>
684 return No_Name;
686 when First_Language_Indexes =>
687 return In_Project.Naming.Impl_Suffixes (Language);
689 when others =>
690 declare
691 Supp : Supp_Suffix;
692 Supp_Index : Supp_Language_Index :=
693 In_Project.Naming.Supp_Suffixes;
695 begin
696 while Supp_Index /= No_Supp_Language_Index loop
697 Supp := Supp_Suffix_Table.Table (Supp_Index);
699 if Supp.Index = Language then
700 return Supp.Suffix;
701 end if;
703 Supp_Index := Supp.Next;
704 end loop;
706 return No_Name;
707 end;
708 end case;
709 end Suffix_Of;
711 -----------
712 -- Value --
713 -----------
715 function Value (Image : String) return Casing_Type is
716 begin
717 for Casing in The_Casing_Images'Range loop
718 if To_Lower (Image) = To_Lower (The_Casing_Images (Casing).all) then
719 return Casing;
720 end if;
721 end loop;
723 raise Constraint_Error;
724 end Value;
726 begin
727 -- Make sure that the standard project file extension is compatible
728 -- with canonical case file naming.
730 Canonical_Case_File_Name (Project_File_Extension);
731 end Prj;