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 Namet; use Namet;
29 with Osint; use Osint;
30 with Output; use Output;
31 with Prj.Com; use Prj.Com;
35 with GNAT.OS_Lib; use GNAT.OS_Lib;
37 package body Prj.Env is
39 type Naming_Id is new Nat;
41 Current_Source_Path_File : Name_Id := No_Name;
42 -- Current value of project source path file env var.
43 -- Used to avoid setting the env var to the same value.
45 Current_Object_Path_File : Name_Id := No_Name;
46 -- Current value of project object path file env var.
47 -- Used to avoid setting the env var to the same value.
49 Ada_Path_Buffer : String_Access := new String (1 .. 1024);
50 -- A buffer where values for ADA_INCLUDE_PATH
51 -- and ADA_OBJECTS_PATH are stored.
53 Ada_Path_Length : Natural := 0;
54 -- Index of the last valid character in Ada_Path_Buffer.
56 Ada_Prj_Include_File_Set : Boolean := False;
57 Ada_Prj_Objects_File_Set : Boolean := False;
58 -- These flags are set to True when the corresponding environment variables
59 -- are set and are used to give these environment variables an empty string
60 -- value at the end of the program. This has no practical effect on most
61 -- platforms, except on VMS where the logical names are deassigned, thus
62 -- avoiding the pollution of the environment of the caller.
64 package Namings is new Table.Table
65 (Table_Component_Type => Naming_Data,
66 Table_Index_Type => Naming_Id,
69 Table_Increment => 100,
70 Table_Name => "Prj.Env.Namings");
72 Default_Naming : constant Naming_Id := Namings.First;
74 Fill_Mapping_File : Boolean := True;
76 package Path_Files is new Table.Table
77 (Table_Component_Type => Name_Id,
78 Table_Index_Type => Natural,
81 Table_Increment => 50,
82 Table_Name => "Prj.Env.Path_Files");
83 -- Table storing all the temp path file names.
84 -- Used by Delete_All_Path_Files.
86 type Project_Flags is array (Project_Id range <>) of Boolean;
87 -- A Boolean array type used in Create_Mapping_File to select the projects
88 -- in the closure of a specific project.
90 package Source_Paths is new Table.Table
91 (Table_Component_Type => Name_Id,
92 Table_Index_Type => Natural,
95 Table_Increment => 50,
96 Table_Name => "Prj.Env.Source_Paths");
97 -- A table to store the source dirs before creating the source path file
99 package Object_Paths is new Table.Table
100 (Table_Component_Type => Name_Id,
101 Table_Index_Type => Natural,
102 Table_Low_Bound => 1,
104 Table_Increment => 50,
105 Table_Name => "Prj.Env.Source_Paths");
106 -- A table to store the object dirs, before creating the object path file
108 -----------------------
109 -- Local Subprograms --
110 -----------------------
112 function Body_Path_Name_Of (Unit : Unit_Id) return String;
113 -- Returns the path name of the body of a unit.
114 -- Compute it first, if necessary.
116 function Spec_Path_Name_Of (Unit : Unit_Id) return String;
117 -- Returns the path name of the spec of a unit.
118 -- Compute it first, if necessary.
120 procedure Add_To_Path (Source_Dirs : String_List_Id);
121 -- Add to Ada_Path_Buffer all the source directories in string list
122 -- Source_Dirs, if any. Increment Ada_Path_Length.
124 procedure Add_To_Path (Dir : String);
125 -- If Dir is not already in the global variable Ada_Path_Buffer, add it.
126 -- Increment Ada_Path_Length.
127 -- If Ada_Path_Length /= 0, prepend a Path_Separator character to
130 procedure Add_To_Source_Path (Source_Dirs : String_List_Id);
131 -- Add to Ada_Path_B all the source directories in string list
132 -- Source_Dirs, if any. Increment Ada_Path_Length.
134 procedure Add_To_Object_Path (Object_Dir : Name_Id);
135 -- Add Object_Dir to object path table. Make sure it is not duplicate
136 -- and it is the last one in the current table.
138 procedure Create_New_Path_File
139 (Path_FD : out File_Descriptor;
140 Path_Name : out Name_Id);
141 -- Create a new temporary path file. Get the file name in Path_Name.
142 -- The name is normally obtained by increasing the number in
143 -- Temp_Path_File_Name by 1.
145 procedure Set_Path_File_Var (Name : String; Value : String);
146 -- Call Setenv, after calling To_Host_File_Spec
148 function Ultimate_Extension_Of (Project : in Project_Id) return Project_Id;
149 -- Return a project that is either Project or an extended ancestor of
150 -- Project that itself is not extended.
152 ----------------------
153 -- Ada_Include_Path --
154 ----------------------
156 function Ada_Include_Path (Project : Project_Id) return String_Access is
158 procedure Add (Project : Project_Id);
159 -- Add all the source directories of a project to the path only if
160 -- this project has not been visited. Calls itself recursively for
161 -- projects being extended, and imported projects. Adds the project
162 -- to the list Seen if this is the call to Add for this project.
168 procedure Add (Project : Project_Id) is
170 -- If Seen is empty, then the project cannot have been visited
172 if not Projects.Table (Project).Seen then
173 Projects.Table (Project).Seen := True;
176 Data : constant Project_Data := Projects.Table (Project);
177 List : Project_List := Data.Imported_Projects;
180 -- Add to path all source directories of this project
182 Add_To_Path (Data.Source_Dirs);
184 -- Call Add to the project being extended, if any
186 if Data.Extends /= No_Project then
190 -- Call Add for each imported project, if any
192 while List /= Empty_Project_List loop
193 Add (Project_Lists.Table (List).Project);
194 List := Project_Lists.Table (List).Next;
200 -- Start of processing for Ada_Include_Path
203 -- If it is the first time we call this function for
204 -- this project, compute the source path
206 if Projects.Table (Project).Ada_Include_Path = null then
207 Ada_Path_Length := 0;
209 for Index in 1 .. Projects.Last loop
210 Projects.Table (Index).Seen := False;
214 Projects.Table (Project).Ada_Include_Path :=
215 new String'(Ada_Path_Buffer (1 .. Ada_Path_Length));
218 return Projects.Table (Project).Ada_Include_Path;
219 end Ada_Include_Path;
221 ----------------------
222 -- Ada_Include_Path --
223 ----------------------
225 function Ada_Include_Path
226 (Project : Project_Id;
227 Recursive : Boolean) return String
231 return Ada_Include_Path (Project).all;
233 Ada_Path_Length := 0;
234 Add_To_Path (Projects.Table (Project).Source_Dirs);
235 return Ada_Path_Buffer (1 .. Ada_Path_Length);
237 end Ada_Include_Path;
239 ----------------------
240 -- Ada_Objects_Path --
241 ----------------------
243 function Ada_Objects_Path
244 (Project : Project_Id;
245 Including_Libraries : Boolean := True) return String_Access
247 procedure Add (Project : Project_Id);
248 -- Add all the object directories of a project to the path only if
249 -- this project has not been visited. Calls itself recursively for
250 -- projects being extended, and imported projects. Adds the project
251 -- to the list Seen if this is the first call to Add for this project.
257 procedure Add (Project : Project_Id) is
259 -- If this project has not been seen yet
261 if not Projects.Table (Project).Seen then
262 Projects.Table (Project).Seen := True;
265 Data : constant Project_Data := Projects.Table (Project);
266 List : Project_List := Data.Imported_Projects;
269 -- Add to path the object directory of this project
270 -- except if we don't include library project and
271 -- this is a library project.
273 if (Data.Library and then Including_Libraries)
275 (Data.Object_Directory /= No_Name
277 (not Including_Libraries or else not Data.Library))
279 -- For a library project, add the library directory
282 Add_To_Path (Get_Name_String (Data.Library_Dir));
285 -- For a non library project, add the object directory
287 Add_To_Path (Get_Name_String (Data.Object_Directory));
291 -- Call Add to the project being extended, if any
293 if Data.Extends /= No_Project then
297 -- Call Add for each imported project, if any
299 while List /= Empty_Project_List loop
300 Add (Project_Lists.Table (List).Project);
301 List := Project_Lists.Table (List).Next;
308 -- Start of processing for Ada_Objects_Path
311 -- If it is the first time we call this function for
312 -- this project, compute the objects path
314 if Projects.Table (Project).Ada_Objects_Path = null then
315 Ada_Path_Length := 0;
317 for Index in 1 .. Projects.Last loop
318 Projects.Table (Index).Seen := False;
322 Projects.Table (Project).Ada_Objects_Path :=
323 new String'(Ada_Path_Buffer (1 .. Ada_Path_Length));
326 return Projects.Table (Project).Ada_Objects_Path;
327 end Ada_Objects_Path;
329 ------------------------
330 -- Add_To_Object_Path --
331 ------------------------
333 procedure Add_To_Object_Path (Object_Dir : Name_Id) is
335 -- Check if the directory is already in the table
337 for Index in 1 .. Object_Paths.Last loop
339 -- If it is, remove it, and add it as the last one
341 if Object_Paths.Table (Index) = Object_Dir then
342 for Index2 in Index + 1 .. Object_Paths.Last loop
343 Object_Paths.Table (Index2 - 1) :=
344 Object_Paths.Table (Index2);
347 Object_Paths.Table (Object_Paths.Last) := Object_Dir;
352 -- The directory is not already in the table, add it
354 Object_Paths.Increment_Last;
355 Object_Paths.Table (Object_Paths.Last) := Object_Dir;
356 end Add_To_Object_Path;
362 procedure Add_To_Path (Source_Dirs : String_List_Id) is
363 Current : String_List_Id := Source_Dirs;
364 Source_Dir : String_Element;
366 while Current /= Nil_String loop
367 Source_Dir := String_Elements.Table (Current);
368 Add_To_Path (Get_Name_String (Source_Dir.Display_Value));
369 Current := Source_Dir.Next;
373 procedure Add_To_Path (Dir : String) is
375 New_Buffer : String_Access;
378 function Is_Present (Path : String; Dir : String) return Boolean;
379 -- Return True if Dir is part of Path
385 function Is_Present (Path : String; Dir : String) return Boolean is
386 Last : constant Integer := Path'Last - Dir'Length + 1;
389 for J in Path'First .. Last loop
391 -- Note: the order of the conditions below is important, since
392 -- it ensures a minimal number of string comparisons.
395 or else Path (J - 1) = Path_Separator)
397 (J + Dir'Length > Path'Last
398 or else Path (J + Dir'Length) = Path_Separator)
399 and then Dir = Path (J .. J + Dir'Length - 1)
408 -- Start of processing for Add_To_Path
411 if Is_Present (Ada_Path_Buffer (1 .. Ada_Path_Length), Dir) then
413 -- Dir is already in the path, nothing to do
418 Min_Len := Ada_Path_Length + Dir'Length;
420 if Ada_Path_Length > 0 then
422 -- Add 1 for the Path_Separator character
424 Min_Len := Min_Len + 1;
427 -- If Ada_Path_Buffer is too small, increase it
429 Len := Ada_Path_Buffer'Last;
431 if Len < Min_Len then
434 exit when Len >= Min_Len;
437 New_Buffer := new String (1 .. Len);
438 New_Buffer (1 .. Ada_Path_Length) :=
439 Ada_Path_Buffer (1 .. Ada_Path_Length);
440 Free (Ada_Path_Buffer);
441 Ada_Path_Buffer := New_Buffer;
444 if Ada_Path_Length > 0 then
445 Ada_Path_Length := Ada_Path_Length + 1;
446 Ada_Path_Buffer (Ada_Path_Length) := Path_Separator;
450 (Ada_Path_Length + 1 .. Ada_Path_Length + Dir'Length) := Dir;
451 Ada_Path_Length := Ada_Path_Length + Dir'Length;
454 ------------------------
455 -- Add_To_Source_Path --
456 ------------------------
458 procedure Add_To_Source_Path (Source_Dirs : String_List_Id) is
459 Current : String_List_Id := Source_Dirs;
460 Source_Dir : String_Element;
464 -- Add each source directory
466 while Current /= Nil_String loop
467 Source_Dir := String_Elements.Table (Current);
470 -- Check if the source directory is already in the table
472 for Index in 1 .. Source_Paths.Last loop
473 -- If it is already, no need to add it
475 if Source_Paths.Table (Index) = Source_Dir.Value then
482 Source_Paths.Increment_Last;
483 Source_Paths.Table (Source_Paths.Last) := Source_Dir.Value;
486 -- Next source directory
488 Current := Source_Dir.Next;
490 end Add_To_Source_Path;
492 -----------------------
493 -- Body_Path_Name_Of --
494 -----------------------
496 function Body_Path_Name_Of (Unit : Unit_Id) return String is
497 Data : Unit_Data := Units.Table (Unit);
500 -- If we don't know the path name of the body of this unit,
501 -- we compute it, and we store it.
503 if Data.File_Names (Body_Part).Path = No_Name then
505 Current_Source : String_List_Id :=
506 Projects.Table (Data.File_Names (Body_Part).Project).Sources;
507 Path : GNAT.OS_Lib.String_Access;
510 -- By default, put the file name
512 Data.File_Names (Body_Part).Path :=
513 Data.File_Names (Body_Part).Name;
515 -- For each source directory
517 while Current_Source /= Nil_String loop
520 (Namet.Get_Name_String
521 (Data.File_Names (Body_Part).Name),
522 Namet.Get_Name_String
523 (String_Elements.Table (Current_Source).Value));
525 -- If the file is in this directory,
526 -- then we store the path, and we are done.
529 Name_Len := Path'Length;
530 Name_Buffer (1 .. Name_Len) := Path.all;
531 Data.File_Names (Body_Part).Path := Name_Enter;
536 String_Elements.Table (Current_Source).Next;
540 Units.Table (Unit) := Data;
544 -- Returned the stored value
546 return Namet.Get_Name_String (Data.File_Names (Body_Part).Path);
547 end Body_Path_Name_Of;
549 --------------------------------
550 -- Create_Config_Pragmas_File --
551 --------------------------------
553 procedure Create_Config_Pragmas_File
554 (For_Project : Project_Id;
555 Main_Project : Project_Id;
556 Include_Config_Files : Boolean := True)
558 pragma Unreferenced (Main_Project);
559 pragma Unreferenced (Include_Config_Files);
561 File_Name : Name_Id := No_Name;
562 File : File_Descriptor := Invalid_FD;
564 Current_Unit : Unit_Id := Units.First;
566 First_Project : Project_List := Empty_Project_List;
568 Current_Project : Project_List;
569 Current_Naming : Naming_Id;
574 procedure Check (Project : Project_Id);
575 -- Recursive procedure that put in the config pragmas file any non
576 -- standard naming schemes, if it is not already in the file, then call
577 -- itself for any imported project.
579 procedure Check_Temp_File;
580 -- Check that a temporary file has been opened.
581 -- If not, create one, and put its name in the project data,
582 -- with the indication that it is a temporary file.
585 (Unit_Name : Name_Id;
587 Unit_Kind : Spec_Or_Body);
588 -- Put an SFN pragma in the temporary file
590 procedure Put (File : File_Descriptor; S : String);
591 procedure Put_Line (File : File_Descriptor; S : String);
592 -- Output procedures, analogous to normal Text_IO procs of same name
598 procedure Check (Project : Project_Id) is
599 Data : constant Project_Data := Projects.Table (Project);
602 if Current_Verbosity = High then
603 Write_Str ("Checking project file """);
604 Write_Str (Namet.Get_Name_String (Data.Name));
609 -- Is this project in the list of the visited project?
611 Current_Project := First_Project;
612 while Current_Project /= Empty_Project_List
613 and then Project_Lists.Table (Current_Project).Project /= Project
615 Current_Project := Project_Lists.Table (Current_Project).Next;
618 -- If it is not, put it in the list, and visit it
620 if Current_Project = Empty_Project_List then
621 Project_Lists.Increment_Last;
622 Project_Lists.Table (Project_Lists.Last) :=
623 (Project => Project, Next => First_Project);
624 First_Project := Project_Lists.Last;
626 -- Is the naming scheme of this project one that we know?
628 Current_Naming := Default_Naming;
629 while Current_Naming <= Namings.Last and then
630 not Same_Naming_Scheme
631 (Left => Namings.Table (Current_Naming),
632 Right => Data.Naming) loop
633 Current_Naming := Current_Naming + 1;
636 -- If we don't know it, add it
638 if Current_Naming > Namings.Last then
639 Namings.Increment_Last;
640 Namings.Table (Namings.Last) := Data.Naming;
642 -- We need a temporary file to be created
646 -- Put the SFN pragmas for the naming scheme
651 (File, "pragma Source_File_Name_Project");
653 (File, " (Spec_File_Name => ""*" &
654 Namet.Get_Name_String (Data.Naming.Current_Spec_Suffix) &
657 (File, " Casing => " &
658 Image (Data.Naming.Casing) & ",");
660 (File, " Dot_Replacement => """ &
661 Namet.Get_Name_String (Data.Naming.Dot_Replacement) &
667 (File, "pragma Source_File_Name_Project");
669 (File, " (Body_File_Name => ""*" &
670 Namet.Get_Name_String (Data.Naming.Current_Body_Suffix) &
673 (File, " Casing => " &
674 Image (Data.Naming.Casing) & ",");
676 (File, " Dot_Replacement => """ &
677 Namet.Get_Name_String (Data.Naming.Dot_Replacement) &
680 -- and maybe separate
683 Data.Naming.Current_Body_Suffix /= Data.Naming.Separate_Suffix
686 (File, "pragma Source_File_Name_Project");
688 (File, " (Subunit_File_Name => ""*" &
689 Namet.Get_Name_String (Data.Naming.Separate_Suffix) &
692 (File, " Casing => " &
693 Image (Data.Naming.Casing) &
696 (File, " Dot_Replacement => """ &
697 Namet.Get_Name_String (Data.Naming.Dot_Replacement) &
702 if Data.Extends /= No_Project then
703 Check (Data.Extends);
707 Current : Project_List := Data.Imported_Projects;
710 while Current /= Empty_Project_List loop
711 Check (Project_Lists.Table (Current).Project);
712 Current := Project_Lists.Table (Current).Next;
718 ---------------------
719 -- Check_Temp_File --
720 ---------------------
722 procedure Check_Temp_File is
724 if File = Invalid_FD then
725 Tempdir.Create_Temp_File (File, Name => File_Name);
727 if File = Invalid_FD then
729 ("unable to create temporary configuration pragmas file");
730 elsif Opt.Verbose_Mode then
731 Write_Str ("Creating temp file """);
732 Write_Str (Get_Name_String (File_Name));
743 (Unit_Name : Name_Id;
745 Unit_Kind : Spec_Or_Body)
748 -- A temporary file needs to be open
752 -- Put the pragma SFN for the unit kind (spec or body)
754 Put (File, "pragma Source_File_Name_Project (");
755 Put (File, Namet.Get_Name_String (Unit_Name));
757 if Unit_Kind = Specification then
758 Put (File, ", Spec_File_Name => """);
760 Put (File, ", Body_File_Name => """);
763 Put (File, Namet.Get_Name_String (File_Name));
764 Put_Line (File, """);");
767 procedure Put (File : File_Descriptor; S : String) is
771 Last := Write (File, S (S'First)'Address, S'Length);
773 if Last /= S'Length then
774 Prj.Com.Fail ("Disk full");
777 if Current_Verbosity = High then
786 procedure Put_Line (File : File_Descriptor; S : String) is
787 S0 : String (1 .. S'Length + 1);
791 -- Add an ASCII.LF to the string. As this gnat.adc is supposed to
792 -- be used only by the compiler, we don't care about the characters
793 -- for the end of line. In fact we could have put a space, but
794 -- it is more convenient to be able to read gnat.adc during
795 -- development, for which the ASCII.LF is fine.
797 S0 (1 .. S'Length) := S;
798 S0 (S0'Last) := ASCII.LF;
799 Last := Write (File, S0'Address, S0'Length);
801 if Last /= S'Length + 1 then
802 Prj.Com.Fail ("Disk full");
805 if Current_Verbosity = High then
810 -- Start of processing for Create_Config_Pragmas_File
813 if not Projects.Table (For_Project).Config_Checked then
815 -- Remove any memory of processed naming schemes, if any
817 Namings.Set_Last (Default_Naming);
819 -- Check the naming schemes
823 -- Visit all the units and process those that need an SFN pragma
825 while Current_Unit <= Units.Last loop
827 Unit : constant Unit_Data :=
828 Units.Table (Current_Unit);
831 if Unit.File_Names (Specification).Needs_Pragma then
833 Unit.File_Names (Specification).Name,
837 if Unit.File_Names (Body_Part).Needs_Pragma then
839 Unit.File_Names (Body_Part).Name,
843 Current_Unit := Current_Unit + 1;
847 -- If there are no non standard naming scheme, issue the GNAT
848 -- standard naming scheme. This will tell the compiler that
849 -- a project file is used and will forbid any pragma SFN.
851 if File = Invalid_FD then
854 Put_Line (File, "pragma Source_File_Name_Project");
855 Put_Line (File, " (Spec_File_Name => ""*.ads"",");
856 Put_Line (File, " Dot_Replacement => ""-"",");
857 Put_Line (File, " Casing => lowercase);");
859 Put_Line (File, "pragma Source_File_Name_Project");
860 Put_Line (File, " (Body_File_Name => ""*.adb"",");
861 Put_Line (File, " Dot_Replacement => ""-"",");
862 Put_Line (File, " Casing => lowercase);");
865 -- Close the temporary file
867 GNAT.OS_Lib.Close (File, Status);
870 Prj.Com.Fail ("disk full");
873 if Opt.Verbose_Mode then
874 Write_Str ("Closing configuration file """);
875 Write_Str (Get_Name_String (File_Name));
879 Projects.Table (For_Project).Config_File_Name := File_Name;
880 Projects.Table (For_Project).Config_File_Temp := True;
882 Projects.Table (For_Project).Config_Checked := True;
884 end Create_Config_Pragmas_File;
886 -------------------------
887 -- Create_Mapping_File --
888 -------------------------
890 procedure Create_Mapping_File
891 (Project : Project_Id;
894 File : File_Descriptor := Invalid_FD;
895 The_Unit_Data : Unit_Data;
896 Data : File_Name_Data;
901 Present : Project_Flags (No_Project .. Projects.Last) :=
903 -- For each project in the closure of Project, the corresponding flag
904 -- will be set to True;
906 procedure Put_Name_Buffer;
907 -- Put the line contained in the Name_Buffer in the mapping file
909 procedure Put_Data (Spec : Boolean);
910 -- Put the mapping of the spec or body contained in Data in the file
913 procedure Recursive_Flag (Prj : Project_Id);
914 -- Set the flags corresponding to Prj, the projects it imports
915 -- (directly or indirectly) or extends to True. Call itself recursively.
921 procedure Put_Name_Buffer is
925 Name_Len := Name_Len + 1;
926 Name_Buffer (Name_Len) := ASCII.LF;
927 Last := Write (File, Name_Buffer (1)'Address, Name_Len);
929 if Last /= Name_Len then
930 Prj.Com.Fail ("Disk full");
938 procedure Put_Data (Spec : Boolean) is
940 -- Line with the unit name
942 Get_Name_String (The_Unit_Data.Name);
943 Name_Len := Name_Len + 1;
944 Name_Buffer (Name_Len) := '%';
945 Name_Len := Name_Len + 1;
948 Name_Buffer (Name_Len) := 's';
950 Name_Buffer (Name_Len) := 'b';
955 -- Line with the file name
957 Get_Name_String (Data.Name);
960 -- Line with the path name
962 Get_Name_String (Data.Path);
971 procedure Recursive_Flag (Prj : Project_Id) is
972 Imported : Project_List;
976 -- Nothing to do for non existent project or project that has
977 -- already been flagged.
979 if Prj = No_Project or else Present (Prj) then
983 -- Flag the current project
985 Present (Prj) := True;
986 Imported := Projects.Table (Prj).Imported_Projects;
988 -- Call itself for each project directly imported
990 while Imported /= Empty_Project_List loop
991 Proj := Project_Lists.Table (Imported).Project;
992 Imported := Project_Lists.Table (Imported).Next;
993 Recursive_Flag (Proj);
996 -- Call itself for an eventual project being extended
998 Recursive_Flag (Projects.Table (Prj).Extends);
1001 -- Start of processing for Create_Mapping_File
1004 -- Flag the necessary projects
1006 Recursive_Flag (Project);
1008 -- Create the temporary file
1010 Tempdir.Create_Temp_File (File, Name => Name);
1012 if File = Invalid_FD then
1013 Prj.Com.Fail ("unable to create temporary mapping file");
1015 elsif Opt.Verbose_Mode then
1016 Write_Str ("Creating temp mapping file """);
1017 Write_Str (Get_Name_String (Name));
1021 if Fill_Mapping_File then
1022 -- For all units in table Units
1024 for Unit in 1 .. Units.Last loop
1025 The_Unit_Data := Units.Table (Unit);
1027 -- If the unit has a valid name
1029 if The_Unit_Data.Name /= No_Name then
1030 Data := The_Unit_Data.File_Names (Specification);
1032 -- If there is a spec, put it mapping in the file if it is
1033 -- from a project in the closure of Project.
1035 if Data.Name /= No_Name and then Present (Data.Project) then
1036 Put_Data (Spec => True);
1039 Data := The_Unit_Data.File_Names (Body_Part);
1041 -- If there is a body (or subunit) put its mapping in the file
1042 -- if it is from a project in the closure of Project.
1044 if Data.Name /= No_Name and then Present (Data.Project) then
1045 Put_Data (Spec => False);
1052 GNAT.OS_Lib.Close (File, Status);
1055 Prj.Com.Fail ("disk full");
1057 end Create_Mapping_File;
1059 --------------------------
1060 -- Create_New_Path_File --
1061 --------------------------
1063 procedure Create_New_Path_File
1064 (Path_FD : out File_Descriptor;
1065 Path_Name : out Name_Id)
1068 Tempdir.Create_Temp_File (Path_FD, Path_Name);
1070 if Path_Name /= No_Name then
1072 -- Record the name, so that the temp path file will be deleted
1073 -- at the end of the program.
1075 Path_Files.Increment_Last;
1076 Path_Files.Table (Path_Files.Last) := Path_Name;
1078 end Create_New_Path_File;
1080 ---------------------------
1081 -- Delete_All_Path_Files --
1082 ---------------------------
1084 procedure Delete_All_Path_Files is
1085 Disregard : Boolean := True;
1088 for Index in 1 .. Path_Files.Last loop
1089 if Path_Files.Table (Index) /= No_Name then
1091 (Get_Name_String (Path_Files.Table (Index)), Disregard);
1095 -- If any of the environment variables ADA_PRJ_INCLUDE_FILE or
1096 -- ADA_PRJ_OBJECTS_FILE has been set, then reset their value to
1097 -- the empty string. On VMS, this has the effect of deassigning
1098 -- the logical names.
1100 if Ada_Prj_Include_File_Set then
1101 Setenv (Project_Include_Path_File, "");
1102 Ada_Prj_Include_File_Set := False;
1105 if Ada_Prj_Objects_File_Set then
1106 Setenv (Project_Objects_Path_File, "");
1107 Ada_Prj_Objects_File_Set := False;
1109 end Delete_All_Path_Files;
1111 ------------------------------------
1112 -- File_Name_Of_Library_Unit_Body --
1113 ------------------------------------
1115 function File_Name_Of_Library_Unit_Body
1117 Project : Project_Id;
1118 Main_Project_Only : Boolean := True;
1119 Full_Path : Boolean := False) return String
1121 The_Project : Project_Id := Project;
1122 Data : Project_Data := Projects.Table (Project);
1123 Original_Name : String := Name;
1125 Extended_Spec_Name : String :=
1126 Name & Namet.Get_Name_String
1127 (Data.Naming.Current_Spec_Suffix);
1128 Extended_Body_Name : String :=
1129 Name & Namet.Get_Name_String
1130 (Data.Naming.Current_Body_Suffix);
1134 The_Original_Name : Name_Id;
1135 The_Spec_Name : Name_Id;
1136 The_Body_Name : Name_Id;
1139 Canonical_Case_File_Name (Original_Name);
1140 Name_Len := Original_Name'Length;
1141 Name_Buffer (1 .. Name_Len) := Original_Name;
1142 The_Original_Name := Name_Find;
1144 Canonical_Case_File_Name (Extended_Spec_Name);
1145 Name_Len := Extended_Spec_Name'Length;
1146 Name_Buffer (1 .. Name_Len) := Extended_Spec_Name;
1147 The_Spec_Name := Name_Find;
1149 Canonical_Case_File_Name (Extended_Body_Name);
1150 Name_Len := Extended_Body_Name'Length;
1151 Name_Buffer (1 .. Name_Len) := Extended_Body_Name;
1152 The_Body_Name := Name_Find;
1154 if Current_Verbosity = High then
1155 Write_Str ("Looking for file name of """);
1159 Write_Str (" Extended Spec Name = """);
1160 Write_Str (Extended_Spec_Name);
1163 Write_Str (" Extended Body Name = """);
1164 Write_Str (Extended_Body_Name);
1169 -- For extending project, search in the extended project
1170 -- if the source is not found. For non extending projects,
1171 -- this loop will be run only once.
1174 -- Loop through units
1175 -- Should have comment explaining reverse ???
1177 for Current in reverse Units.First .. Units.Last loop
1178 Unit := Units.Table (Current);
1182 if not Main_Project_Only
1183 or else Unit.File_Names (Body_Part).Project = The_Project
1186 Current_Name : constant Name_Id :=
1187 Unit.File_Names (Body_Part).Name;
1190 -- Case of a body present
1192 if Current_Name /= No_Name then
1193 if Current_Verbosity = High then
1194 Write_Str (" Comparing with """);
1195 Write_Str (Get_Name_String (Current_Name));
1200 -- If it has the name of the original name,
1201 -- return the original name
1203 if Unit.Name = The_Original_Name
1204 or else Current_Name = The_Original_Name
1206 if Current_Verbosity = High then
1211 return Get_Name_String
1212 (Unit.File_Names (Body_Part).Path);
1215 return Get_Name_String (Current_Name);
1218 -- If it has the name of the extended body name,
1219 -- return the extended body name
1221 elsif Current_Name = The_Body_Name then
1222 if Current_Verbosity = High then
1227 return Get_Name_String
1228 (Unit.File_Names (Body_Part).Path);
1231 return Extended_Body_Name;
1235 if Current_Verbosity = High then
1236 Write_Line (" not good");
1245 if not Main_Project_Only
1246 or else Unit.File_Names (Specification).Project = The_Project
1249 Current_Name : constant Name_Id :=
1250 Unit.File_Names (Specification).Name;
1253 -- Case of spec present
1255 if Current_Name /= No_Name then
1256 if Current_Verbosity = High then
1257 Write_Str (" Comparing with """);
1258 Write_Str (Get_Name_String (Current_Name));
1263 -- If name same as original name, return original name
1265 if Unit.Name = The_Original_Name
1266 or else Current_Name = The_Original_Name
1268 if Current_Verbosity = High then
1274 return Get_Name_String
1275 (Unit.File_Names (Specification).Path);
1277 return Get_Name_String (Current_Name);
1280 -- If it has the same name as the extended spec name,
1281 -- return the extended spec name.
1283 elsif Current_Name = The_Spec_Name then
1284 if Current_Verbosity = High then
1289 return Get_Name_String
1290 (Unit.File_Names (Specification).Path);
1292 return Extended_Spec_Name;
1296 if Current_Verbosity = High then
1297 Write_Line (" not good");
1305 -- If we are not in an extending project, give up
1307 exit when (not Main_Project_Only) or else Data.Extends = No_Project;
1309 -- Otherwise, look in the project we are extending
1311 The_Project := Data.Extends;
1312 Data := Projects.Table (The_Project);
1315 -- We don't know this file name, return an empty string
1318 end File_Name_Of_Library_Unit_Body;
1320 -------------------------
1321 -- For_All_Object_Dirs --
1322 -------------------------
1324 procedure For_All_Object_Dirs (Project : Project_Id) is
1325 Seen : Project_List := Empty_Project_List;
1327 procedure Add (Project : Project_Id);
1328 -- Process a project. Remember the processes visited to avoid
1329 -- processing a project twice. Recursively process an eventual
1330 -- extended project, and all imported projects.
1336 procedure Add (Project : Project_Id) is
1337 Data : constant Project_Data := Projects.Table (Project);
1338 List : Project_List := Data.Imported_Projects;
1341 -- If the list of visited project is empty, then
1342 -- for sure we never visited this project.
1344 if Seen = Empty_Project_List then
1345 Project_Lists.Increment_Last;
1346 Seen := Project_Lists.Last;
1347 Project_Lists.Table (Seen) :=
1348 (Project => Project, Next => Empty_Project_List);
1351 -- Check if the project is in the list
1354 Current : Project_List := Seen;
1358 -- If it is, then there is nothing else to do
1360 if Project_Lists.Table (Current).Project = Project then
1364 exit when Project_Lists.Table (Current).Next =
1366 Current := Project_Lists.Table (Current).Next;
1369 -- This project has never been visited, add it
1372 Project_Lists.Increment_Last;
1373 Project_Lists.Table (Current).Next := Project_Lists.Last;
1374 Project_Lists.Table (Project_Lists.Last) :=
1375 (Project => Project, Next => Empty_Project_List);
1379 -- If there is an object directory, call Action
1382 if Data.Object_Directory /= No_Name then
1383 Get_Name_String (Data.Object_Directory);
1384 Action (Name_Buffer (1 .. Name_Len));
1387 -- If we are extending a project, visit it
1389 if Data.Extends /= No_Project then
1393 -- And visit all imported projects
1395 while List /= Empty_Project_List loop
1396 Add (Project_Lists.Table (List).Project);
1397 List := Project_Lists.Table (List).Next;
1401 -- Start of processing for For_All_Object_Dirs
1404 -- Visit this project, and its imported projects,
1408 end For_All_Object_Dirs;
1410 -------------------------
1411 -- For_All_Source_Dirs --
1412 -------------------------
1414 procedure For_All_Source_Dirs (Project : Project_Id) is
1415 Seen : Project_List := Empty_Project_List;
1417 procedure Add (Project : Project_Id);
1418 -- Process a project. Remember the processes visited to avoid
1419 -- processing a project twice. Recursively process an eventual
1420 -- extended project, and all imported projects.
1426 procedure Add (Project : Project_Id) is
1427 Data : constant Project_Data := Projects.Table (Project);
1428 List : Project_List := Data.Imported_Projects;
1431 -- If the list of visited project is empty, then
1432 -- for sure we never visited this project.
1434 if Seen = Empty_Project_List then
1435 Project_Lists.Increment_Last;
1436 Seen := Project_Lists.Last;
1437 Project_Lists.Table (Seen) :=
1438 (Project => Project, Next => Empty_Project_List);
1441 -- Check if the project is in the list
1444 Current : Project_List := Seen;
1448 -- If it is, then there is nothing else to do
1450 if Project_Lists.Table (Current).Project = Project then
1454 exit when Project_Lists.Table (Current).Next =
1456 Current := Project_Lists.Table (Current).Next;
1459 -- This project has never been visited, add it
1462 Project_Lists.Increment_Last;
1463 Project_Lists.Table (Current).Next := Project_Lists.Last;
1464 Project_Lists.Table (Project_Lists.Last) :=
1465 (Project => Project, Next => Empty_Project_List);
1470 Current : String_List_Id := Data.Source_Dirs;
1471 The_String : String_Element;
1474 -- If there are Ada sources, call action with the name of every
1475 -- source directory.
1477 if Projects.Table (Project).Sources_Present then
1478 while Current /= Nil_String loop
1479 The_String := String_Elements.Table (Current);
1480 Action (Get_Name_String (The_String.Value));
1481 Current := The_String.Next;
1486 -- If we are extending a project, visit it
1488 if Data.Extends /= No_Project then
1492 -- And visit all imported projects
1494 while List /= Empty_Project_List loop
1495 Add (Project_Lists.Table (List).Project);
1496 List := Project_Lists.Table (List).Next;
1500 -- Start of processing for For_All_Source_Dirs
1503 -- Visit this project, and its imported projects recursively
1506 end For_All_Source_Dirs;
1512 procedure Get_Reference
1513 (Source_File_Name : String;
1514 Project : out Project_Id;
1518 -- Body below could use some comments ???
1520 if Current_Verbosity > Default then
1521 Write_Str ("Getting Reference_Of (""");
1522 Write_Str (Source_File_Name);
1523 Write_Str (""") ... ");
1527 Original_Name : String := Source_File_Name;
1531 Canonical_Case_File_Name (Original_Name);
1533 for Id in Units.First .. Units.Last loop
1534 Unit := Units.Table (Id);
1536 if (Unit.File_Names (Specification).Name /= No_Name
1538 Namet.Get_Name_String
1539 (Unit.File_Names (Specification).Name) = Original_Name)
1540 or else (Unit.File_Names (Specification).Path /= No_Name
1542 Namet.Get_Name_String
1543 (Unit.File_Names (Specification).Path) =
1546 Project := Ultimate_Extension_Of
1547 (Unit.File_Names (Specification).Project);
1548 Path := Unit.File_Names (Specification).Display_Path;
1550 if Current_Verbosity > Default then
1551 Write_Str ("Done: Specification.");
1557 elsif (Unit.File_Names (Body_Part).Name /= No_Name
1559 Namet.Get_Name_String
1560 (Unit.File_Names (Body_Part).Name) = Original_Name)
1561 or else (Unit.File_Names (Body_Part).Path /= No_Name
1562 and then Namet.Get_Name_String
1563 (Unit.File_Names (Body_Part).Path) =
1566 Project := Ultimate_Extension_Of
1567 (Unit.File_Names (Body_Part).Project);
1568 Path := Unit.File_Names (Body_Part).Display_Path;
1570 if Current_Verbosity > Default then
1571 Write_Str ("Done: Body.");
1580 Project := No_Project;
1583 if Current_Verbosity > Default then
1584 Write_Str ("Cannot be found.");
1593 -- This is a place holder for possible required initialization in
1594 -- the future. In the current version no initialization is required.
1596 procedure Initialize is
1601 ------------------------------------
1602 -- Path_Name_Of_Library_Unit_Body --
1603 ------------------------------------
1605 -- Could use some comments in the body here ???
1607 function Path_Name_Of_Library_Unit_Body
1609 Project : Project_Id) return String
1611 Data : constant Project_Data := Projects.Table (Project);
1612 Original_Name : String := Name;
1614 Extended_Spec_Name : String :=
1615 Name & Namet.Get_Name_String
1616 (Data.Naming.Current_Spec_Suffix);
1617 Extended_Body_Name : String :=
1618 Name & Namet.Get_Name_String
1619 (Data.Naming.Current_Body_Suffix);
1621 First : Unit_Id := Units.First;
1626 Canonical_Case_File_Name (Original_Name);
1627 Canonical_Case_File_Name (Extended_Spec_Name);
1628 Canonical_Case_File_Name (Extended_Body_Name);
1630 if Current_Verbosity = High then
1631 Write_Str ("Looking for path name of """);
1635 Write_Str (" Extended Spec Name = """);
1636 Write_Str (Extended_Spec_Name);
1639 Write_Str (" Extended Body Name = """);
1640 Write_Str (Extended_Body_Name);
1645 while First <= Units.Last
1646 and then Units.Table (First).File_Names (Body_Part).Project /= Project
1652 while Current <= Units.Last loop
1653 Unit := Units.Table (Current);
1655 if Unit.File_Names (Body_Part).Project = Project
1656 and then Unit.File_Names (Body_Part).Name /= No_Name
1659 Current_Name : constant String :=
1660 Namet.Get_Name_String (Unit.File_Names (Body_Part).Name);
1662 if Current_Verbosity = High then
1663 Write_Str (" Comparing with """);
1664 Write_Str (Current_Name);
1669 if Current_Name = Original_Name then
1670 if Current_Verbosity = High then
1674 return Body_Path_Name_Of (Current);
1676 elsif Current_Name = Extended_Body_Name then
1677 if Current_Verbosity = High then
1681 return Body_Path_Name_Of (Current);
1684 if Current_Verbosity = High then
1685 Write_Line (" not good");
1690 elsif Unit.File_Names (Specification).Name /= No_Name then
1692 Current_Name : constant String :=
1693 Namet.Get_Name_String
1694 (Unit.File_Names (Specification).Name);
1697 if Current_Verbosity = High then
1698 Write_Str (" Comparing with """);
1699 Write_Str (Current_Name);
1704 if Current_Name = Original_Name then
1705 if Current_Verbosity = High then
1709 return Spec_Path_Name_Of (Current);
1711 elsif Current_Name = Extended_Spec_Name then
1712 if Current_Verbosity = High then
1716 return Spec_Path_Name_Of (Current);
1719 if Current_Verbosity = High then
1720 Write_Line (" not good");
1725 Current := Current + 1;
1729 end Path_Name_Of_Library_Unit_Body;
1735 -- Could use some comments in this body ???
1737 procedure Print_Sources is
1741 Write_Line ("List of Sources:");
1743 for Id in Units.First .. Units.Last loop
1744 Unit := Units.Table (Id);
1746 Write_Line (Namet.Get_Name_String (Unit.Name));
1748 if Unit.File_Names (Specification).Name /= No_Name then
1749 if Unit.File_Names (Specification).Project = No_Project then
1750 Write_Line (" No project");
1753 Write_Str (" Project: ");
1756 (Unit.File_Names (Specification).Project).Path_Name);
1757 Write_Line (Name_Buffer (1 .. Name_Len));
1760 Write_Str (" spec: ");
1762 (Namet.Get_Name_String
1763 (Unit.File_Names (Specification).Name));
1766 if Unit.File_Names (Body_Part).Name /= No_Name then
1767 if Unit.File_Names (Body_Part).Project = No_Project then
1768 Write_Line (" No project");
1771 Write_Str (" Project: ");
1774 (Unit.File_Names (Body_Part).Project).Path_Name);
1775 Write_Line (Name_Buffer (1 .. Name_Len));
1778 Write_Str (" body: ");
1780 (Namet.Get_Name_String
1781 (Unit.File_Names (Body_Part).Name));
1785 Write_Line ("end of List of Sources.");
1794 Main_Project : Project_Id) return Project_Id
1796 Result : Project_Id := No_Project;
1798 Original_Name : String := Name;
1800 Data : constant Project_Data := Projects.Table (Main_Project);
1802 Extended_Spec_Name : String :=
1803 Name & Namet.Get_Name_String
1804 (Data.Naming.Current_Spec_Suffix);
1805 Extended_Body_Name : String :=
1806 Name & Namet.Get_Name_String
1807 (Data.Naming.Current_Body_Suffix);
1811 Current_Name : Name_Id;
1813 The_Original_Name : Name_Id;
1814 The_Spec_Name : Name_Id;
1815 The_Body_Name : Name_Id;
1818 Canonical_Case_File_Name (Original_Name);
1819 Name_Len := Original_Name'Length;
1820 Name_Buffer (1 .. Name_Len) := Original_Name;
1821 The_Original_Name := Name_Find;
1823 Canonical_Case_File_Name (Extended_Spec_Name);
1824 Name_Len := Extended_Spec_Name'Length;
1825 Name_Buffer (1 .. Name_Len) := Extended_Spec_Name;
1826 The_Spec_Name := Name_Find;
1828 Canonical_Case_File_Name (Extended_Body_Name);
1829 Name_Len := Extended_Body_Name'Length;
1830 Name_Buffer (1 .. Name_Len) := Extended_Body_Name;
1831 The_Body_Name := Name_Find;
1833 for Current in reverse Units.First .. Units.Last loop
1834 Unit := Units.Table (Current);
1838 Current_Name := Unit.File_Names (Body_Part).Name;
1840 -- Case of a body present
1842 if Current_Name /= No_Name then
1844 -- If it has the name of the original name or the body name,
1845 -- we have found the project.
1847 if Unit.Name = The_Original_Name
1848 or else Current_Name = The_Original_Name
1849 or else Current_Name = The_Body_Name
1851 Result := Unit.File_Names (Body_Part).Project;
1858 Current_Name := Unit.File_Names (Specification).Name;
1860 if Current_Name /= No_Name then
1862 -- If name same as the original name, or the spec name, we have
1863 -- found the project.
1865 if Unit.Name = The_Original_Name
1866 or else Current_Name = The_Original_Name
1867 or else Current_Name = The_Spec_Name
1869 Result := Unit.File_Names (Specification).Project;
1875 -- Get the ultimate extending project
1877 if Result /= No_Project then
1878 while Projects.Table (Result).Extended_By /= No_Project loop
1879 Result := Projects.Table (Result).Extended_By;
1890 procedure Set_Ada_Paths
1891 (Project : Project_Id;
1892 Including_Libraries : Boolean)
1894 Source_FD : File_Descriptor := Invalid_FD;
1895 Object_FD : File_Descriptor := Invalid_FD;
1897 Process_Source_Dirs : Boolean := False;
1898 Process_Object_Dirs : Boolean := False;
1901 -- For calls to Close
1905 procedure Add (Proj : Project_Id);
1906 -- Add all the source/object directories of a project to the path only
1907 -- if this project has not been visited. Calls an internal procedure
1908 -- recursively for projects being extended, and imported projects.
1914 procedure Add (Proj : Project_Id) is
1916 procedure Recursive_Add (Project : Project_Id);
1917 -- Recursive procedure to add the source/object paths of extended/
1918 -- imported projects.
1924 procedure Recursive_Add (Project : Project_Id) is
1926 -- If Seen is False, then the project has not yet been visited
1928 if not Projects.Table (Project).Seen then
1929 Projects.Table (Project).Seen := True;
1932 Data : constant Project_Data := Projects.Table (Project);
1933 List : Project_List := Data.Imported_Projects;
1936 if Process_Source_Dirs then
1938 -- Add to path all source directories of this project
1939 -- if there are Ada sources.
1941 if Projects.Table (Project).Sources_Present then
1942 Add_To_Source_Path (Data.Source_Dirs);
1946 if Process_Object_Dirs then
1948 -- Add to path the object directory of this project
1949 -- except if we don't include library project and
1950 -- this is a library project.
1952 if (Data.Library and then Including_Libraries)
1954 (Data.Object_Directory /= No_Name
1956 (not Including_Libraries or else not Data.Library))
1958 -- For a library project, add the library directory
1960 if Data.Library then
1961 Add_To_Object_Path (Data.Library_Dir);
1964 -- For a non library project, add the object
1967 Add_To_Object_Path (Data.Object_Directory);
1972 -- Call Add to the project being extended, if any
1974 if Data.Extends /= No_Project then
1975 Recursive_Add (Data.Extends);
1978 -- Call Add for each imported project, if any
1980 while List /= Empty_Project_List loop
1981 Recursive_Add (Project_Lists.Table (List).Project);
1982 List := Project_Lists.Table (List).Next;
1989 Source_Paths.Set_Last (0);
1990 Object_Paths.Set_Last (0);
1992 for Index in 1 .. Projects.Last loop
1993 Projects.Table (Index).Seen := False;
1996 Recursive_Add (Proj);
1999 -- Start of processing for Set_Ada_Paths
2002 -- If it is the first time we call this procedure for
2003 -- this project, compute the source path and/or the object path.
2005 if Projects.Table (Project).Include_Path_File = No_Name then
2006 Process_Source_Dirs := True;
2007 Create_New_Path_File
2008 (Source_FD, Projects.Table (Project).Include_Path_File);
2011 -- For the object path, we make a distinction depending on
2012 -- Including_Libraries.
2014 if Including_Libraries then
2015 if Projects.Table (Project).Objects_Path_File_With_Libs = No_Name then
2016 Process_Object_Dirs := True;
2017 Create_New_Path_File
2018 (Object_FD, Projects.Table (Project).
2019 Objects_Path_File_With_Libs);
2024 Projects.Table (Project).Objects_Path_File_Without_Libs = No_Name
2026 Process_Object_Dirs := True;
2027 Create_New_Path_File
2028 (Object_FD, Projects.Table (Project).
2029 Objects_Path_File_Without_Libs);
2033 -- If there is something to do, set Seen to False for all projects,
2034 -- then call the recursive procedure Add for Project.
2036 if Process_Source_Dirs or Process_Object_Dirs then
2040 -- Write and close any file that has been created.
2042 if Source_FD /= Invalid_FD then
2043 for Index in 1 .. Source_Paths.Last loop
2044 Get_Name_String (Source_Paths.Table (Index));
2045 Name_Len := Name_Len + 1;
2046 Name_Buffer (Name_Len) := ASCII.LF;
2047 Len := Write (Source_FD, Name_Buffer (1)'Address, Name_Len);
2049 if Len /= Name_Len then
2050 Prj.Com.Fail ("disk full");
2054 Close (Source_FD, Status);
2057 Prj.Com.Fail ("disk full");
2061 if Object_FD /= Invalid_FD then
2062 for Index in 1 .. Object_Paths.Last loop
2063 Get_Name_String (Object_Paths.Table (Index));
2064 Name_Len := Name_Len + 1;
2065 Name_Buffer (Name_Len) := ASCII.LF;
2066 Len := Write (Object_FD, Name_Buffer (1)'Address, Name_Len);
2068 if Len /= Name_Len then
2069 Prj.Com.Fail ("disk full");
2073 Close (Object_FD, Status);
2076 Prj.Com.Fail ("disk full");
2080 -- Set the env vars, if they need to be changed, and set the
2081 -- corresponding flags.
2083 if Current_Source_Path_File /=
2084 Projects.Table (Project).Include_Path_File
2086 Current_Source_Path_File :=
2087 Projects.Table (Project).Include_Path_File;
2089 (Project_Include_Path_File,
2090 Get_Name_String (Current_Source_Path_File));
2091 Ada_Prj_Include_File_Set := True;
2094 if Including_Libraries then
2095 if Current_Object_Path_File
2096 /= Projects.Table (Project).Objects_Path_File_With_Libs
2098 Current_Object_Path_File :=
2099 Projects.Table (Project).Objects_Path_File_With_Libs;
2101 (Project_Objects_Path_File,
2102 Get_Name_String (Current_Object_Path_File));
2103 Ada_Prj_Objects_File_Set := True;
2107 if Current_Object_Path_File
2108 /= Projects.Table (Project).Objects_Path_File_Without_Libs
2110 Current_Object_Path_File :=
2111 Projects.Table (Project).Objects_Path_File_Without_Libs;
2113 (Project_Objects_Path_File,
2114 Get_Name_String (Current_Object_Path_File));
2115 Ada_Prj_Objects_File_Set := True;
2120 ---------------------------------------------
2121 -- Set_Mapping_File_Initial_State_To_Empty --
2122 ---------------------------------------------
2124 procedure Set_Mapping_File_Initial_State_To_Empty is
2126 Fill_Mapping_File := False;
2127 end Set_Mapping_File_Initial_State_To_Empty;
2129 -----------------------
2130 -- Set_Path_File_Var --
2131 -----------------------
2133 procedure Set_Path_File_Var (Name : String; Value : String) is
2134 Host_Spec : String_Access := To_Host_File_Spec (Value);
2137 if Host_Spec = null then
2139 ("could not convert file name """, Value, """ to host spec");
2141 Setenv (Name, Host_Spec.all);
2144 end Set_Path_File_Var;
2146 -----------------------
2147 -- Spec_Path_Name_Of --
2148 -----------------------
2150 function Spec_Path_Name_Of (Unit : Unit_Id) return String is
2151 Data : Unit_Data := Units.Table (Unit);
2154 if Data.File_Names (Specification).Path = No_Name then
2156 Current_Source : String_List_Id :=
2157 Projects.Table (Data.File_Names (Specification).Project).Sources;
2158 Path : GNAT.OS_Lib.String_Access;
2161 Data.File_Names (Specification).Path :=
2162 Data.File_Names (Specification).Name;
2164 while Current_Source /= Nil_String loop
2165 Path := Locate_Regular_File
2166 (Namet.Get_Name_String
2167 (Data.File_Names (Specification).Name),
2168 Namet.Get_Name_String
2169 (String_Elements.Table (Current_Source).Value));
2171 if Path /= null then
2172 Name_Len := Path'Length;
2173 Name_Buffer (1 .. Name_Len) := Path.all;
2174 Data.File_Names (Specification).Path := Name_Enter;
2178 String_Elements.Table (Current_Source).Next;
2182 Units.Table (Unit) := Data;
2186 return Namet.Get_Name_String (Data.File_Names (Specification).Path);
2187 end Spec_Path_Name_Of;
2189 ---------------------------
2190 -- Ultimate_Extension_Of --
2191 ---------------------------
2193 function Ultimate_Extension_Of (Project : in Project_Id) return Project_Id
2195 Result : Project_Id := Project;
2198 while Projects.Table (Result).Extended_By /= No_Project loop
2199 Result := Projects.Table (Result).Extended_By;
2203 end Ultimate_Extension_Of;
2205 -- Package initialization
2206 -- What is relationshiop to procedure Initialize
2209 Path_Files.Set_Last (0);