1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2001-2009, 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 3, 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 COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
27 with Osint
; use Osint
;
28 with Output
; use Output
;
30 with Prj
.Err
; use Prj
.Err
;
31 with Snames
; use Snames
;
32 with Uintp
; use Uintp
;
34 with Ada
.Characters
.Handling
; use Ada
.Characters
.Handling
;
35 with Ada
.Unchecked_Deallocation
;
37 with GNAT
.Directory_Operations
; use GNAT
.Directory_Operations
;
39 with System
.Case_Util
; use System
.Case_Util
;
44 Object_Suffix
: constant String := Get_Target_Object_Suffix
.all;
45 -- File suffix for object files
47 Initial_Buffer_Size
: constant := 100;
48 -- Initial size for extensible buffer used in Add_To_Buffer
50 The_Empty_String
: Name_Id
:= No_Name
;
52 subtype Known_Casing
is Casing_Type
range All_Upper_Case
.. Mixed_Case
;
54 type Cst_String_Access
is access constant String;
56 All_Lower_Case_Image
: aliased constant String := "lowercase";
57 All_Upper_Case_Image
: aliased constant String := "UPPERCASE";
58 Mixed_Case_Image
: aliased constant String := "MixedCase";
60 The_Casing_Images
: constant array (Known_Casing
) of Cst_String_Access
:=
61 (All_Lower_Case
=> All_Lower_Case_Image
'Access,
62 All_Upper_Case
=> All_Upper_Case_Image
'Access,
63 Mixed_Case
=> Mixed_Case_Image
'Access);
65 Project_Empty
: constant Project_Data
:=
66 (Qualifier
=> Unspecified
,
67 Externally_Built
=> False,
68 Config
=> Default_Project_Config
,
70 Display_Name
=> No_Name
,
71 Path
=> No_Path_Information
,
73 Location
=> No_Location
,
75 Directory
=> No_Path_Information
,
77 Library_Dir
=> No_Path_Information
,
78 Library_Src_Dir
=> No_Path_Information
,
79 Library_ALI_Dir
=> No_Path_Information
,
80 Library_Name
=> No_Name
,
81 Library_Kind
=> Static
,
82 Lib_Internal_Name
=> No_Name
,
83 Standalone_Library
=> False,
84 Lib_Interface_ALIs
=> Nil_String
,
85 Lib_Auto_Init
=> False,
86 Libgnarl_Needed
=> Unknown
,
87 Symbol_Data
=> No_Symbols
,
88 Interfaces_Defined
=> False,
89 Source_Dirs
=> Nil_String
,
90 Source_Dir_Ranks
=> No_Number_List
,
91 Object_Directory
=> No_Path_Information
,
92 Library_TS
=> Empty_Time_Stamp
,
93 Exec_Directory
=> No_Path_Information
,
94 Extends
=> No_Project
,
95 Extended_By
=> No_Project
,
96 Languages
=> No_Language_Index
,
97 Decl
=> No_Declarations
,
98 Imported_Projects
=> null,
99 Include_Path_File
=> No_Path
,
100 All_Imported_Projects
=> null,
101 Ada_Include_Path
=> null,
102 Ada_Objects_Path
=> null,
103 Objects_Path
=> null,
104 Objects_Path_File_With_Libs
=> No_Path
,
105 Objects_Path_File_Without_Libs
=> No_Path
,
106 Config_File_Name
=> No_Path
,
107 Config_File_Temp
=> False,
108 Config_Checked
=> False,
109 Need_To_Build_Lib
=> False,
110 Has_Multi_Unit_Sources
=> False,
112 Unkept_Comments
=> False);
114 procedure Free
(Project
: in out Project_Id
);
115 -- Free memory allocated for Project
117 procedure Free_List
(Languages
: in out Language_Ptr
);
118 procedure Free_List
(Source
: in out Source_Id
);
119 procedure Free_List
(Languages
: in out Language_List
);
120 -- Free memory allocated for the list of languages or sources
122 procedure Free_Units
(Table
: in out Units_Htable
.Instance
);
123 -- Free memory allocated for unit information in the project
125 procedure Language_Changed
(Iter
: in out Source_Iterator
);
126 procedure Project_Changed
(Iter
: in out Source_Iterator
);
127 -- Called when a new project or language was selected for this iterator
129 function Contains_ALI_Files
(Dir
: Path_Name_Type
) return Boolean;
130 -- Return True if there is at least one ALI file in the directory Dir
136 procedure Add_To_Buffer
138 To
: in out String_Access
;
139 Last
: in out Natural)
143 To
:= new String (1 .. Initial_Buffer_Size
);
147 -- If Buffer is too small, double its size
149 while Last
+ S
'Length > To
'Last loop
151 New_Buffer
: constant String_Access
:=
152 new String (1 .. 2 * Last
);
155 New_Buffer
(1 .. Last
) := To
(1 .. Last
);
161 To
(Last
+ 1 .. Last
+ S
'Length) := S
;
162 Last
:= Last
+ S
'Length;
165 ---------------------------
166 -- Delete_Temporary_File --
167 ---------------------------
169 procedure Delete_Temporary_File
170 (Tree
: Project_Tree_Ref
;
171 Path
: Path_Name_Type
)
174 pragma Warnings
(Off
, Dont_Care
);
177 if not Debug
.Debug_Flag_N
then
178 if Current_Verbosity
= High
then
179 Write_Line
("Removing temp file: " & Get_Name_String
(Path
));
182 Delete_File
(Get_Name_String
(Path
), Dont_Care
);
185 1 .. Temp_Files_Table
.Last
(Tree
.Private_Part
.Temp_Files
)
187 if Tree
.Private_Part
.Temp_Files
.Table
(Index
) = Path
then
188 Tree
.Private_Part
.Temp_Files
.Table
(Index
) := No_Path
;
192 end Delete_Temporary_File
;
194 ---------------------------
195 -- Delete_All_Temp_Files --
196 ---------------------------
198 procedure Delete_All_Temp_Files
(Tree
: Project_Tree_Ref
) is
200 pragma Warnings
(Off
, Dont_Care
);
202 Path
: Path_Name_Type
;
205 if not Debug
.Debug_Flag_N
then
207 1 .. Temp_Files_Table
.Last
(Tree
.Private_Part
.Temp_Files
)
209 Path
:= Tree
.Private_Part
.Temp_Files
.Table
(Index
);
211 if Path
/= No_Path
then
212 if Current_Verbosity
= High
then
213 Write_Line
("Removing temp file: "
214 & Get_Name_String
(Path
));
217 Delete_File
(Get_Name_String
(Path
), Dont_Care
);
221 Temp_Files_Table
.Free
(Tree
.Private_Part
.Temp_Files
);
222 Temp_Files_Table
.Init
(Tree
.Private_Part
.Temp_Files
);
225 -- If any of the environment variables ADA_PRJ_INCLUDE_FILE or
226 -- ADA_PRJ_OBJECTS_FILE has been set, then reset their value to
227 -- the empty string. On VMS, this has the effect of deassigning
228 -- the logical names.
230 if Tree
.Private_Part
.Current_Source_Path_File
/= No_Path
then
231 Setenv
(Project_Include_Path_File
, "");
234 if Tree
.Private_Part
.Current_Object_Path_File
/= No_Path
then
235 Setenv
(Project_Objects_Path_File
, "");
237 end Delete_All_Temp_Files
;
239 ---------------------
240 -- Dependency_Name --
241 ---------------------
243 function Dependency_Name
244 (Source_File_Name
: File_Name_Type
;
245 Dependency
: Dependency_File_Kind
) return File_Name_Type
256 (Source_File_Name
, Makefile_Dependency_Suffix
));
262 (Source_File_Name
, ALI_Dependency_Suffix
));
270 function Empty_File
return File_Name_Type
is
272 return File_Name_Type
(The_Empty_String
);
279 function Empty_Project
return Project_Data
is
281 Prj
.Initialize
(Tree
=> No_Project_Tree
);
282 return Project_Empty
;
289 function Empty_String
return Name_Id
is
291 return The_Empty_String
;
298 procedure Expect
(The_Token
: Token_Type
; Token_Image
: String) is
300 if Token
/= The_Token
then
301 -- ??? Should pass user flags here instead
302 Error_Msg
(Gnatmake_Flags
, Token_Image
& " expected", Token_Ptr
);
311 (File
: File_Name_Type
;
312 With_Suffix
: String) return File_Name_Type
317 Get_Name_String
(File
);
318 Last
:= Name_Len
+ 1;
320 while Name_Len
/= 0 and then Name_Buffer
(Name_Len
) /= '.' loop
321 Name_Len
:= Name_Len
- 1;
324 if Name_Len
<= 1 then
328 for J
in With_Suffix
'Range loop
329 Name_Buffer
(Name_Len
) := With_Suffix
(J
);
330 Name_Len
:= Name_Len
+ 1;
333 Name_Len
:= Name_Len
- 1;
338 ---------------------
339 -- Project_Changed --
340 ---------------------
342 procedure Project_Changed
(Iter
: in out Source_Iterator
) is
344 Iter
.Language
:= Iter
.Project
.Project
.Languages
;
345 Language_Changed
(Iter
);
348 ----------------------
349 -- Language_Changed --
350 ----------------------
352 procedure Language_Changed
(Iter
: in out Source_Iterator
) is
354 Iter
.Current
:= No_Source
;
356 if Iter
.Language_Name
/= No_Name
then
357 while Iter
.Language
/= null
358 and then Iter
.Language
.Name
/= Iter
.Language_Name
360 Iter
.Language
:= Iter
.Language
.Next
;
364 -- If there is no matching language in this project, move to next
366 if Iter
.Language
= No_Language_Index
then
367 if Iter
.All_Projects
then
368 Iter
.Project
:= Iter
.Project
.Next
;
370 if Iter
.Project
/= null then
371 Project_Changed
(Iter
);
375 Iter
.Project
:= null;
379 Iter
.Current
:= Iter
.Language
.First_Source
;
381 if Iter
.Current
= No_Source
then
382 Iter
.Language
:= Iter
.Language
.Next
;
383 Language_Changed
(Iter
);
386 end Language_Changed
;
388 ---------------------
389 -- For_Each_Source --
390 ---------------------
392 function For_Each_Source
393 (In_Tree
: Project_Tree_Ref
;
394 Project
: Project_Id
:= No_Project
;
395 Language
: Name_Id
:= No_Name
) return Source_Iterator
397 Iter
: Source_Iterator
;
399 Iter
:= Source_Iterator
'
401 Project => In_Tree.Projects,
402 All_Projects => Project = No_Project,
403 Language_Name => Language,
404 Language => No_Language_Index,
405 Current => No_Source);
407 if Project /= null then
408 while Iter.Project /= null
409 and then Iter.Project.Project /= Project
411 Iter.Project := Iter.Project.Next;
415 Project_Changed (Iter);
424 function Element (Iter : Source_Iterator) return Source_Id is
433 procedure Next (Iter : in out Source_Iterator) is
435 Iter.Current := Iter.Current.Next_In_Lang;
436 if Iter.Current = No_Source then
437 Iter.Language := Iter.Language.Next;
438 Language_Changed (Iter);
442 --------------------------------
443 -- For_Every_Project_Imported --
444 --------------------------------
446 procedure For_Every_Project_Imported
448 With_State : in out State;
449 Imported_First : Boolean := False)
451 use Project_Boolean_Htable;
452 Seen : Project_Boolean_Htable.Instance := Project_Boolean_Htable.Nil;
454 procedure Recursive_Check (Project : Project_Id);
455 -- Check if a project has already been seen. If not seen, mark it as
456 -- Seen, Call Action, and check all its imported projects.
458 ---------------------
459 -- Recursive_Check --
460 ---------------------
462 procedure Recursive_Check (Project : Project_Id) is
466 if not Get (Seen, Project) then
467 Set (Seen, Project, True);
469 if not Imported_First then
470 Action (Project, With_State);
473 -- Visited all extended projects
475 if Project.Extends /= No_Project then
476 Recursive_Check (Project.Extends);
479 -- Visited all imported projects
481 List := Project.Imported_Projects;
482 while List /= null loop
483 Recursive_Check (List.Project);
487 if Imported_First then
488 Action (Project, With_State);
493 -- Start of processing for For_Every_Project_Imported
496 Recursive_Check (Project => By);
498 end For_Every_Project_Imported;
505 (In_Tree : Project_Tree_Ref;
506 Project : Project_Id;
507 In_Imported_Only : Boolean := False;
508 In_Extended_Only : Boolean := False;
509 Base_Name : File_Name_Type) return Source_Id
511 Result : Source_Id := No_Source;
513 procedure Look_For_Sources (Proj : Project_Id; Src : in out Source_Id);
514 -- Look for Base_Name in the sources of Proj
516 ----------------------
517 -- Look_For_Sources --
518 ----------------------
520 procedure Look_For_Sources (Proj : Project_Id; Src : in out Source_Id) is
521 Iterator : Source_Iterator;
524 Iterator := For_Each_Source (In_Tree => In_Tree, Project => Proj);
525 while Element (Iterator) /= No_Source loop
526 if Element (Iterator).File = Base_Name then
527 Src := Element (Iterator);
533 end Look_For_Sources;
535 procedure For_Imported_Projects is new For_Every_Project_Imported
536 (State => Source_Id, Action => Look_For_Sources);
540 -- Start of processing for Find_Source
543 if In_Extended_Only then
545 while Proj /= No_Project loop
546 Look_For_Sources (Proj, Result);
547 exit when Result /= No_Source;
549 Proj := Proj.Extends;
552 elsif In_Imported_Only then
553 Look_For_Sources (Project, Result);
555 if Result = No_Source then
556 For_Imported_Projects
558 With_State => Result);
561 Look_For_Sources (No_Project, Result);
571 function Hash is new System.HTable.Hash (Header_Num => Header_Num);
572 -- Used in implementation of other functions Hash below
574 function Hash (Name : File_Name_Type) return Header_Num is
576 return Hash (Get_Name_String (Name));
579 function Hash (Name : Name_Id) return Header_Num is
581 return Hash (Get_Name_String (Name));
584 function Hash (Name : Path_Name_Type) return Header_Num is
586 return Hash (Get_Name_String (Name));
589 function Hash (Project : Project_Id) return Header_Num is
591 if Project = No_Project then
592 return Header_Num'First;
594 return Hash (Get_Name_String (Project.Name));
602 function Image (The_Casing : Casing_Type) return String is
604 return The_Casing_Images (The_Casing).all;
607 -----------------------------
608 -- Is_Standard_GNAT_Naming --
609 -----------------------------
611 function Is_Standard_GNAT_Naming
612 (Naming : Lang_Naming_Data) return Boolean
615 return Get_Name_String (Naming.Spec_Suffix) = ".ads"
616 and then Get_Name_String (Naming.Body_Suffix) = ".adb"
617 and then Get_Name_String (Naming.Dot_Replacement) = "-";
618 end Is_Standard_GNAT_Naming;
624 procedure Initialize (Tree : Project_Tree_Ref) is
626 if The_Empty_String = No_Name then
629 The_Empty_String := Name_Find;
632 Set_Name_Table_Byte (Name_Project, Token_Type'Pos (Tok_Project));
633 Set_Name_Table_Byte (Name_Extends, Token_Type'Pos (Tok_Extends));
634 Set_Name_Table_Byte (Name_External, Token_Type'Pos (Tok_External));
637 if Tree /= No_Project_Tree then
646 function Is_Extending
647 (Extending : Project_Id;
648 Extended : Project_Id) return Boolean
654 while Proj /= No_Project loop
655 if Proj = Extended then
659 Proj := Proj.Extends;
670 (Source_File_Name : File_Name_Type;
671 Object_File_Suffix : Name_Id := No_Name) return File_Name_Type
674 if Object_File_Suffix = No_Name then
676 (Source_File_Name, Object_Suffix);
679 (Source_File_Name, Get_Name_String (Object_File_Suffix));
684 (Source_File_Name : File_Name_Type;
686 Index_Separator : Character;
687 Object_File_Suffix : Name_Id := No_Name) return File_Name_Type
689 Index_Img : constant String := Source_Index'Img;
693 Get_Name_String (Source_File_Name);
696 while Last > 1 and then Name_Buffer (Last) /= '.' loop
701 Name_Len := Last - 1;
704 Add_Char_To_Name_Buffer (Index_Separator);
705 Add_Str_To_Name_Buffer (Index_Img (2 .. Index_Img'Last));
707 if Object_File_Suffix = No_Name then
708 Add_Str_To_Name_Buffer (Object_Suffix);
710 Add_Str_To_Name_Buffer (Get_Name_String (Object_File_Suffix));
716 ----------------------
717 -- Record_Temp_File --
718 ----------------------
720 procedure Record_Temp_File
721 (Tree : Project_Tree_Ref;
722 Path : Path_Name_Type)
725 Temp_Files_Table.Append (Tree.Private_Part.Temp_Files, Path);
726 end Record_Temp_File;
732 procedure Free (Project : in out Project_Id) is
733 procedure Unchecked_Free is new Ada.Unchecked_Deallocation
734 (Project_Data, Project_Id);
737 if Project /= null then
738 Free (Project.Ada_Include_Path);
739 Free (Project.Objects_Path);
740 Free (Project.Ada_Objects_Path);
741 Free_List (Project.Imported_Projects, Free_Project => False);
742 Free_List (Project.All_Imported_Projects, Free_Project => False);
743 Free_List (Project.Languages);
745 Unchecked_Free (Project);
753 procedure Free_List (Languages : in out Language_List) is
754 procedure Unchecked_Free is new Ada.Unchecked_Deallocation
755 (Language_List_Element, Language_List);
758 while Languages /= null loop
759 Tmp := Languages.Next;
760 Unchecked_Free (Languages);
769 procedure Free_List (Source : in out Source_Id) is
770 procedure Unchecked_Free is new
771 Ada.Unchecked_Deallocation (Source_Data, Source_Id);
776 while Source /= No_Source loop
777 Tmp := Source.Next_In_Lang;
778 Free_List (Source.Alternate_Languages);
780 if Source.Unit /= null
781 and then Source.Kind in Spec_Or_Body
783 Source.Unit.File_Names (Source.Kind) := null;
786 Unchecked_Free (Source);
796 (List : in out Project_List;
797 Free_Project : Boolean)
799 procedure Unchecked_Free is new
800 Ada.Unchecked_Deallocation (Project_List_Element, Project_List);
805 while List /= null loop
812 Unchecked_Free (List);
821 procedure Free_List (Languages : in out Language_Ptr) is
822 procedure Unchecked_Free is new
823 Ada.Unchecked_Deallocation (Language_Data, Language_Ptr);
828 while Languages /= null loop
829 Tmp := Languages.Next;
830 Free_List (Languages.First_Source);
831 Unchecked_Free (Languages);
840 procedure Free_Units (Table : in out Units_Htable.Instance) is
841 procedure Unchecked_Free is new
842 Ada.Unchecked_Deallocation (Unit_Data, Unit_Index);
847 Unit := Units_Htable.Get_First (Table);
848 while Unit /= No_Unit_Index loop
849 if Unit.File_Names (Spec) /= null then
850 Unit.File_Names (Spec).Unit := No_Unit_Index;
853 if Unit.File_Names (Impl) /= null then
854 Unit.File_Names (Impl).Unit := No_Unit_Index;
857 Unchecked_Free (Unit);
858 Unit := Units_Htable.Get_Next (Table);
861 Units_Htable.Reset (Table);
868 procedure Free (Tree : in out Project_Tree_Ref) is
869 procedure Unchecked_Free is new
870 Ada.Unchecked_Deallocation (Project_Tree_Data, Project_Tree_Ref);
874 Name_List_Table.Free (Tree.Name_Lists);
875 Number_List_Table.Free (Tree.Number_Lists);
876 String_Element_Table.Free (Tree.String_Elements);
877 Variable_Element_Table.Free (Tree.Variable_Elements);
878 Array_Element_Table.Free (Tree.Array_Elements);
879 Array_Table.Free (Tree.Arrays);
880 Package_Table.Free (Tree.Packages);
881 Source_Paths_Htable.Reset (Tree.Source_Paths_HT);
883 Free_List (Tree.Projects, Free_Project => True);
884 Free_Units (Tree.Units_HT);
888 Temp_Files_Table.Free (Tree.Private_Part.Temp_Files);
890 Unchecked_Free (Tree);
898 procedure Reset (Tree : Project_Tree_Ref) is
902 Name_List_Table.Init (Tree.Name_Lists);
903 Number_List_Table.Init (Tree.Number_Lists);
904 String_Element_Table.Init (Tree.String_Elements);
905 Variable_Element_Table.Init (Tree.Variable_Elements);
906 Array_Element_Table.Init (Tree.Array_Elements);
907 Array_Table.Init (Tree.Arrays);
908 Package_Table.Init (Tree.Packages);
909 Source_Paths_Htable.Reset (Tree.Source_Paths_HT);
911 Free_List (Tree.Projects, Free_Project => True);
912 Free_Units (Tree.Units_HT);
914 -- Private part table
916 Temp_Files_Table.Init (Tree.Private_Part.Temp_Files);
918 Tree.Private_Part.Current_Source_Path_File := No_Path;
919 Tree.Private_Part.Current_Object_Path_File := No_Path;
926 function Switches_Name
927 (Source_File_Name : File_Name_Type) return File_Name_Type
930 return Extend_Name (Source_File_Name, Switches_Dependency_Suffix);
937 function Value (Image : String) return Casing_Type is
939 for Casing in The_Casing_Images'Range loop
940 if To_Lower (Image) = To_Lower (The_Casing_Images (Casing).all) then
945 raise Constraint_Error;
948 ---------------------
949 -- Has_Ada_Sources --
950 ---------------------
952 function Has_Ada_Sources (Data : Project_Id) return Boolean is
956 Lang := Data.Languages;
957 while Lang /= No_Language_Index loop
958 if Lang.Name = Name_Ada then
959 return Lang.First_Source /= No_Source;
967 ------------------------
968 -- Contains_ALI_Files --
969 ------------------------
971 function Contains_ALI_Files (Dir : Path_Name_Type) return Boolean is
972 Dir_Name : constant String := Get_Name_String (Dir);
974 Name : String (1 .. 1_000);
976 Result : Boolean := False;
979 Open (Direct, Dir_Name);
981 -- For each file in the directory, check if it is an ALI file
984 Read (Direct, Name, Last);
986 Canonical_Case_File_Name (Name (1 .. Last));
987 Result := Last >= 5 and then Name (Last - 3 .. Last) = ".ali";
995 -- If there is any problem, close the directory if open and return True.
996 -- The library directory will be added to the path.
999 if Is_Open (Direct) then
1004 end Contains_ALI_Files;
1006 --------------------------
1007 -- Get_Object_Directory --
1008 --------------------------
1010 function Get_Object_Directory
1011 (Project : Project_Id;
1012 Including_Libraries : Boolean;
1013 Only_If_Ada : Boolean := False) return Path_Name_Type
1016 if (Project.Library and then Including_Libraries)
1018 (Project.Object_Directory /= No_Path_Information
1019 and then (not Including_Libraries or else not Project.Library))
1021 -- For a library project, add the library ALI directory if there is
1022 -- no object directory or if the library ALI directory contains ALI
1023 -- files; otherwise add the object directory.
1025 if Project.Library then
1026 if Project.Object_Directory = No_Path_Information
1027 or else Contains_ALI_Files (Project.Library_ALI_Dir.Name)
1029 return Project.Library_ALI_Dir.Name;
1031 return Project.Object_Directory.Name;
1034 -- For a non-library project, add object directory if it is not a
1035 -- virtual project, and if there are Ada sources in the project or
1036 -- one of the projects it extends. If there are no Ada sources,
1037 -- adding the object directory could disrupt the order of the
1038 -- object dirs in the path.
1040 elsif not Project.Virtual then
1042 Add_Object_Dir : Boolean;
1046 Add_Object_Dir := not Only_If_Ada;
1048 while not Add_Object_Dir and then Prj /= No_Project loop
1049 if Has_Ada_Sources (Prj) then
1050 Add_Object_Dir := True;
1056 if Add_Object_Dir then
1057 return Project.Object_Directory.Name;
1064 end Get_Object_Directory;
1066 -----------------------------------
1067 -- Ultimate_Extending_Project_Of --
1068 -----------------------------------
1070 function Ultimate_Extending_Project_Of
1071 (Proj : Project_Id) return Project_Id
1077 while Prj /= null and then Prj.Extended_By /= No_Project loop
1078 Prj := Prj.Extended_By;
1082 end Ultimate_Extending_Project_Of;
1084 -----------------------------------
1085 -- Compute_All_Imported_Projects --
1086 -----------------------------------
1088 procedure Compute_All_Imported_Projects (Tree : Project_Tree_Ref) is
1089 Project : Project_Id;
1091 procedure Recursive_Add (Prj : Project_Id; Dummy : in out Boolean);
1092 -- Recursively add the projects imported by project Project, but not
1093 -- those that are extended.
1099 procedure Recursive_Add (Prj : Project_Id; Dummy : in out Boolean) is
1100 pragma Unreferenced (Dummy);
1101 List : Project_List;
1105 -- A project is not importing itself
1107 Prj2 := Ultimate_Extending_Project_Of (Prj);
1109 if Project /= Prj2 then
1111 -- Check that the project is not already in the list. We know the
1112 -- one passed to Recursive_Add have never been visited before, but
1113 -- the one passed it are the extended projects.
1115 List := Project.All_Imported_Projects;
1116 while List /= null loop
1117 if List.Project = Prj2 then
1124 -- Add it to the list
1126 Project.All_Imported_Projects :=
1127 new Project_List_Element'
1129 Next
=> Project
.All_Imported_Projects
);
1133 procedure For_All_Projects
is
1134 new For_Every_Project_Imported
(Boolean, Recursive_Add
);
1136 Dummy
: Boolean := False;
1137 List
: Project_List
;
1140 List
:= Tree
.Projects
;
1141 while List
/= null loop
1142 Project
:= List
.Project
;
1143 Free_List
(Project
.All_Imported_Projects
, Free_Project
=> False);
1144 For_All_Projects
(Project
, Dummy
);
1147 end Compute_All_Imported_Projects
;
1153 function Is_Compilable
(Source
: Source_Id
) return Boolean is
1155 return Source
.Language
.Config
.Compiler_Driver
/= No_File
1156 and then Length_Of_Name
(Source
.Language
.Config
.Compiler_Driver
) /= 0
1157 and then not Source
.Locally_Removed
;
1160 ------------------------------
1161 -- Object_To_Global_Archive --
1162 ------------------------------
1164 function Object_To_Global_Archive
(Source
: Source_Id
) return Boolean is
1166 return Source
.Language
.Config
.Kind
= File_Based
1167 and then Source
.Kind
= Impl
1168 and then Source
.Language
.Config
.Objects_Linked
1169 and then Is_Compilable
(Source
)
1170 and then Source
.Language
.Config
.Object_Generated
;
1171 end Object_To_Global_Archive
;
1173 ----------------------------
1174 -- Get_Language_From_Name --
1175 ----------------------------
1177 function Get_Language_From_Name
1178 (Project
: Project_Id
;
1179 Name
: String) return Language_Ptr
1182 Result
: Language_Ptr
;
1185 Name_Len
:= Name
'Length;
1186 Name_Buffer
(1 .. Name_Len
) := Name
;
1187 To_Lower
(Name_Buffer
(1 .. Name_Len
));
1190 Result
:= Project
.Languages
;
1191 while Result
/= No_Language_Index
loop
1192 if Result
.Name
= N
then
1196 Result
:= Result
.Next
;
1199 return No_Language_Index
;
1200 end Get_Language_From_Name
;
1206 function Other_Part
(Source
: Source_Id
) return Source_Id
is
1208 if Source
.Unit
/= No_Unit_Index
then
1211 return Source
.Unit
.File_Names
(Spec
);
1213 return Source
.Unit
.File_Names
(Impl
);
1226 function Create_Flags
1227 (Report_Error
: Error_Handler
;
1228 When_No_Sources
: Error_Warning
;
1229 Require_Sources_Other_Lang
: Boolean := True;
1230 Allow_Duplicate_Basenames
: Boolean := True;
1231 Compiler_Driver_Mandatory
: Boolean := False;
1232 Error_On_Unknown_Language
: Boolean := True;
1233 Require_Obj_Dirs
: Error_Warning
:= Error
)
1234 return Processing_Flags
1237 return Processing_Flags
'
1238 (Report_Error => Report_Error,
1239 When_No_Sources => When_No_Sources,
1240 Require_Sources_Other_Lang => Require_Sources_Other_Lang,
1241 Allow_Duplicate_Basenames => Allow_Duplicate_Basenames,
1242 Error_On_Unknown_Language => Error_On_Unknown_Language,
1243 Compiler_Driver_Mandatory => Compiler_Driver_Mandatory,
1244 Require_Obj_Dirs => Require_Obj_Dirs);
1252 (Table : Name_List_Table.Instance;
1253 List : Name_List_Index) return Natural
1255 Count : Natural := 0;
1256 Tmp : Name_List_Index;
1260 while Tmp /= No_Name_List loop
1262 Tmp := Table.Table (Tmp).Next;
1269 -- Make sure that the standard config and user project file extensions are
1270 -- compatible with canonical case file naming.
1272 Canonical_Case_File_Name (Config_Project_File_Extension);
1273 Canonical_Case_File_Name (Project_File_Extension);