1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2004 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, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, 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;
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;
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,
87 Display_Path_Name => No_Name,
89 Location => No_Location,
92 Display_Directory => No_Name,
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,
140 Need_To_Build_Lib => False,
142 Unkept_Comments => False);
144 -----------------------
145 -- Add_Language_Name --
146 -----------------------
148 procedure Add_Language_Name (Name : Name_Id) is
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;
160 procedure Add_To_Buffer (S : String) is
162 -- If Buffer is too small, double its size
164 if Buffer_Last + S'Length > Buffer'Last then
166 New_Buffer : constant String_Access :=
167 new String (1 .. 2 * Buffer'Last);
170 New_Buffer (1 .. Buffer_Last) := Buffer (1 .. Buffer_Last);
172 Buffer := New_Buffer;
176 Buffer (Buffer_Last + 1 .. Buffer_Last + S'Length) := S;
177 Buffer_Last := Buffer_Last + S'Length;
180 ---------------------------
181 -- Display_Language_Name --
182 ---------------------------
184 procedure Display_Language_Name (Language : Language_Index) is
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;
195 function Empty_Project return Project_Data is
198 return Project_Empty;
205 function Empty_String return Name_Id is
207 return The_Empty_String;
214 procedure Expect (The_Token : Token_Type; Token_Image : String) is
216 if Token /= The_Token then
217 Error_Msg (Token_Image & " expected", Token_Ptr);
221 --------------------------------
222 -- For_Every_Project_Imported --
223 --------------------------------
225 procedure For_Every_Project_Imported
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.
238 procedure Check (Project : Project_Id) is
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;
254 -- Start of procecessing for For_Every_Project_Imported
257 for Project in Projects.First .. Projects.Last loop
258 Projects.Table (Project).Seen := False;
261 Check (Project => By);
262 end For_Every_Project_Imported;
268 function Hash (Name : Name_Id) return Header_Num is
270 return Hash (Get_Name_String (Name));
277 function Image (Casing : Casing_Type) return String is
279 return The_Casing_Images (Casing).all;
286 procedure Initialize is
288 if not Initialized then
292 The_Empty_String := Name_Find;
293 Empty_Name := The_Empty_String;
295 Name_Buffer (1 .. 4) := ".ads";
296 Default_Ada_Spec_Suffix := Name_Find;
298 Name_Buffer (1 .. 4) := ".adb";
299 Default_Ada_Body_Suffix := Name_Find;
301 Name_Buffer (1) := '/';
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);
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;
323 Add_Language_Name (Name_Ada);
324 Add_Language_Name (Name_C);
325 Add_Language_Name (Name_C_Plus_Plus);
334 (Language : Language_Index;
335 In_Project : Project_Data) return Boolean
339 when No_Language_Index =>
342 when First_Language_Indexes =>
343 return In_Project.Languages (Language);
347 Supp : Supp_Language;
348 Supp_Index : Supp_Language_Index := In_Project.Supp_Languages;
351 while Supp_Index /= No_Supp_Language_Index loop
352 Supp := Present_Languages.Table (Supp_Index);
354 if Supp.Index = Language then
358 Supp_Index := Supp.Next;
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
376 when No_Language_Index =>
377 return Default_Language_Processing_Data;
379 when First_Language_Indexes =>
380 return In_Project.First_Language_Processing (Language);
384 Supp : Supp_Language_Data;
385 Supp_Index : Supp_Language_Index :=
386 In_Project.Supp_Language_Processing;
389 while Supp_Index /= No_Supp_Language_Index loop
390 Supp := Supp_Languages.Table (Supp_Index);
392 if Supp.Index = Language then
396 Supp_Index := Supp.Next;
399 return Default_Language_Processing_Data;
402 end Language_Processing_Data_Of;
404 ------------------------------------
405 -- Register_Default_Naming_Scheme --
406 ------------------------------------
408 procedure Register_Default_Naming_Scheme
410 Default_Spec_Suffix : Name_Id;
411 Default_Body_Suffix : Name_Id)
414 Suffix : Array_Element_Id;
415 Found : Boolean := False;
416 Element : Array_Element;
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));
425 Suffix := Std_Naming_Data.Spec_Suffix;
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
436 Element.Value.Value := Default_Spec_Suffix;
437 Array_Elements.Table (Suffix) := Element;
440 Suffix := Element.Next;
444 -- If none can be found, create a new one.
450 Index_Case_Sensitive => False,
451 Value => (Project => No_Project,
453 Location => No_Location,
455 Value => Default_Spec_Suffix,
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;
463 Suffix := Std_Naming_Data.Body_Suffix;
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
474 Element.Value.Value := Default_Body_Suffix;
475 Array_Elements.Table (Suffix) := Element;
478 Suffix := Element.Next;
482 -- If none can be found, create a new one.
488 Index_Case_Sensitive => False,
489 Value => (Project => No_Project,
491 Location => No_Location,
493 Value => Default_Body_Suffix,
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;
500 end Register_Default_Naming_Scheme;
512 Variable_Elements.Init;
513 String_Elements.Init;
515 Prj.Com.Units_Htable.Reset;
516 Prj.Com.Files_Htable.Reset;
519 ------------------------
520 -- Same_Naming_Scheme --
521 ------------------------
523 function Same_Naming_Scheme
524 (Left, Right : Naming_Data) return Boolean
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;
539 (Language : Language_Index;
541 In_Project : in out Project_Data)
545 when No_Language_Index =>
548 when First_Language_Indexes =>
549 In_Project.Languages (Language) := Present;
553 Supp : Supp_Language;
554 Supp_Index : Supp_Language_Index := In_Project.Supp_Languages;
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;
565 Supp_Index := Supp.Next;
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;
579 (Language_Processing : in Language_Processing_Data;
580 For_Language : Language_Index;
581 In_Project : in out Project_Data)
585 when No_Language_Index =>
588 when First_Language_Indexes =>
589 In_Project.First_Language_Processing (For_Language) :=
594 Supp : Supp_Language_Data;
595 Supp_Index : Supp_Language_Index :=
596 In_Project.Supp_Language_Processing;
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 :=
608 Supp_Index := Supp.Next;
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;
623 For_Language : Language_Index;
624 In_Project : in out Project_Data)
628 when No_Language_Index =>
631 when First_Language_Indexes =>
632 In_Project.Naming.Impl_Suffixes (For_Language) := Suffix;
637 Supp_Index : Supp_Language_Index :=
638 In_Project.Naming.Supp_Suffixes;
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;
649 Supp_Index := Supp.Next;
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;
663 --------------------------
664 -- Standard_Naming_Data --
665 --------------------------
667 function Standard_Naming_Data return Naming_Data is
670 return Std_Naming_Data;
671 end Standard_Naming_Data;
678 (Language : Language_Index;
679 In_Project : Project_Data) return Name_Id
683 when No_Language_Index =>
686 when First_Language_Indexes =>
687 return In_Project.Naming.Impl_Suffixes (Language);
692 Supp_Index : Supp_Language_Index :=
693 In_Project.Naming.Supp_Suffixes;
696 while Supp_Index /= No_Supp_Language_Index loop
697 Supp := Supp_Suffix_Table.Table (Supp_Index);
699 if Supp.Index = Language then
703 Supp_Index := Supp.Next;
715 function Value (Image : String) return Casing_Type is
717 for Casing in The_Casing_Images'Range loop
718 if To_Lower (Image) = To_Lower (The_Casing_Images (Casing).all) then
723 raise Constraint_Error;
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);