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 Namet
; use Namet
;
29 with Osint
; use Osint
;
30 with Output
; use Output
;
31 with Prj
.Com
; use Prj
.Com
;
34 with GNAT
.Directory_Operations
; use GNAT
.Directory_Operations
;
36 package body Prj
.Env
is
38 Current_Source_Path_File
: Name_Id
:= No_Name
;
39 -- Current value of project source path file env var.
40 -- Used to avoid setting the env var to the same value.
42 Current_Object_Path_File
: Name_Id
:= No_Name
;
43 -- Current value of project object path file env var.
44 -- Used to avoid setting the env var to the same value.
46 Ada_Path_Buffer
: String_Access
:= new String (1 .. 1024);
47 -- A buffer where values for ADA_INCLUDE_PATH
48 -- and ADA_OBJECTS_PATH are stored.
50 Ada_Path_Length
: Natural := 0;
51 -- Index of the last valid character in Ada_Path_Buffer
53 Ada_Prj_Include_File_Set
: Boolean := False;
54 Ada_Prj_Objects_File_Set
: Boolean := False;
55 -- These flags are set to True when the corresponding environment variables
56 -- are set and are used to give these environment variables an empty string
57 -- value at the end of the program. This has no practical effect on most
58 -- platforms, except on VMS where the logical names are deassigned, thus
59 -- avoiding the pollution of the environment of the caller.
61 Default_Naming
: constant Naming_Id
:= Naming_Table
.First
;
63 Fill_Mapping_File
: Boolean := True;
65 type Project_Flags
is array (Project_Id
range <>) of Boolean;
66 -- A Boolean array type used in Create_Mapping_File to select the projects
67 -- in the closure of a specific project.
69 -----------------------
70 -- Local Subprograms --
71 -----------------------
73 function Body_Path_Name_Of
75 In_Tree
: Project_Tree_Ref
) return String;
76 -- Returns the path name of the body of a unit.
77 -- Compute it first, if necessary.
79 function Spec_Path_Name_Of
81 In_Tree
: Project_Tree_Ref
) return String;
82 -- Returns the path name of the spec of a unit.
83 -- Compute it first, if necessary.
86 (Source_Dirs
: String_List_Id
;
87 In_Tree
: Project_Tree_Ref
);
88 -- Add to Ada_Path_Buffer all the source directories in string list
89 -- Source_Dirs, if any. Increment Ada_Path_Length.
91 procedure Add_To_Path
(Dir
: String);
92 -- If Dir is not already in the global variable Ada_Path_Buffer, add it.
93 -- Increment Ada_Path_Length.
94 -- If Ada_Path_Length /= 0, prepend a Path_Separator character to
97 procedure Add_To_Source_Path
98 (Source_Dirs
: String_List_Id
; In_Tree
: Project_Tree_Ref
);
99 -- Add to Ada_Path_B all the source directories in string list
100 -- Source_Dirs, if any. Increment Ada_Path_Length.
102 procedure Add_To_Object_Path
103 (Object_Dir
: Name_Id
;
104 In_Tree
: Project_Tree_Ref
);
105 -- Add Object_Dir to object path table. Make sure it is not duplicate
106 -- and it is the last one in the current table.
108 function Contains_ALI_Files
(Dir
: Name_Id
) return Boolean;
109 -- Return True if there is at least one ALI file in the directory Dir
111 procedure Create_New_Path_File
112 (In_Tree
: Project_Tree_Ref
;
113 Path_FD
: out File_Descriptor
;
114 Path_Name
: out Name_Id
);
115 -- Create a new temporary path file. Get the file name in Path_Name.
116 -- The name is normally obtained by increasing the number in
117 -- Temp_Path_File_Name by 1.
119 procedure Set_Path_File_Var
(Name
: String; Value
: String);
120 -- Call Setenv, after calling To_Host_File_Spec
122 function Ultimate_Extension_Of
123 (Project
: Project_Id
;
124 In_Tree
: Project_Tree_Ref
) return Project_Id
;
125 -- Return a project that is either Project or an extended ancestor of
126 -- Project that itself is not extended.
128 ----------------------
129 -- Ada_Include_Path --
130 ----------------------
132 function Ada_Include_Path
133 (Project
: Project_Id
;
134 In_Tree
: Project_Tree_Ref
) return String_Access
is
136 procedure Add
(Project
: Project_Id
);
137 -- Add all the source directories of a project to the path only if
138 -- this project has not been visited. Calls itself recursively for
139 -- projects being extended, and imported projects. Adds the project
140 -- to the list Seen if this is the call to Add for this project.
146 procedure Add
(Project
: Project_Id
) is
148 -- If Seen is empty, then the project cannot have been visited
150 if not In_Tree
.Projects
.Table
(Project
).Seen
then
151 In_Tree
.Projects
.Table
(Project
).Seen
:= True;
154 Data
: constant Project_Data
:=
155 In_Tree
.Projects
.Table
(Project
);
156 List
: Project_List
:= Data
.Imported_Projects
;
159 -- Add to path all source directories of this project
161 Add_To_Path
(Data
.Source_Dirs
, In_Tree
);
163 -- Call Add to the project being extended, if any
165 if Data
.Extends
/= No_Project
then
169 -- Call Add for each imported project, if any
171 while List
/= Empty_Project_List
loop
173 (In_Tree
.Project_Lists
.Table
(List
).Project
);
174 List
:= In_Tree
.Project_Lists
.Table
(List
).Next
;
180 -- Start of processing for Ada_Include_Path
183 -- If it is the first time we call this function for
184 -- this project, compute the source path
187 In_Tree
.Projects
.Table
(Project
).Ada_Include_Path
= null
189 Ada_Path_Length
:= 0;
191 for Index
in Project_Table
.First
..
192 Project_Table
.Last
(In_Tree
.Projects
)
194 In_Tree
.Projects
.Table
(Index
).Seen
:= False;
198 In_Tree
.Projects
.Table
(Project
).Ada_Include_Path
:=
199 new String'(Ada_Path_Buffer (1 .. Ada_Path_Length));
202 return In_Tree.Projects.Table (Project).Ada_Include_Path;
203 end Ada_Include_Path;
205 ----------------------
206 -- Ada_Include_Path --
207 ----------------------
209 function Ada_Include_Path
210 (Project : Project_Id;
211 In_Tree : Project_Tree_Ref;
212 Recursive : Boolean) return String
216 return Ada_Include_Path (Project, In_Tree).all;
218 Ada_Path_Length := 0;
220 (In_Tree.Projects.Table (Project).Source_Dirs, In_Tree);
221 return Ada_Path_Buffer (1 .. Ada_Path_Length);
223 end Ada_Include_Path;
225 ----------------------
226 -- Ada_Objects_Path --
227 ----------------------
229 function Ada_Objects_Path
230 (Project : Project_Id;
231 In_Tree : Project_Tree_Ref;
232 Including_Libraries : Boolean := True) return String_Access
234 procedure Add (Project : Project_Id);
235 -- Add all the object directories of a project to the path only if
236 -- this project has not been visited. Calls itself recursively for
237 -- projects being extended, and imported projects. Adds the project
238 -- to the list Seen if this is the first call to Add for this project.
244 procedure Add (Project : Project_Id) is
246 -- If this project has not been seen yet
248 if not In_Tree.Projects.Table (Project).Seen then
249 In_Tree.Projects.Table (Project).Seen := True;
252 Data : constant Project_Data :=
253 In_Tree.Projects.Table (Project);
254 List : Project_List := Data.Imported_Projects;
257 -- Add to path the object directory of this project
258 -- except if we don't include library project and
259 -- this is a library project.
261 if (Data.Library and then Including_Libraries)
263 (Data.Object_Directory /= No_Name
265 (not Including_Libraries or else not Data.Library))
267 -- For a library project, add the library directory,
268 -- if there is no object directory or if it contains ALI
269 -- files; otherwise add the object directory.
272 if Data.Object_Directory = No_Name
274 Contains_ALI_Files (Data.Library_ALI_Dir)
276 Add_To_Path (Get_Name_String (Data.Library_ALI_Dir));
278 Add_To_Path (Get_Name_String (Data.Object_Directory));
282 -- For a non library project, add the object directory
284 Add_To_Path (Get_Name_String (Data.Object_Directory));
288 -- Call Add to the project being extended, if any
290 if Data.Extends /= No_Project then
294 -- Call Add for each imported project, if any
296 while List /= Empty_Project_List loop
298 (In_Tree.Project_Lists.Table (List).Project);
299 List := In_Tree.Project_Lists.Table (List).Next;
306 -- Start of processing for Ada_Objects_Path
309 -- If it is the first time we call this function for
310 -- this project, compute the objects path
313 In_Tree.Projects.Table (Project).Ada_Objects_Path = null
315 Ada_Path_Length := 0;
317 for Index in Project_Table.First ..
318 Project_Table.Last (In_Tree.Projects)
320 In_Tree.Projects.Table (Index).Seen := False;
324 In_Tree.Projects.Table (Project).Ada_Objects_Path :=
325 new String'(Ada_Path_Buffer
(1 .. Ada_Path_Length
));
328 return In_Tree
.Projects
.Table
(Project
).Ada_Objects_Path
;
329 end Ada_Objects_Path
;
331 ------------------------
332 -- Add_To_Object_Path --
333 ------------------------
335 procedure Add_To_Object_Path
336 (Object_Dir
: Name_Id
; In_Tree
: Project_Tree_Ref
)
339 -- Check if the directory is already in the table
341 for Index
in Object_Path_Table
.First
..
342 Object_Path_Table
.Last
(In_Tree
.Private_Part
.Object_Paths
)
345 -- If it is, remove it, and add it as the last one
347 if In_Tree
.Private_Part
.Object_Paths
.Table
(Index
) = Object_Dir
then
348 for Index2
in Index
+ 1 ..
349 Object_Path_Table
.Last
350 (In_Tree
.Private_Part
.Object_Paths
)
352 In_Tree
.Private_Part
.Object_Paths
.Table
(Index2
- 1) :=
353 In_Tree
.Private_Part
.Object_Paths
.Table
(Index2
);
356 In_Tree
.Private_Part
.Object_Paths
.Table
357 (Object_Path_Table
.Last
(In_Tree
.Private_Part
.Object_Paths
)) :=
363 -- The directory is not already in the table, add it
365 Object_Path_Table
.Increment_Last
(In_Tree
.Private_Part
.Object_Paths
);
366 In_Tree
.Private_Part
.Object_Paths
.Table
367 (Object_Path_Table
.Last
(In_Tree
.Private_Part
.Object_Paths
)) :=
369 end Add_To_Object_Path
;
375 procedure Add_To_Path
376 (Source_Dirs
: String_List_Id
;
377 In_Tree
: Project_Tree_Ref
)
379 Current
: String_List_Id
:= Source_Dirs
;
380 Source_Dir
: String_Element
;
382 while Current
/= Nil_String
loop
383 Source_Dir
:= In_Tree
.String_Elements
.Table
(Current
);
384 Add_To_Path
(Get_Name_String
(Source_Dir
.Display_Value
));
385 Current
:= Source_Dir
.Next
;
389 procedure Add_To_Path
(Dir
: String) is
391 New_Buffer
: String_Access
;
394 function Is_Present
(Path
: String; Dir
: String) return Boolean;
395 -- Return True if Dir is part of Path
401 function Is_Present
(Path
: String; Dir
: String) return Boolean is
402 Last
: constant Integer := Path
'Last - Dir
'Length + 1;
405 for J
in Path
'First .. Last
loop
407 -- Note: the order of the conditions below is important, since
408 -- it ensures a minimal number of string comparisons.
411 or else Path
(J
- 1) = Path_Separator
)
413 (J
+ Dir
'Length > Path
'Last
414 or else Path
(J
+ Dir
'Length) = Path_Separator
)
415 and then Dir
= Path
(J
.. J
+ Dir
'Length - 1)
424 -- Start of processing for Add_To_Path
427 if Is_Present
(Ada_Path_Buffer
(1 .. Ada_Path_Length
), Dir
) then
429 -- Dir is already in the path, nothing to do
434 Min_Len
:= Ada_Path_Length
+ Dir
'Length;
436 if Ada_Path_Length
> 0 then
438 -- Add 1 for the Path_Separator character
440 Min_Len
:= Min_Len
+ 1;
443 -- If Ada_Path_Buffer is too small, increase it
445 Len
:= Ada_Path_Buffer
'Last;
447 if Len
< Min_Len
then
450 exit when Len
>= Min_Len
;
453 New_Buffer
:= new String (1 .. Len
);
454 New_Buffer
(1 .. Ada_Path_Length
) :=
455 Ada_Path_Buffer
(1 .. Ada_Path_Length
);
456 Free
(Ada_Path_Buffer
);
457 Ada_Path_Buffer
:= New_Buffer
;
460 if Ada_Path_Length
> 0 then
461 Ada_Path_Length
:= Ada_Path_Length
+ 1;
462 Ada_Path_Buffer
(Ada_Path_Length
) := Path_Separator
;
466 (Ada_Path_Length
+ 1 .. Ada_Path_Length
+ Dir
'Length) := Dir
;
467 Ada_Path_Length
:= Ada_Path_Length
+ Dir
'Length;
470 ------------------------
471 -- Add_To_Source_Path --
472 ------------------------
474 procedure Add_To_Source_Path
475 (Source_Dirs
: String_List_Id
; In_Tree
: Project_Tree_Ref
)
477 Current
: String_List_Id
:= Source_Dirs
;
478 Source_Dir
: String_Element
;
482 -- Add each source directory
484 while Current
/= Nil_String
loop
485 Source_Dir
:= In_Tree
.String_Elements
.Table
(Current
);
488 -- Check if the source directory is already in the table
490 for Index
in Source_Path_Table
.First
..
491 Source_Path_Table
.Last
492 (In_Tree
.Private_Part
.Source_Paths
)
494 -- If it is already, no need to add it
496 if In_Tree
.Private_Part
.Source_Paths
.Table
(Index
) =
505 Source_Path_Table
.Increment_Last
506 (In_Tree
.Private_Part
.Source_Paths
);
507 In_Tree
.Private_Part
.Source_Paths
.Table
508 (Source_Path_Table
.Last
(In_Tree
.Private_Part
.Source_Paths
)) :=
512 -- Next source directory
514 Current
:= Source_Dir
.Next
;
516 end Add_To_Source_Path
;
518 -----------------------
519 -- Body_Path_Name_Of --
520 -----------------------
522 function Body_Path_Name_Of
523 (Unit
: Unit_Id
; In_Tree
: Project_Tree_Ref
) return String
525 Data
: Unit_Data
:= In_Tree
.Units
.Table
(Unit
);
528 -- If we don't know the path name of the body of this unit,
529 -- we compute it, and we store it.
531 if Data
.File_Names
(Body_Part
).Path
= No_Name
then
533 Current_Source
: String_List_Id
:=
534 In_Tree
.Projects
.Table
535 (Data
.File_Names
(Body_Part
).Project
).Sources
;
536 Path
: GNAT
.OS_Lib
.String_Access
;
539 -- By default, put the file name
541 Data
.File_Names
(Body_Part
).Path
:=
542 Data
.File_Names
(Body_Part
).Name
;
544 -- For each source directory
546 while Current_Source
/= Nil_String
loop
549 (Namet
.Get_Name_String
550 (Data
.File_Names
(Body_Part
).Name
),
551 Namet
.Get_Name_String
552 (In_Tree
.String_Elements
.Table
553 (Current_Source
).Value
));
555 -- If the file is in this directory, then we store the path,
559 Name_Len
:= Path
'Length;
560 Name_Buffer
(1 .. Name_Len
) := Path
.all;
561 Data
.File_Names
(Body_Part
).Path
:= Name_Enter
;
566 In_Tree
.String_Elements
.Table
567 (Current_Source
).Next
;
571 In_Tree
.Units
.Table
(Unit
) := Data
;
575 -- Returned the stored value
577 return Namet
.Get_Name_String
(Data
.File_Names
(Body_Part
).Path
);
578 end Body_Path_Name_Of
;
580 ------------------------
581 -- Contains_ALI_Files --
582 ------------------------
584 function Contains_ALI_Files
(Dir
: Name_Id
) return Boolean is
585 Dir_Name
: constant String := Get_Name_String
(Dir
);
587 Name
: String (1 .. 1_000
);
589 Result
: Boolean := False;
592 Open
(Direct
, Dir_Name
);
594 -- For each file in the directory, check if it is an ALI file
597 Read
(Direct
, Name
, Last
);
599 Canonical_Case_File_Name
(Name
(1 .. Last
));
600 Result
:= Last
>= 5 and then Name
(Last
- 3 .. Last
) = ".ali";
608 -- If there is any problem, close the directory if open and return
609 -- True; the library directory will be added to the path.
612 if Is_Open
(Direct
) then
617 end Contains_ALI_Files
;
619 --------------------------------
620 -- Create_Config_Pragmas_File --
621 --------------------------------
623 procedure Create_Config_Pragmas_File
624 (For_Project
: Project_Id
;
625 Main_Project
: Project_Id
;
626 In_Tree
: Project_Tree_Ref
;
627 Include_Config_Files
: Boolean := True)
629 pragma Unreferenced
(Main_Project
);
630 pragma Unreferenced
(Include_Config_Files
);
632 File_Name
: Name_Id
:= No_Name
;
633 File
: File_Descriptor
:= Invalid_FD
;
635 Current_Unit
: Unit_Id
:= Unit_Table
.First
;
637 First_Project
: Project_List
:= Empty_Project_List
;
639 Current_Project
: Project_List
;
640 Current_Naming
: Naming_Id
;
645 procedure Check
(Project
: Project_Id
);
646 -- Recursive procedure that put in the config pragmas file any non
647 -- standard naming schemes, if it is not already in the file, then call
648 -- itself for any imported project.
650 procedure Check_Temp_File
;
651 -- Check that a temporary file has been opened.
652 -- If not, create one, and put its name in the project data,
653 -- with the indication that it is a temporary file.
656 (Unit_Name
: Name_Id
;
658 Unit_Kind
: Spec_Or_Body
;
660 -- Put an SFN pragma in the temporary file
662 procedure Put
(File
: File_Descriptor
; S
: String);
663 procedure Put_Line
(File
: File_Descriptor
; S
: String);
664 -- Output procedures, analogous to normal Text_IO procs of same name
670 procedure Check
(Project
: Project_Id
) is
671 Data
: constant Project_Data
:=
672 In_Tree
.Projects
.Table
(Project
);
675 if Current_Verbosity
= High
then
676 Write_Str
("Checking project file """);
677 Write_Str
(Namet
.Get_Name_String
(Data
.Name
));
682 -- Is this project in the list of the visited project?
684 Current_Project
:= First_Project
;
685 while Current_Project
/= Empty_Project_List
686 and then In_Tree
.Project_Lists
.Table
687 (Current_Project
).Project
/= Project
690 In_Tree
.Project_Lists
.Table
(Current_Project
).Next
;
693 -- If it is not, put it in the list, and visit it
695 if Current_Project
= Empty_Project_List
then
696 Project_List_Table
.Increment_Last
697 (In_Tree
.Project_Lists
);
698 In_Tree
.Project_Lists
.Table
699 (Project_List_Table
.Last
(In_Tree
.Project_Lists
)) :=
700 (Project
=> Project
, Next
=> First_Project
);
702 Project_List_Table
.Last
(In_Tree
.Project_Lists
);
704 -- Is the naming scheme of this project one that we know?
706 Current_Naming
:= Default_Naming
;
707 while Current_Naming
<=
708 Naming_Table
.Last
(In_Tree
.Private_Part
.Namings
)
709 and then not Same_Naming_Scheme
710 (Left
=> In_Tree
.Private_Part
.Namings
.Table
(Current_Naming
),
711 Right
=> Data
.Naming
) loop
712 Current_Naming
:= Current_Naming
+ 1;
715 -- If we don't know it, add it
718 Naming_Table
.Last
(In_Tree
.Private_Part
.Namings
)
720 Naming_Table
.Increment_Last
(In_Tree
.Private_Part
.Namings
);
721 In_Tree
.Private_Part
.Namings
.Table
722 (Naming_Table
.Last
(In_Tree
.Private_Part
.Namings
)) :=
725 -- We need a temporary file to be created
729 -- Put the SFN pragmas for the naming scheme
734 (File
, "pragma Source_File_Name_Project");
736 (File
, " (Spec_File_Name => ""*" &
737 Namet
.Get_Name_String
(Data
.Naming
.Ada_Spec_Suffix
) &
740 (File
, " Casing => " &
741 Image
(Data
.Naming
.Casing
) & ",");
743 (File
, " Dot_Replacement => """ &
744 Namet
.Get_Name_String
(Data
.Naming
.Dot_Replacement
) &
750 (File
, "pragma Source_File_Name_Project");
752 (File
, " (Body_File_Name => ""*" &
753 Namet
.Get_Name_String
(Data
.Naming
.Ada_Body_Suffix
) &
756 (File
, " Casing => " &
757 Image
(Data
.Naming
.Casing
) & ",");
759 (File
, " Dot_Replacement => """ &
760 Namet
.Get_Name_String
(Data
.Naming
.Dot_Replacement
) &
763 -- and maybe separate
766 Data
.Naming
.Ada_Body_Suffix
/= Data
.Naming
.Separate_Suffix
769 (File
, "pragma Source_File_Name_Project");
771 (File
, " (Subunit_File_Name => ""*" &
772 Namet
.Get_Name_String
(Data
.Naming
.Separate_Suffix
) &
775 (File
, " Casing => " &
776 Image
(Data
.Naming
.Casing
) &
779 (File
, " Dot_Replacement => """ &
780 Namet
.Get_Name_String
(Data
.Naming
.Dot_Replacement
) &
785 if Data
.Extends
/= No_Project
then
786 Check
(Data
.Extends
);
790 Current
: Project_List
:= Data
.Imported_Projects
;
793 while Current
/= Empty_Project_List
loop
795 (In_Tree
.Project_Lists
.Table
797 Current
:= In_Tree
.Project_Lists
.Table
804 ---------------------
805 -- Check_Temp_File --
806 ---------------------
808 procedure Check_Temp_File
is
810 if File
= Invalid_FD
then
811 Tempdir
.Create_Temp_File
(File
, Name
=> File_Name
);
813 if File
= Invalid_FD
then
815 ("unable to create temporary configuration pragmas file");
816 elsif Opt
.Verbose_Mode
then
817 Write_Str
("Creating temp file """);
818 Write_Str
(Get_Name_String
(File_Name
));
829 (Unit_Name
: Name_Id
;
831 Unit_Kind
: Spec_Or_Body
;
835 -- A temporary file needs to be open
839 -- Put the pragma SFN for the unit kind (spec or body)
841 Put
(File
, "pragma Source_File_Name_Project (");
842 Put
(File
, Namet
.Get_Name_String
(Unit_Name
));
844 if Unit_Kind
= Specification
then
845 Put
(File
, ", Spec_File_Name => """);
847 Put
(File
, ", Body_File_Name => """);
850 Put
(File
, Namet
.Get_Name_String
(File_Name
));
854 Put
(File
, ", Index =>");
855 Put
(File
, Index
'Img);
858 Put_Line
(File
, ");");
861 procedure Put
(File
: File_Descriptor
; S
: String) is
865 Last
:= Write
(File
, S
(S
'First)'Address, S
'Length);
867 if Last
/= S
'Length then
868 Prj
.Com
.Fail
("Disk full");
871 if Current_Verbosity
= High
then
880 procedure Put_Line
(File
: File_Descriptor
; S
: String) is
881 S0
: String (1 .. S
'Length + 1);
885 -- Add an ASCII.LF to the string. As this config file is supposed to
886 -- be used only by the compiler, we don't care about the characters
887 -- for the end of line. In fact we could have put a space, but
888 -- it is more convenient to be able to read gnat.adc during
889 -- development, for which the ASCII.LF is fine.
891 S0
(1 .. S
'Length) := S
;
892 S0
(S0
'Last) := ASCII
.LF
;
893 Last
:= Write
(File
, S0
'Address, S0
'Length);
895 if Last
/= S
'Length + 1 then
896 Prj
.Com
.Fail
("Disk full");
899 if Current_Verbosity
= High
then
904 -- Start of processing for Create_Config_Pragmas_File
908 In_Tree
.Projects
.Table
(For_Project
).Config_Checked
911 -- Remove any memory of processed naming schemes, if any
913 Naming_Table
.Set_Last
(In_Tree
.Private_Part
.Namings
, Default_Naming
);
915 -- Check the naming schemes
919 -- Visit all the units and process those that need an SFN pragma
922 Current_Unit
<= Unit_Table
.Last
(In_Tree
.Units
)
925 Unit
: constant Unit_Data
:=
926 In_Tree
.Units
.Table
(Current_Unit
);
929 if Unit
.File_Names
(Specification
).Needs_Pragma
then
931 Unit
.File_Names
(Specification
).Name
,
933 Unit
.File_Names
(Specification
).Index
);
936 if Unit
.File_Names
(Body_Part
).Needs_Pragma
then
938 Unit
.File_Names
(Body_Part
).Name
,
940 Unit
.File_Names
(Body_Part
).Index
);
943 Current_Unit
:= Current_Unit
+ 1;
947 -- If there are no non standard naming scheme, issue the GNAT
948 -- standard naming scheme. This will tell the compiler that
949 -- a project file is used and will forbid any pragma SFN.
951 if File
= Invalid_FD
then
954 Put_Line
(File
, "pragma Source_File_Name_Project");
955 Put_Line
(File
, " (Spec_File_Name => ""*.ads"",");
956 Put_Line
(File
, " Dot_Replacement => ""-"",");
957 Put_Line
(File
, " Casing => lowercase);");
959 Put_Line
(File
, "pragma Source_File_Name_Project");
960 Put_Line
(File
, " (Body_File_Name => ""*.adb"",");
961 Put_Line
(File
, " Dot_Replacement => ""-"",");
962 Put_Line
(File
, " Casing => lowercase);");
965 -- Close the temporary file
967 GNAT
.OS_Lib
.Close
(File
, Status
);
970 Prj
.Com
.Fail
("disk full");
973 if Opt
.Verbose_Mode
then
974 Write_Str
("Closing configuration file """);
975 Write_Str
(Get_Name_String
(File_Name
));
979 In_Tree
.Projects
.Table
(For_Project
).Config_File_Name
:=
981 In_Tree
.Projects
.Table
(For_Project
).Config_File_Temp
:=
984 In_Tree
.Projects
.Table
(For_Project
).Config_Checked
:=
987 end Create_Config_Pragmas_File
;
989 -------------------------
990 -- Create_Mapping_File --
991 -------------------------
993 procedure Create_Mapping_File
994 (Project
: Project_Id
;
995 In_Tree
: Project_Tree_Ref
;
998 File
: File_Descriptor
:= Invalid_FD
;
999 The_Unit_Data
: Unit_Data
;
1000 Data
: File_Name_Data
;
1003 -- For call to Close
1005 Present
: Project_Flags
1006 (No_Project
.. Project_Table
.Last
(In_Tree
.Projects
)) :=
1008 -- For each project in the closure of Project, the corresponding flag
1009 -- will be set to True;
1011 procedure Put_Name_Buffer
;
1012 -- Put the line contained in the Name_Buffer in the mapping file
1014 procedure Put_Data
(Spec
: Boolean);
1015 -- Put the mapping of the spec or body contained in Data in the file
1018 procedure Recursive_Flag
(Prj
: Project_Id
);
1019 -- Set the flags corresponding to Prj, the projects it imports
1020 -- (directly or indirectly) or extends to True. Call itself recursively.
1026 procedure Put_Name_Buffer
is
1030 Name_Len
:= Name_Len
+ 1;
1031 Name_Buffer
(Name_Len
) := ASCII
.LF
;
1032 Last
:= Write
(File
, Name_Buffer
(1)'Address, Name_Len
);
1034 if Last
/= Name_Len
then
1035 Prj
.Com
.Fail
("Disk full");
1037 end Put_Name_Buffer
;
1043 procedure Put_Data
(Spec
: Boolean) is
1045 -- Line with the unit name
1047 Get_Name_String
(The_Unit_Data
.Name
);
1048 Name_Len
:= Name_Len
+ 1;
1049 Name_Buffer
(Name_Len
) := '%';
1050 Name_Len
:= Name_Len
+ 1;
1053 Name_Buffer
(Name_Len
) := 's';
1055 Name_Buffer
(Name_Len
) := 'b';
1060 -- Line with the file name
1062 Get_Name_String
(Data
.Name
);
1065 -- Line with the path name
1067 Get_Name_String
(Data
.Path
);
1072 --------------------
1073 -- Recursive_Flag --
1074 --------------------
1076 procedure Recursive_Flag
(Prj
: Project_Id
) is
1077 Imported
: Project_List
;
1081 -- Nothing to do for non existent project or project that has
1082 -- already been flagged.
1084 if Prj
= No_Project
or else Present
(Prj
) then
1088 -- Flag the current project
1090 Present
(Prj
) := True;
1092 In_Tree
.Projects
.Table
(Prj
).Imported_Projects
;
1094 -- Call itself for each project directly imported
1096 while Imported
/= Empty_Project_List
loop
1098 In_Tree
.Project_Lists
.Table
(Imported
).Project
;
1100 In_Tree
.Project_Lists
.Table
(Imported
).Next
;
1101 Recursive_Flag
(Proj
);
1104 -- Call itself for an eventual project being extended
1106 Recursive_Flag
(In_Tree
.Projects
.Table
(Prj
).Extends
);
1109 -- Start of processing for Create_Mapping_File
1112 -- Flag the necessary projects
1114 Recursive_Flag
(Project
);
1116 -- Create the temporary file
1118 Tempdir
.Create_Temp_File
(File
, Name
=> Name
);
1120 if File
= Invalid_FD
then
1121 Prj
.Com
.Fail
("unable to create temporary mapping file");
1123 elsif Opt
.Verbose_Mode
then
1124 Write_Str
("Creating temp mapping file """);
1125 Write_Str
(Get_Name_String
(Name
));
1129 if Fill_Mapping_File
then
1131 -- For all units in table Units
1133 for Unit
in 1 .. Unit_Table
.Last
(In_Tree
.Units
) loop
1134 The_Unit_Data
:= In_Tree
.Units
.Table
(Unit
);
1136 -- If the unit has a valid name
1138 if The_Unit_Data
.Name
/= No_Name
then
1139 Data
:= The_Unit_Data
.File_Names
(Specification
);
1141 -- If there is a spec, put it mapping in the file if it is
1142 -- from a project in the closure of Project.
1144 if Data
.Name
/= No_Name
and then Present
(Data
.Project
) then
1145 Put_Data
(Spec
=> True);
1148 Data
:= The_Unit_Data
.File_Names
(Body_Part
);
1150 -- If there is a body (or subunit) put its mapping in the file
1151 -- if it is from a project in the closure of Project.
1153 if Data
.Name
/= No_Name
and then Present
(Data
.Project
) then
1154 Put_Data
(Spec
=> False);
1161 GNAT
.OS_Lib
.Close
(File
, Status
);
1164 Prj
.Com
.Fail
("disk full");
1166 end Create_Mapping_File
;
1168 --------------------------
1169 -- Create_New_Path_File --
1170 --------------------------
1172 procedure Create_New_Path_File
1173 (In_Tree
: Project_Tree_Ref
;
1174 Path_FD
: out File_Descriptor
;
1175 Path_Name
: out Name_Id
)
1178 Tempdir
.Create_Temp_File
(Path_FD
, Path_Name
);
1180 if Path_Name
/= No_Name
then
1182 -- Record the name, so that the temp path file will be deleted
1183 -- at the end of the program.
1185 Path_File_Table
.Increment_Last
(In_Tree
.Private_Part
.Path_Files
);
1186 In_Tree
.Private_Part
.Path_Files
.Table
1187 (Path_File_Table
.Last
(In_Tree
.Private_Part
.Path_Files
)) :=
1190 end Create_New_Path_File
;
1192 ---------------------------
1193 -- Delete_All_Path_Files --
1194 ---------------------------
1196 procedure Delete_All_Path_Files
(In_Tree
: Project_Tree_Ref
) is
1197 Disregard
: Boolean := True;
1200 for Index
in Path_File_Table
.First
..
1201 Path_File_Table
.Last
(In_Tree
.Private_Part
.Path_Files
)
1203 if In_Tree
.Private_Part
.Path_Files
.Table
(Index
) /= No_Name
then
1206 (In_Tree
.Private_Part
.Path_Files
.Table
(Index
)),
1211 -- If any of the environment variables ADA_PRJ_INCLUDE_FILE or
1212 -- ADA_PRJ_OBJECTS_FILE has been set, then reset their value to
1213 -- the empty string. On VMS, this has the effect of deassigning
1214 -- the logical names.
1216 if Ada_Prj_Include_File_Set
then
1217 Setenv
(Project_Include_Path_File
, "");
1218 Ada_Prj_Include_File_Set
:= False;
1221 if Ada_Prj_Objects_File_Set
then
1222 Setenv
(Project_Objects_Path_File
, "");
1223 Ada_Prj_Objects_File_Set
:= False;
1225 end Delete_All_Path_Files
;
1227 ------------------------------------
1228 -- File_Name_Of_Library_Unit_Body --
1229 ------------------------------------
1231 function File_Name_Of_Library_Unit_Body
1233 Project
: Project_Id
;
1234 In_Tree
: Project_Tree_Ref
;
1235 Main_Project_Only
: Boolean := True;
1236 Full_Path
: Boolean := False) return String
1238 The_Project
: Project_Id
:= Project
;
1239 Data
: Project_Data
:=
1240 In_Tree
.Projects
.Table
(Project
);
1241 Original_Name
: String := Name
;
1243 Extended_Spec_Name
: String :=
1244 Name
& Namet
.Get_Name_String
1245 (Data
.Naming
.Ada_Spec_Suffix
);
1246 Extended_Body_Name
: String :=
1247 Name
& Namet
.Get_Name_String
1248 (Data
.Naming
.Ada_Body_Suffix
);
1252 The_Original_Name
: Name_Id
;
1253 The_Spec_Name
: Name_Id
;
1254 The_Body_Name
: Name_Id
;
1257 Canonical_Case_File_Name
(Original_Name
);
1258 Name_Len
:= Original_Name
'Length;
1259 Name_Buffer
(1 .. Name_Len
) := Original_Name
;
1260 The_Original_Name
:= Name_Find
;
1262 Canonical_Case_File_Name
(Extended_Spec_Name
);
1263 Name_Len
:= Extended_Spec_Name
'Length;
1264 Name_Buffer
(1 .. Name_Len
) := Extended_Spec_Name
;
1265 The_Spec_Name
:= Name_Find
;
1267 Canonical_Case_File_Name
(Extended_Body_Name
);
1268 Name_Len
:= Extended_Body_Name
'Length;
1269 Name_Buffer
(1 .. Name_Len
) := Extended_Body_Name
;
1270 The_Body_Name
:= Name_Find
;
1272 if Current_Verbosity
= High
then
1273 Write_Str
("Looking for file name of """);
1277 Write_Str
(" Extended Spec Name = """);
1278 Write_Str
(Extended_Spec_Name
);
1281 Write_Str
(" Extended Body Name = """);
1282 Write_Str
(Extended_Body_Name
);
1287 -- For extending project, search in the extended project
1288 -- if the source is not found. For non extending projects,
1289 -- this loop will be run only once.
1292 -- Loop through units
1293 -- Should have comment explaining reverse ???
1295 for Current
in reverse Unit_Table
.First
..
1296 Unit_Table
.Last
(In_Tree
.Units
)
1298 Unit
:= In_Tree
.Units
.Table
(Current
);
1302 if not Main_Project_Only
1303 or else Unit
.File_Names
(Body_Part
).Project
= The_Project
1306 Current_Name
: constant Name_Id
:=
1307 Unit
.File_Names
(Body_Part
).Name
;
1310 -- Case of a body present
1312 if Current_Name
/= No_Name
then
1313 if Current_Verbosity
= High
then
1314 Write_Str
(" Comparing with """);
1315 Write_Str
(Get_Name_String
(Current_Name
));
1320 -- If it has the name of the original name,
1321 -- return the original name
1323 if Unit
.Name
= The_Original_Name
1324 or else Current_Name
= The_Original_Name
1326 if Current_Verbosity
= High
then
1331 return Get_Name_String
1332 (Unit
.File_Names
(Body_Part
).Path
);
1335 return Get_Name_String
(Current_Name
);
1338 -- If it has the name of the extended body name,
1339 -- return the extended body name
1341 elsif Current_Name
= The_Body_Name
then
1342 if Current_Verbosity
= High
then
1347 return Get_Name_String
1348 (Unit
.File_Names
(Body_Part
).Path
);
1351 return Extended_Body_Name
;
1355 if Current_Verbosity
= High
then
1356 Write_Line
(" not good");
1365 if not Main_Project_Only
1366 or else Unit
.File_Names
(Specification
).Project
= The_Project
1369 Current_Name
: constant Name_Id
:=
1370 Unit
.File_Names
(Specification
).Name
;
1373 -- Case of spec present
1375 if Current_Name
/= No_Name
then
1376 if Current_Verbosity
= High
then
1377 Write_Str
(" Comparing with """);
1378 Write_Str
(Get_Name_String
(Current_Name
));
1383 -- If name same as original name, return original name
1385 if Unit
.Name
= The_Original_Name
1386 or else Current_Name
= The_Original_Name
1388 if Current_Verbosity
= High
then
1393 return Get_Name_String
1394 (Unit
.File_Names
(Specification
).Path
);
1396 return Get_Name_String
(Current_Name
);
1399 -- If it has the same name as the extended spec name,
1400 -- return the extended spec name.
1402 elsif Current_Name
= The_Spec_Name
then
1403 if Current_Verbosity
= High
then
1408 return Get_Name_String
1409 (Unit
.File_Names
(Specification
).Path
);
1411 return Extended_Spec_Name
;
1415 if Current_Verbosity
= High
then
1416 Write_Line
(" not good");
1424 -- If we are not in an extending project, give up
1426 exit when (not Main_Project_Only
) or else Data
.Extends
= No_Project
;
1428 -- Otherwise, look in the project we are extending
1430 The_Project
:= Data
.Extends
;
1431 Data
:= In_Tree
.Projects
.Table
(The_Project
);
1434 -- We don't know this file name, return an empty string
1437 end File_Name_Of_Library_Unit_Body
;
1439 -------------------------
1440 -- For_All_Object_Dirs --
1441 -------------------------
1443 procedure For_All_Object_Dirs
1444 (Project
: Project_Id
;
1445 In_Tree
: Project_Tree_Ref
)
1447 Seen
: Project_List
:= Empty_Project_List
;
1449 procedure Add
(Project
: Project_Id
);
1450 -- Process a project. Remember the processes visited to avoid
1451 -- processing a project twice. Recursively process an eventual
1452 -- extended project, and all imported projects.
1458 procedure Add
(Project
: Project_Id
) is
1459 Data
: constant Project_Data
:=
1460 In_Tree
.Projects
.Table
(Project
);
1461 List
: Project_List
:= Data
.Imported_Projects
;
1464 -- If the list of visited project is empty, then
1465 -- for sure we never visited this project.
1467 if Seen
= Empty_Project_List
then
1468 Project_List_Table
.Increment_Last
1469 (In_Tree
.Project_Lists
);
1471 Project_List_Table
.Last
(In_Tree
.Project_Lists
);
1472 In_Tree
.Project_Lists
.Table
(Seen
) :=
1473 (Project
=> Project
, Next
=> Empty_Project_List
);
1476 -- Check if the project is in the list
1479 Current
: Project_List
:= Seen
;
1483 -- If it is, then there is nothing else to do
1485 if In_Tree
.Project_Lists
.Table
1486 (Current
).Project
= Project
1492 In_Tree
.Project_Lists
.Table
(Current
).Next
=
1495 In_Tree
.Project_Lists
.Table
(Current
).Next
;
1498 -- This project has never been visited, add it
1501 Project_List_Table
.Increment_Last
1502 (In_Tree
.Project_Lists
);
1503 In_Tree
.Project_Lists
.Table
(Current
).Next
:=
1504 Project_List_Table
.Last
(In_Tree
.Project_Lists
);
1505 In_Tree
.Project_Lists
.Table
1506 (Project_List_Table
.Last
1507 (In_Tree
.Project_Lists
)) :=
1508 (Project
=> Project
, Next
=> Empty_Project_List
);
1512 -- If there is an object directory, call Action
1515 if Data
.Object_Directory
/= No_Name
then
1516 Get_Name_String
(Data
.Object_Directory
);
1517 Action
(Name_Buffer
(1 .. Name_Len
));
1520 -- If we are extending a project, visit it
1522 if Data
.Extends
/= No_Project
then
1526 -- And visit all imported projects
1528 while List
/= Empty_Project_List
loop
1529 Add
(In_Tree
.Project_Lists
.Table
(List
).Project
);
1530 List
:= In_Tree
.Project_Lists
.Table
(List
).Next
;
1534 -- Start of processing for For_All_Object_Dirs
1537 -- Visit this project, and its imported projects,
1541 end For_All_Object_Dirs
;
1543 -------------------------
1544 -- For_All_Source_Dirs --
1545 -------------------------
1547 procedure For_All_Source_Dirs
1548 (Project
: Project_Id
;
1549 In_Tree
: Project_Tree_Ref
)
1551 Seen
: Project_List
:= Empty_Project_List
;
1553 procedure Add
(Project
: Project_Id
);
1554 -- Process a project. Remember the processes visited to avoid
1555 -- processing a project twice. Recursively process an eventual
1556 -- extended project, and all imported projects.
1562 procedure Add
(Project
: Project_Id
) is
1563 Data
: constant Project_Data
:=
1564 In_Tree
.Projects
.Table
(Project
);
1565 List
: Project_List
:= Data
.Imported_Projects
;
1568 -- If the list of visited project is empty, then
1569 -- for sure we never visited this project.
1571 if Seen
= Empty_Project_List
then
1572 Project_List_Table
.Increment_Last
1573 (In_Tree
.Project_Lists
);
1574 Seen
:= Project_List_Table
.Last
1575 (In_Tree
.Project_Lists
);
1576 In_Tree
.Project_Lists
.Table
(Seen
) :=
1577 (Project
=> Project
, Next
=> Empty_Project_List
);
1580 -- Check if the project is in the list
1583 Current
: Project_List
:= Seen
;
1587 -- If it is, then there is nothing else to do
1589 if In_Tree
.Project_Lists
.Table
1590 (Current
).Project
= Project
1596 In_Tree
.Project_Lists
.Table
(Current
).Next
=
1599 In_Tree
.Project_Lists
.Table
(Current
).Next
;
1602 -- This project has never been visited, add it
1605 Project_List_Table
.Increment_Last
1606 (In_Tree
.Project_Lists
);
1607 In_Tree
.Project_Lists
.Table
(Current
).Next
:=
1608 Project_List_Table
.Last
(In_Tree
.Project_Lists
);
1609 In_Tree
.Project_Lists
.Table
1610 (Project_List_Table
.Last
1611 (In_Tree
.Project_Lists
)) :=
1612 (Project
=> Project
, Next
=> Empty_Project_List
);
1617 Current
: String_List_Id
:= Data
.Source_Dirs
;
1618 The_String
: String_Element
;
1621 -- If there are Ada sources, call action with the name of every
1622 -- source directory.
1625 In_Tree
.Projects
.Table
(Project
).Ada_Sources_Present
1627 while Current
/= Nil_String
loop
1629 In_Tree
.String_Elements
.Table
(Current
);
1630 Action
(Get_Name_String
(The_String
.Value
));
1631 Current
:= The_String
.Next
;
1636 -- If we are extending a project, visit it
1638 if Data
.Extends
/= No_Project
then
1642 -- And visit all imported projects
1644 while List
/= Empty_Project_List
loop
1645 Add
(In_Tree
.Project_Lists
.Table
(List
).Project
);
1646 List
:= In_Tree
.Project_Lists
.Table
(List
).Next
;
1650 -- Start of processing for For_All_Source_Dirs
1653 -- Visit this project, and its imported projects recursively
1656 end For_All_Source_Dirs
;
1662 procedure Get_Reference
1663 (Source_File_Name
: String;
1664 In_Tree
: Project_Tree_Ref
;
1665 Project
: out Project_Id
;
1669 -- Body below could use some comments ???
1671 if Current_Verbosity
> Default
then
1672 Write_Str
("Getting Reference_Of (""");
1673 Write_Str
(Source_File_Name
);
1674 Write_Str
(""") ... ");
1678 Original_Name
: String := Source_File_Name
;
1682 Canonical_Case_File_Name
(Original_Name
);
1684 for Id
in Unit_Table
.First
..
1685 Unit_Table
.Last
(In_Tree
.Units
)
1687 Unit
:= In_Tree
.Units
.Table
(Id
);
1689 if (Unit
.File_Names
(Specification
).Name
/= No_Name
1691 Namet
.Get_Name_String
1692 (Unit
.File_Names
(Specification
).Name
) = Original_Name
)
1693 or else (Unit
.File_Names
(Specification
).Path
/= No_Name
1695 Namet
.Get_Name_String
1696 (Unit
.File_Names
(Specification
).Path
) =
1699 Project
:= Ultimate_Extension_Of
1700 (Project
=> Unit
.File_Names
(Specification
).Project
,
1701 In_Tree
=> In_Tree
);
1702 Path
:= Unit
.File_Names
(Specification
).Display_Path
;
1704 if Current_Verbosity
> Default
then
1705 Write_Str
("Done: Specification.");
1711 elsif (Unit
.File_Names
(Body_Part
).Name
/= No_Name
1713 Namet
.Get_Name_String
1714 (Unit
.File_Names
(Body_Part
).Name
) = Original_Name
)
1715 or else (Unit
.File_Names
(Body_Part
).Path
/= No_Name
1716 and then Namet
.Get_Name_String
1717 (Unit
.File_Names
(Body_Part
).Path
) =
1720 Project
:= Ultimate_Extension_Of
1721 (Project
=> Unit
.File_Names
(Body_Part
).Project
,
1722 In_Tree
=> In_Tree
);
1723 Path
:= Unit
.File_Names
(Body_Part
).Display_Path
;
1725 if Current_Verbosity
> Default
then
1726 Write_Str
("Done: Body.");
1735 Project
:= No_Project
;
1738 if Current_Verbosity
> Default
then
1739 Write_Str
("Cannot be found.");
1748 procedure Initialize
is
1750 Fill_Mapping_File
:= True;
1753 ------------------------------------
1754 -- Path_Name_Of_Library_Unit_Body --
1755 ------------------------------------
1757 -- Could use some comments in the body here ???
1759 function Path_Name_Of_Library_Unit_Body
1761 Project
: Project_Id
;
1762 In_Tree
: Project_Tree_Ref
) return String
1764 Data
: constant Project_Data
:=
1765 In_Tree
.Projects
.Table
(Project
);
1766 Original_Name
: String := Name
;
1768 Extended_Spec_Name
: String :=
1769 Name
& Namet
.Get_Name_String
1770 (Data
.Naming
.Ada_Spec_Suffix
);
1771 Extended_Body_Name
: String :=
1772 Name
& Namet
.Get_Name_String
1773 (Data
.Naming
.Ada_Body_Suffix
);
1775 First
: Unit_Id
:= Unit_Table
.First
;
1780 Canonical_Case_File_Name
(Original_Name
);
1781 Canonical_Case_File_Name
(Extended_Spec_Name
);
1782 Canonical_Case_File_Name
(Extended_Body_Name
);
1784 if Current_Verbosity
= High
then
1785 Write_Str
("Looking for path name of """);
1789 Write_Str
(" Extended Spec Name = """);
1790 Write_Str
(Extended_Spec_Name
);
1793 Write_Str
(" Extended Body Name = """);
1794 Write_Str
(Extended_Body_Name
);
1799 while First
<= Unit_Table
.Last
(In_Tree
.Units
)
1800 and then In_Tree
.Units
.Table
1801 (First
).File_Names
(Body_Part
).Project
/= Project
1807 while Current
<= Unit_Table
.Last
(In_Tree
.Units
) loop
1808 Unit
:= In_Tree
.Units
.Table
(Current
);
1810 if Unit
.File_Names
(Body_Part
).Project
= Project
1811 and then Unit
.File_Names
(Body_Part
).Name
/= No_Name
1814 Current_Name
: constant String :=
1815 Namet
.Get_Name_String
(Unit
.File_Names
(Body_Part
).Name
);
1817 if Current_Verbosity
= High
then
1818 Write_Str
(" Comparing with """);
1819 Write_Str
(Current_Name
);
1824 if Current_Name
= Original_Name
then
1825 if Current_Verbosity
= High
then
1829 return Body_Path_Name_Of
(Current
, In_Tree
);
1831 elsif Current_Name
= Extended_Body_Name
then
1832 if Current_Verbosity
= High
then
1836 return Body_Path_Name_Of
(Current
, In_Tree
);
1839 if Current_Verbosity
= High
then
1840 Write_Line
(" not good");
1845 elsif Unit
.File_Names
(Specification
).Name
/= No_Name
then
1847 Current_Name
: constant String :=
1848 Namet
.Get_Name_String
1849 (Unit
.File_Names
(Specification
).Name
);
1852 if Current_Verbosity
= High
then
1853 Write_Str
(" Comparing with """);
1854 Write_Str
(Current_Name
);
1859 if Current_Name
= Original_Name
then
1860 if Current_Verbosity
= High
then
1864 return Spec_Path_Name_Of
(Current
, In_Tree
);
1866 elsif Current_Name
= Extended_Spec_Name
then
1867 if Current_Verbosity
= High
then
1871 return Spec_Path_Name_Of
(Current
, In_Tree
);
1874 if Current_Verbosity
= High
then
1875 Write_Line
(" not good");
1880 Current
:= Current
+ 1;
1884 end Path_Name_Of_Library_Unit_Body
;
1890 -- Could use some comments in this body ???
1892 procedure Print_Sources
(In_Tree
: Project_Tree_Ref
) is
1896 Write_Line
("List of Sources:");
1898 for Id
in Unit_Table
.First
..
1899 Unit_Table
.Last
(In_Tree
.Units
)
1901 Unit
:= In_Tree
.Units
.Table
(Id
);
1903 Write_Line
(Namet
.Get_Name_String
(Unit
.Name
));
1905 if Unit
.File_Names
(Specification
).Name
/= No_Name
then
1906 if Unit
.File_Names
(Specification
).Project
= No_Project
then
1907 Write_Line
(" No project");
1910 Write_Str
(" Project: ");
1912 (In_Tree
.Projects
.Table
1913 (Unit
.File_Names
(Specification
).Project
).Path_Name
);
1914 Write_Line
(Name_Buffer
(1 .. Name_Len
));
1917 Write_Str
(" spec: ");
1919 (Namet
.Get_Name_String
1920 (Unit
.File_Names
(Specification
).Name
));
1923 if Unit
.File_Names
(Body_Part
).Name
/= No_Name
then
1924 if Unit
.File_Names
(Body_Part
).Project
= No_Project
then
1925 Write_Line
(" No project");
1928 Write_Str
(" Project: ");
1930 (In_Tree
.Projects
.Table
1931 (Unit
.File_Names
(Body_Part
).Project
).Path_Name
);
1932 Write_Line
(Name_Buffer
(1 .. Name_Len
));
1935 Write_Str
(" body: ");
1937 (Namet
.Get_Name_String
1938 (Unit
.File_Names
(Body_Part
).Name
));
1942 Write_Line
("end of List of Sources.");
1951 Main_Project
: Project_Id
;
1952 In_Tree
: Project_Tree_Ref
) return Project_Id
1954 Result
: Project_Id
:= No_Project
;
1956 Original_Name
: String := Name
;
1958 Data
: constant Project_Data
:=
1959 In_Tree
.Projects
.Table
(Main_Project
);
1961 Extended_Spec_Name
: String :=
1962 Name
& Namet
.Get_Name_String
1963 (Data
.Naming
.Ada_Spec_Suffix
);
1964 Extended_Body_Name
: String :=
1965 Name
& Namet
.Get_Name_String
1966 (Data
.Naming
.Ada_Body_Suffix
);
1970 Current_Name
: Name_Id
;
1972 The_Original_Name
: Name_Id
;
1973 The_Spec_Name
: Name_Id
;
1974 The_Body_Name
: Name_Id
;
1977 Canonical_Case_File_Name
(Original_Name
);
1978 Name_Len
:= Original_Name
'Length;
1979 Name_Buffer
(1 .. Name_Len
) := Original_Name
;
1980 The_Original_Name
:= Name_Find
;
1982 Canonical_Case_File_Name
(Extended_Spec_Name
);
1983 Name_Len
:= Extended_Spec_Name
'Length;
1984 Name_Buffer
(1 .. Name_Len
) := Extended_Spec_Name
;
1985 The_Spec_Name
:= Name_Find
;
1987 Canonical_Case_File_Name
(Extended_Body_Name
);
1988 Name_Len
:= Extended_Body_Name
'Length;
1989 Name_Buffer
(1 .. Name_Len
) := Extended_Body_Name
;
1990 The_Body_Name
:= Name_Find
;
1992 for Current
in reverse Unit_Table
.First
..
1993 Unit_Table
.Last
(In_Tree
.Units
)
1995 Unit
:= In_Tree
.Units
.Table
(Current
);
1999 Current_Name
:= Unit
.File_Names
(Body_Part
).Name
;
2001 -- Case of a body present
2003 if Current_Name
/= No_Name
then
2005 -- If it has the name of the original name or the body name,
2006 -- we have found the project.
2008 if Unit
.Name
= The_Original_Name
2009 or else Current_Name
= The_Original_Name
2010 or else Current_Name
= The_Body_Name
2012 Result
:= Unit
.File_Names
(Body_Part
).Project
;
2019 Current_Name
:= Unit
.File_Names
(Specification
).Name
;
2021 if Current_Name
/= No_Name
then
2023 -- If name same as the original name, or the spec name, we have
2024 -- found the project.
2026 if Unit
.Name
= The_Original_Name
2027 or else Current_Name
= The_Original_Name
2028 or else Current_Name
= The_Spec_Name
2030 Result
:= Unit
.File_Names
(Specification
).Project
;
2036 -- Get the ultimate extending project
2038 if Result
/= No_Project
then
2039 while In_Tree
.Projects
.Table
(Result
).Extended_By
/=
2042 Result
:= In_Tree
.Projects
.Table
(Result
).Extended_By
;
2053 procedure Set_Ada_Paths
2054 (Project
: Project_Id
;
2055 In_Tree
: Project_Tree_Ref
;
2056 Including_Libraries
: Boolean)
2058 Source_FD
: File_Descriptor
:= Invalid_FD
;
2059 Object_FD
: File_Descriptor
:= Invalid_FD
;
2061 Process_Source_Dirs
: Boolean := False;
2062 Process_Object_Dirs
: Boolean := False;
2065 -- For calls to Close
2069 procedure Add
(Proj
: Project_Id
);
2070 -- Add all the source/object directories of a project to the path only
2071 -- if this project has not been visited. Calls an internal procedure
2072 -- recursively for projects being extended, and imported projects.
2078 procedure Add
(Proj
: Project_Id
) is
2080 procedure Recursive_Add
(Project
: Project_Id
);
2081 -- Recursive procedure to add the source/object paths of extended/
2082 -- imported projects.
2088 procedure Recursive_Add
(Project
: Project_Id
) is
2090 -- If Seen is False, then the project has not yet been visited
2092 if not In_Tree
.Projects
.Table
(Project
).Seen
then
2093 In_Tree
.Projects
.Table
(Project
).Seen
:= True;
2096 Data
: constant Project_Data
:=
2097 In_Tree
.Projects
.Table
(Project
);
2098 List
: Project_List
:= Data
.Imported_Projects
;
2101 if Process_Source_Dirs
then
2103 -- Add to path all source directories of this project
2104 -- if there are Ada sources.
2106 if In_Tree
.Projects
.Table
2107 (Project
).Ada_Sources_Present
2109 Add_To_Source_Path
(Data
.Source_Dirs
, In_Tree
);
2113 if Process_Object_Dirs
then
2115 -- Add to path the object directory of this project
2116 -- except if we don't include library project and
2117 -- this is a library project.
2119 if (Data
.Library
and then Including_Libraries
)
2121 (Data
.Object_Directory
/= No_Name
2123 (not Including_Libraries
or else not Data
.Library
))
2125 -- For a library project, add the library ALI
2126 -- directory if there is no object directory or
2127 -- if the library ALI directory contains ALI files;
2128 -- otherwise add the object directory.
2130 if Data
.Library
then
2131 if Data
.Object_Directory
= No_Name
2132 or else Contains_ALI_Files
(Data
.Library_ALI_Dir
)
2135 (Data
.Library_ALI_Dir
, In_Tree
);
2138 (Data
.Object_Directory
, In_Tree
);
2141 -- For a non-library project, add the object
2142 -- directory, if it is not a virtual project, and
2143 -- if there are Ada sources or if the project is an
2144 -- extending project. if There Are No Ada sources,
2145 -- adding the object directory could disrupt
2146 -- the order of the object dirs in the path.
2148 elsif not Data
.Virtual
2149 and then (In_Tree
.Projects
.Table
2150 (Project
).Ada_Sources_Present
2152 (Data
.Extends
/= No_Project
2154 Data
.Object_Directory
/= No_Name
))
2157 (Data
.Object_Directory
, In_Tree
);
2162 -- Call Add to the project being extended, if any
2164 if Data
.Extends
/= No_Project
then
2165 Recursive_Add
(Data
.Extends
);
2168 -- Call Add for each imported project, if any
2170 while List
/= Empty_Project_List
loop
2172 (In_Tree
.Project_Lists
.Table
2175 In_Tree
.Project_Lists
.Table
(List
).Next
;
2182 Source_Path_Table
.Set_Last
(In_Tree
.Private_Part
.Source_Paths
, 0);
2183 Object_Path_Table
.Set_Last
(In_Tree
.Private_Part
.Object_Paths
, 0);
2185 for Index
in Project_Table
.First
..
2186 Project_Table
.Last
(In_Tree
.Projects
)
2188 In_Tree
.Projects
.Table
(Index
).Seen
:= False;
2191 Recursive_Add
(Proj
);
2194 -- Start of processing for Set_Ada_Paths
2197 -- If it is the first time we call this procedure for
2198 -- this project, compute the source path and/or the object path.
2200 if In_Tree
.Projects
.Table
(Project
).Include_Path_File
=
2203 Process_Source_Dirs
:= True;
2204 Create_New_Path_File
2205 (In_Tree
, Source_FD
,
2206 In_Tree
.Projects
.Table
(Project
).Include_Path_File
);
2209 -- For the object path, we make a distinction depending on
2210 -- Including_Libraries.
2212 if Including_Libraries
then
2213 if In_Tree
.Projects
.Table
2214 (Project
).Objects_Path_File_With_Libs
= No_Name
2216 Process_Object_Dirs
:= True;
2217 Create_New_Path_File
2218 (In_Tree
, Object_FD
, In_Tree
.Projects
.Table
(Project
).
2219 Objects_Path_File_With_Libs
);
2223 if In_Tree
.Projects
.Table
2224 (Project
).Objects_Path_File_Without_Libs
= No_Name
2226 Process_Object_Dirs
:= True;
2227 Create_New_Path_File
2228 (In_Tree
, Object_FD
, In_Tree
.Projects
.Table
(Project
).
2229 Objects_Path_File_Without_Libs
);
2233 -- If there is something to do, set Seen to False for all projects,
2234 -- then call the recursive procedure Add for Project.
2236 if Process_Source_Dirs
or Process_Object_Dirs
then
2240 -- Write and close any file that has been created
2242 if Source_FD
/= Invalid_FD
then
2243 for Index
in Source_Path_Table
.First
..
2244 Source_Path_Table
.Last
2245 (In_Tree
.Private_Part
.Source_Paths
)
2247 Get_Name_String
(In_Tree
.Private_Part
.Source_Paths
.Table
(Index
));
2248 Name_Len
:= Name_Len
+ 1;
2249 Name_Buffer
(Name_Len
) := ASCII
.LF
;
2250 Len
:= Write
(Source_FD
, Name_Buffer
(1)'Address, Name_Len
);
2252 if Len
/= Name_Len
then
2253 Prj
.Com
.Fail
("disk full");
2257 Close
(Source_FD
, Status
);
2260 Prj
.Com
.Fail
("disk full");
2264 if Object_FD
/= Invalid_FD
then
2265 for Index
in Object_Path_Table
.First
..
2266 Object_Path_Table
.Last
2267 (In_Tree
.Private_Part
.Object_Paths
)
2269 Get_Name_String
(In_Tree
.Private_Part
.Object_Paths
.Table
(Index
));
2270 Name_Len
:= Name_Len
+ 1;
2271 Name_Buffer
(Name_Len
) := ASCII
.LF
;
2272 Len
:= Write
(Object_FD
, Name_Buffer
(1)'Address, Name_Len
);
2274 if Len
/= Name_Len
then
2275 Prj
.Com
.Fail
("disk full");
2279 Close
(Object_FD
, Status
);
2282 Prj
.Com
.Fail
("disk full");
2286 -- Set the env vars, if they need to be changed, and set the
2287 -- corresponding flags.
2289 if Current_Source_Path_File
/=
2290 In_Tree
.Projects
.Table
(Project
).Include_Path_File
2292 Current_Source_Path_File
:=
2293 In_Tree
.Projects
.Table
(Project
).Include_Path_File
;
2295 (Project_Include_Path_File
,
2296 Get_Name_String
(Current_Source_Path_File
));
2297 Ada_Prj_Include_File_Set
:= True;
2300 if Including_Libraries
then
2301 if Current_Object_Path_File
2302 /= In_Tree
.Projects
.Table
2303 (Project
).Objects_Path_File_With_Libs
2305 Current_Object_Path_File
:=
2306 In_Tree
.Projects
.Table
2307 (Project
).Objects_Path_File_With_Libs
;
2309 (Project_Objects_Path_File
,
2310 Get_Name_String
(Current_Object_Path_File
));
2311 Ada_Prj_Objects_File_Set
:= True;
2315 if Current_Object_Path_File
/=
2316 In_Tree
.Projects
.Table
2317 (Project
).Objects_Path_File_Without_Libs
2319 Current_Object_Path_File
:=
2320 In_Tree
.Projects
.Table
2321 (Project
).Objects_Path_File_Without_Libs
;
2323 (Project_Objects_Path_File
,
2324 Get_Name_String
(Current_Object_Path_File
));
2325 Ada_Prj_Objects_File_Set
:= True;
2330 ---------------------------------------------
2331 -- Set_Mapping_File_Initial_State_To_Empty --
2332 ---------------------------------------------
2334 procedure Set_Mapping_File_Initial_State_To_Empty
is
2336 Fill_Mapping_File
:= False;
2337 end Set_Mapping_File_Initial_State_To_Empty
;
2339 -----------------------
2340 -- Set_Path_File_Var --
2341 -----------------------
2343 procedure Set_Path_File_Var
(Name
: String; Value
: String) is
2344 Host_Spec
: String_Access
:= To_Host_File_Spec
(Value
);
2347 if Host_Spec
= null then
2349 ("could not convert file name """, Value
, """ to host spec");
2351 Setenv
(Name
, Host_Spec
.all);
2354 end Set_Path_File_Var
;
2356 -----------------------
2357 -- Spec_Path_Name_Of --
2358 -----------------------
2360 function Spec_Path_Name_Of
2361 (Unit
: Unit_Id
; In_Tree
: Project_Tree_Ref
) return String
2363 Data
: Unit_Data
:= In_Tree
.Units
.Table
(Unit
);
2366 if Data
.File_Names
(Specification
).Path
= No_Name
then
2368 Current_Source
: String_List_Id
:=
2369 In_Tree
.Projects
.Table
2370 (Data
.File_Names
(Specification
).Project
).Sources
;
2371 Path
: GNAT
.OS_Lib
.String_Access
;
2374 Data
.File_Names
(Specification
).Path
:=
2375 Data
.File_Names
(Specification
).Name
;
2377 while Current_Source
/= Nil_String
loop
2378 Path
:= Locate_Regular_File
2379 (Namet
.Get_Name_String
2380 (Data
.File_Names
(Specification
).Name
),
2381 Namet
.Get_Name_String
2382 (In_Tree
.String_Elements
.Table
2383 (Current_Source
).Value
));
2385 if Path
/= null then
2386 Name_Len
:= Path
'Length;
2387 Name_Buffer
(1 .. Name_Len
) := Path
.all;
2388 Data
.File_Names
(Specification
).Path
:= Name_Enter
;
2392 In_Tree
.String_Elements
.Table
2393 (Current_Source
).Next
;
2397 In_Tree
.Units
.Table
(Unit
) := Data
;
2401 return Namet
.Get_Name_String
(Data
.File_Names
(Specification
).Path
);
2402 end Spec_Path_Name_Of
;
2404 ---------------------------
2405 -- Ultimate_Extension_Of --
2406 ---------------------------
2408 function Ultimate_Extension_Of
2409 (Project
: Project_Id
;
2410 In_Tree
: Project_Tree_Ref
) return Project_Id
2412 Result
: Project_Id
:= Project
;
2415 while In_Tree
.Projects
.Table
(Result
).Extended_By
/=
2418 Result
:= In_Tree
.Projects
.Table
(Result
).Extended_By
;
2422 end Ultimate_Extension_Of
;