1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2006, Free Software Foundation, Inc. --
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, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
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
;
34 with Prj
.Err
; use Prj
.Err
;
35 with Snames
; use Snames
;
36 with Uintp
; use Uintp
;
38 with GNAT
.Case_Util
; use GNAT
.Case_Util
;
42 Initial_Buffer_Size
: constant := 100;
43 -- Initial size for extensible buffer used in Add_To_Buffer
45 The_Empty_String
: Name_Id
;
47 Name_C_Plus_Plus
: Name_Id
;
49 Default_Ada_Spec_Suffix_Id
: Name_Id
;
50 Default_Ada_Body_Suffix_Id
: Name_Id
;
52 -- Initialized in Prj.Initialized, then never modified
54 subtype Known_Casing
is Casing_Type
range All_Upper_Case
.. Mixed_Case
;
56 The_Casing_Images
: constant array (Known_Casing
) of String_Access
:=
57 (All_Lower_Case
=> new String'("lowercase"),
58 All_Upper_Case => new String'("UPPERCASE"),
59 Mixed_Case
=> new String'("MixedCase"));
61 Initialized : Boolean := False;
63 Standard_Dot_Replacement : constant Name_Id :=
64 First_Name_Id + Character'Pos ('-');
66 Std_Naming_Data : Naming_Data :=
67 (Dot_Replacement => Standard_Dot_Replacement,
68 Dot_Repl_Loc => No_Location,
69 Casing => All_Lower_Case,
70 Spec_Suffix => No_Array_Element,
71 Ada_Spec_Suffix => No_Name,
72 Spec_Suffix_Loc => No_Location,
73 Impl_Suffixes => No_Impl_Suffixes,
74 Supp_Suffixes => No_Supp_Language_Index,
75 Body_Suffix => No_Array_Element,
76 Ada_Body_Suffix => No_Name,
77 Body_Suffix_Loc => No_Location,
78 Separate_Suffix => No_Name,
79 Sep_Suffix_Loc => No_Location,
80 Specs => No_Array_Element,
81 Bodies => No_Array_Element,
82 Specification_Exceptions => No_Array_Element,
83 Implementation_Exceptions => No_Array_Element);
85 Project_Empty : Project_Data :=
86 (Externally_Built => False,
87 Languages => No_Languages,
88 Supp_Languages => No_Supp_Language_Index,
89 First_Referred_By => No_Project,
91 Display_Name => No_Name,
93 Display_Path_Name => No_Name,
95 Location => No_Location,
98 Display_Directory => No_Name,
101 Library_Dir => No_Name,
102 Display_Library_Dir => No_Name,
103 Library_Src_Dir => No_Name,
104 Display_Library_Src_Dir => No_Name,
105 Library_ALI_Dir => No_Name,
106 Display_Library_ALI_Dir => No_Name,
107 Library_Name => No_Name,
108 Library_Kind => Static,
109 Lib_Internal_Name => No_Name,
110 Standalone_Library => False,
111 Lib_Interface_ALIs => Nil_String,
112 Lib_Auto_Init => False,
113 Symbol_Data => No_Symbols,
114 Ada_Sources_Present => True,
115 Other_Sources_Present => True,
116 Sources => Nil_String,
117 First_Other_Source => No_Other_Source,
118 Last_Other_Source => No_Other_Source,
119 Imported_Directories_Switches => null,
120 Include_Path => null,
121 Include_Data_Set => False,
122 Source_Dirs => Nil_String,
123 Known_Order_Of_Source_Dirs => True,
124 Object_Directory => No_Name,
125 Display_Object_Dir => No_Name,
126 Library_TS => Empty_Time_Stamp,
127 Exec_Directory => No_Name,
128 Display_Exec_Dir => No_Name,
129 Extends => No_Project,
130 Extended_By => No_Project,
131 Naming => Std_Naming_Data,
132 First_Language_Processing => Default_First_Language_Processing_Data,
133 Supp_Language_Processing => No_Supp_Language_Index,
134 Default_Linker => No_Name,
135 Default_Linker_Path => No_Name,
136 Decl => No_Declarations,
137 Imported_Projects => Empty_Project_List,
138 All_Imported_Projects => Empty_Project_List,
139 Ada_Include_Path => null,
140 Ada_Objects_Path => null,
141 Include_Path_File => No_Name,
142 Objects_Path_File_With_Libs => No_Name,
143 Objects_Path_File_Without_Libs => No_Name,
144 Config_File_Name => No_Name,
145 Config_File_Temp => False,
146 Config_Checked => False,
147 Language_Independent_Checked => False,
150 Need_To_Build_Lib => False,
152 Unkept_Comments => False);
154 -----------------------
155 -- Add_Language_Name --
156 -----------------------
158 procedure Add_Language_Name (Name : Name_Id) is
160 Last_Language_Index := Last_Language_Index + 1;
161 Language_Indexes.Set (Name, Last_Language_Index);
162 Language_Names.Increment_Last;
163 Language_Names.Table (Last_Language_Index) := Name;
164 end Add_Language_Name;
170 procedure Add_To_Buffer
172 To : in out String_Access;
173 Last : in out Natural)
177 To := new String (1 .. Initial_Buffer_Size);
181 -- If Buffer is too small, double its size
183 while Last + S'Length > To'Last loop
185 New_Buffer : constant String_Access :=
186 new String (1 .. 2 * Last);
189 New_Buffer (1 .. Last) := To (1 .. Last);
195 To (Last + 1 .. Last + S'Length) := S;
196 Last := Last + S'Length;
199 -----------------------------
200 -- Default_Ada_Body_Suffix --
201 -----------------------------
203 function Default_Ada_Body_Suffix return Name_Id is
205 return Default_Ada_Body_Suffix_Id;
206 end Default_Ada_Body_Suffix;
208 -----------------------------
209 -- Default_Ada_Spec_Suffix --
210 -----------------------------
212 function Default_Ada_Spec_Suffix return Name_Id is
214 return Default_Ada_Spec_Suffix_Id;
215 end Default_Ada_Spec_Suffix;
217 ---------------------------
218 -- Display_Language_Name --
219 ---------------------------
221 procedure Display_Language_Name (Language : Language_Index) is
223 Get_Name_String (Language_Names.Table (Language));
224 To_Upper (Name_Buffer (1 .. 1));
225 Write_Str (Name_Buffer (1 .. Name_Len));
226 end Display_Language_Name;
232 function Empty_Project (Tree : Project_Tree_Ref) return Project_Data is
233 Value : Project_Data;
235 Prj.Initialize (Tree => No_Project_Tree);
236 Value := Project_Empty;
237 Value.Naming := Tree.Private_Part.Default_Naming;
245 function Empty_String return Name_Id is
247 return The_Empty_String;
254 procedure Expect (The_Token : Token_Type; Token_Image : String) is
256 if Token /= The_Token then
257 Error_Msg (Token_Image & " expected", Token_Ptr);
261 --------------------------------
262 -- For_Every_Project_Imported --
263 --------------------------------
265 procedure For_Every_Project_Imported
267 In_Tree : Project_Tree_Ref;
268 With_State : in out State)
271 procedure Recursive_Check (Project : Project_Id);
272 -- Check if a project has already been seen. If not seen, mark it as
273 -- Seen, Call Action, and check all its imported projects.
275 ---------------------
276 -- Recursive_Check --
277 ---------------------
279 procedure Recursive_Check (Project : Project_Id) is
283 if not In_Tree.Projects.Table (Project).Seen then
284 In_Tree.Projects.Table (Project).Seen := True;
285 Action (Project, With_State);
288 In_Tree.Projects.Table (Project).Imported_Projects;
289 while List /= Empty_Project_List loop
290 Recursive_Check (In_Tree.Project_Lists.Table (List).Project);
291 List := In_Tree.Project_Lists.Table (List).Next;
296 -- Start of processing for For_Every_Project_Imported
299 for Project in Project_Table.First ..
300 Project_Table.Last (In_Tree.Projects)
302 In_Tree.Projects.Table (Project).Seen := False;
305 Recursive_Check (Project => By);
306 end For_Every_Project_Imported;
312 function Hash (Name : Name_Id) return Header_Num is
314 return Hash (Get_Name_String (Name));
321 function Image (Casing : Casing_Type) return String is
323 return The_Casing_Images (Casing).all;
330 procedure Initialize (Tree : Project_Tree_Ref) is
332 if not Initialized then
336 The_Empty_String := Name_Find;
337 Empty_Name := The_Empty_String;
339 Name_Buffer (1 .. 4) := ".ads";
340 Default_Ada_Spec_Suffix_Id := Name_Find;
342 Name_Buffer (1 .. 4) := ".adb";
343 Default_Ada_Body_Suffix_Id := Name_Find;
345 Name_Buffer (1) := '/';
346 Slash_Id := Name_Find;
348 Name_Buffer (1 .. 3) := "c++";
349 Name_C_Plus_Plus := Name_Find;
351 Std_Naming_Data.Ada_Spec_Suffix := Default_Ada_Spec_Suffix;
352 Std_Naming_Data.Ada_Body_Suffix := Default_Ada_Body_Suffix;
353 Std_Naming_Data.Separate_Suffix := Default_Ada_Body_Suffix;
354 Project_Empty.Naming := Std_Naming_Data;
357 Set_Name_Table_Byte (Name_Project, Token_Type'Pos (Tok_Project));
358 Set_Name_Table_Byte (Name_Extends, Token_Type'Pos (Tok_Extends));
359 Set_Name_Table_Byte (Name_External, Token_Type'Pos (Tok_External));
361 Language_Indexes.Reset;
362 Last_Language_Index := No_Language_Index;
364 Add_Language_Name (Name_Ada);
365 Add_Language_Name (Name_C);
366 Add_Language_Name (Name_C_Plus_Plus);
369 if Tree /= No_Project_Tree then
379 (Language : Language_Index;
380 In_Project : Project_Data;
381 In_Tree : Project_Tree_Ref) return Boolean
385 when No_Language_Index =>
388 when First_Language_Indexes =>
389 return In_Project.Languages (Language);
393 Supp : Supp_Language;
394 Supp_Index : Supp_Language_Index := In_Project.Supp_Languages;
397 while Supp_Index /= No_Supp_Language_Index loop
398 Supp := In_Tree.Present_Languages.Table (Supp_Index);
400 if Supp.Index = Language then
404 Supp_Index := Supp.Next;
412 ---------------------------------
413 -- Language_Processing_Data_Of --
414 ---------------------------------
416 function Language_Processing_Data_Of
417 (Language : Language_Index;
418 In_Project : Project_Data;
419 In_Tree : Project_Tree_Ref) return Language_Processing_Data
423 when No_Language_Index =>
424 return Default_Language_Processing_Data;
426 when First_Language_Indexes =>
427 return In_Project.First_Language_Processing (Language);
431 Supp : Supp_Language_Data;
432 Supp_Index : Supp_Language_Index :=
433 In_Project.Supp_Language_Processing;
436 while Supp_Index /= No_Supp_Language_Index loop
437 Supp := In_Tree.Supp_Languages.Table (Supp_Index);
439 if Supp.Index = Language then
443 Supp_Index := Supp.Next;
446 return Default_Language_Processing_Data;
449 end Language_Processing_Data_Of;
451 ------------------------------------
452 -- Register_Default_Naming_Scheme --
453 ------------------------------------
455 procedure Register_Default_Naming_Scheme
457 Default_Spec_Suffix : Name_Id;
458 Default_Body_Suffix : Name_Id;
459 In_Tree : Project_Tree_Ref)
462 Suffix : Array_Element_Id;
463 Found : Boolean := False;
464 Element : Array_Element;
467 -- Get the language name in small letters
469 Get_Name_String (Language);
470 Name_Buffer (1 .. Name_Len) := To_Lower (Name_Buffer (1 .. Name_Len));
473 Suffix := In_Tree.Private_Part.Default_Naming.Spec_Suffix;
476 -- Look for an element of the spec sufix array indexed by the language
477 -- name. If one is found, put the default value.
479 while Suffix /= No_Array_Element and then not Found loop
480 Element := In_Tree.Array_Elements.Table (Suffix);
482 if Element.Index = Lang then
484 Element.Value.Value := Default_Spec_Suffix;
485 In_Tree.Array_Elements.Table (Suffix) := Element;
488 Suffix := Element.Next;
492 -- If none can be found, create a new one
498 Index_Case_Sensitive => False,
499 Value => (Project => No_Project,
501 Location => No_Location,
503 Value => Default_Spec_Suffix,
505 Next => In_Tree.Private_Part.Default_Naming.Spec_Suffix);
506 Array_Element_Table.Increment_Last (In_Tree.Array_Elements);
507 In_Tree.Array_Elements.Table
508 (Array_Element_Table.Last (In_Tree.Array_Elements)) :=
510 In_Tree.Private_Part.Default_Naming.Spec_Suffix :=
511 Array_Element_Table.Last (In_Tree.Array_Elements);
514 Suffix := In_Tree.Private_Part.Default_Naming.Body_Suffix;
517 -- Look for an element of the body sufix array indexed by the language
518 -- name. If one is found, put the default value.
520 while Suffix /= No_Array_Element and then not Found loop
521 Element := In_Tree.Array_Elements.Table (Suffix);
523 if Element.Index = Lang then
525 Element.Value.Value := Default_Body_Suffix;
526 In_Tree.Array_Elements.Table (Suffix) := Element;
529 Suffix := Element.Next;
533 -- If none can be found, create a new one
539 Index_Case_Sensitive => False,
540 Value => (Project => No_Project,
542 Location => No_Location,
544 Value => Default_Body_Suffix,
546 Next => In_Tree.Private_Part.Default_Naming.Body_Suffix);
547 Array_Element_Table.Increment_Last
548 (In_Tree.Array_Elements);
549 In_Tree.Array_Elements.Table
550 (Array_Element_Table.Last (In_Tree.Array_Elements))
552 In_Tree.Private_Part.Default_Naming.Body_Suffix :=
553 Array_Element_Table.Last (In_Tree.Array_Elements);
555 end Register_Default_Naming_Scheme;
561 procedure Reset (Tree : Project_Tree_Ref) is
564 Present_Language_Table.Init (Tree.Present_Languages);
565 Supp_Suffix_Table.Init (Tree.Supp_Suffixes);
566 Name_List_Table.Init (Tree.Name_Lists);
567 Supp_Language_Table.Init (Tree.Supp_Languages);
568 Other_Source_Table.Init (Tree.Other_Sources);
569 String_Element_Table.Init (Tree.String_Elements);
570 Variable_Element_Table.Init (Tree.Variable_Elements);
571 Array_Element_Table.Init (Tree.Array_Elements);
572 Array_Table.Init (Tree.Arrays);
573 Package_Table.Init (Tree.Packages);
574 Project_List_Table.Init (Tree.Project_Lists);
575 Project_Table.Init (Tree.Projects);
576 Unit_Table.Init (Tree.Units);
577 Units_Htable.Reset (Tree.Units_HT);
578 Files_Htable.Reset (Tree.Files_HT);
579 Naming_Table.Init (Tree.Private_Part.Namings);
580 Naming_Table.Increment_Last (Tree.Private_Part.Namings);
581 Tree.Private_Part.Namings.Table
582 (Naming_Table.Last (Tree.Private_Part.Namings)) := Std_Naming_Data;
583 Path_File_Table.Init (Tree.Private_Part.Path_Files);
584 Source_Path_Table.Init (Tree.Private_Part.Source_Paths);
585 Object_Path_Table.Init (Tree.Private_Part.Object_Paths);
586 Tree.Private_Part.Default_Naming := Std_Naming_Data;
587 Register_Default_Naming_Scheme
588 (Language => Name_Ada,
589 Default_Spec_Suffix => Default_Ada_Spec_Suffix,
590 Default_Body_Suffix => Default_Ada_Body_Suffix,
594 ------------------------
595 -- Same_Naming_Scheme --
596 ------------------------
598 function Same_Naming_Scheme
599 (Left, Right : Naming_Data) return Boolean
602 return Left.Dot_Replacement = Right.Dot_Replacement
603 and then Left.Casing = Right.Casing
604 and then Left.Ada_Spec_Suffix = Right.Ada_Spec_Suffix
605 and then Left.Ada_Body_Suffix = Right.Ada_Body_Suffix
606 and then Left.Separate_Suffix = Right.Separate_Suffix;
607 end Same_Naming_Scheme;
614 (Language : Language_Index;
616 In_Project : in out Project_Data;
617 In_Tree : Project_Tree_Ref)
621 when No_Language_Index =>
624 when First_Language_Indexes =>
625 In_Project.Languages (Language) := Present;
629 Supp : Supp_Language;
630 Supp_Index : Supp_Language_Index := In_Project.Supp_Languages;
633 while Supp_Index /= No_Supp_Language_Index loop
634 Supp := In_Tree.Present_Languages.Table
637 if Supp.Index = Language then
638 In_Tree.Present_Languages.Table
639 (Supp_Index).Present := Present;
643 Supp_Index := Supp.Next;
646 Supp := (Index => Language, Present => Present,
647 Next => In_Project.Supp_Languages);
648 Present_Language_Table.Increment_Last
649 (In_Tree.Present_Languages);
650 Supp_Index := Present_Language_Table.Last
651 (In_Tree.Present_Languages);
652 In_Tree.Present_Languages.Table (Supp_Index) :=
654 In_Project.Supp_Languages := Supp_Index;
660 (Language_Processing : Language_Processing_Data;
661 For_Language : Language_Index;
662 In_Project : in out Project_Data;
663 In_Tree : Project_Tree_Ref)
667 when No_Language_Index =>
670 when First_Language_Indexes =>
671 In_Project.First_Language_Processing (For_Language) :=
676 Supp : Supp_Language_Data;
677 Supp_Index : Supp_Language_Index :=
678 In_Project.Supp_Language_Processing;
681 while Supp_Index /= No_Supp_Language_Index loop
682 Supp := In_Tree.Supp_Languages.Table (Supp_Index);
684 if Supp.Index = For_Language then
685 In_Tree.Supp_Languages.Table
686 (Supp_Index).Data := Language_Processing;
690 Supp_Index := Supp.Next;
693 Supp := (Index => For_Language, Data => Language_Processing,
694 Next => In_Project.Supp_Language_Processing);
695 Supp_Language_Table.Increment_Last
696 (In_Tree.Supp_Languages);
697 Supp_Index := Supp_Language_Table.Last
698 (In_Tree.Supp_Languages);
699 In_Tree.Supp_Languages.Table (Supp_Index) := Supp;
700 In_Project.Supp_Language_Processing := Supp_Index;
707 For_Language : Language_Index;
708 In_Project : in out Project_Data;
709 In_Tree : Project_Tree_Ref)
713 when No_Language_Index =>
716 when First_Language_Indexes =>
717 In_Project.Naming.Impl_Suffixes (For_Language) := Suffix;
722 Supp_Index : Supp_Language_Index :=
723 In_Project.Naming.Supp_Suffixes;
726 while Supp_Index /= No_Supp_Language_Index loop
727 Supp := In_Tree.Supp_Suffixes.Table
730 if Supp.Index = For_Language then
731 In_Tree.Supp_Suffixes.Table
732 (Supp_Index).Suffix := Suffix;
736 Supp_Index := Supp.Next;
739 Supp := (Index => For_Language, Suffix => Suffix,
740 Next => In_Project.Naming.Supp_Suffixes);
741 Supp_Suffix_Table.Increment_Last
742 (In_Tree.Supp_Suffixes);
743 Supp_Index := Supp_Suffix_Table.Last
744 (In_Tree.Supp_Suffixes);
745 In_Tree.Supp_Suffixes.Table (Supp_Index) := Supp;
746 In_Project.Naming.Supp_Suffixes := Supp_Index;
755 function Slash return Name_Id is
760 --------------------------
761 -- Standard_Naming_Data --
762 --------------------------
764 function Standard_Naming_Data
765 (Tree : Project_Tree_Ref := No_Project_Tree) return Naming_Data
768 if Tree = No_Project_Tree then
769 Prj.Initialize (Tree => No_Project_Tree);
770 return Std_Naming_Data;
773 return Tree.Private_Part.Default_Naming;
775 end Standard_Naming_Data;
782 (Language : Language_Index;
783 In_Project : Project_Data;
784 In_Tree : Project_Tree_Ref) return Name_Id
788 when No_Language_Index =>
791 when First_Language_Indexes =>
792 return In_Project.Naming.Impl_Suffixes (Language);
797 Supp_Index : Supp_Language_Index :=
798 In_Project.Naming.Supp_Suffixes;
801 while Supp_Index /= No_Supp_Language_Index loop
802 Supp := In_Tree.Supp_Suffixes.Table (Supp_Index);
804 if Supp.Index = Language then
808 Supp_Index := Supp.Next;
820 function Value (Image : String) return Casing_Type is
822 for Casing in The_Casing_Images'Range loop
823 if To_Lower (Image) = To_Lower (The_Casing_Images (Casing).all) then
828 raise Constraint_Error;
832 -- Make sure that the standard project file extension is compatible
833 -- with canonical case file naming.
835 Canonical_Case_File_Name (Project_File_Extension);