1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2000-2007, 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 GNAT.Case_Util; use GNAT.Case_Util;
28 with GNAT.Directory_Operations; use GNAT.Directory_Operations;
31 with Err_Vars; use Err_Vars;
36 with Osint; use Osint;
37 with Output; use Output;
38 with Prj.Env; use Prj.Env;
40 with Prj.Util; use Prj.Util;
42 with Snames; use Snames;
43 with Table; use Table;
44 with Targparm; use Targparm;
46 with Ada.Characters.Handling; use Ada.Characters.Handling;
47 with Ada.Directories; use Ada.Directories;
48 with Ada.Strings; use Ada.Strings;
49 with Ada.Strings.Fixed; use Ada.Strings.Fixed;
50 with Ada.Strings.Maps.Constants; use Ada.Strings.Maps.Constants;
52 package body Prj.Nmsc is
54 No_Continuation_String : aliased String := "";
55 Continuation_String : aliased String := "\";
56 -- Used in Check_Library for continuation error messages at the same
59 Error_Report : Put_Line_Access := null;
60 -- Set to point to error reporting procedure
62 When_No_Sources : Error_Warning := Error;
63 -- Indicates what should be done when there is no Ada sources in a non
64 -- extending Ada project.
66 ALI_Suffix : constant String := ".ali";
67 -- File suffix for ali files
69 Object_Suffix : constant String := Get_Target_Object_Suffix.all;
70 -- File suffix for object files
72 type Name_Location is record
73 Name : File_Name_Type;
74 Location : Source_Ptr;
75 Source : Source_Id := No_Source;
76 Except : Boolean := False;
77 Found : Boolean := False;
79 -- Information about file names found in string list attribute
80 -- Source_Files or in a source list file, stored in hash table
81 -- Source_Names, used by procedure Get_Path_Names_And_Record_Sources.
83 No_Name_Location : constant Name_Location :=
85 Location => No_Location,
90 package Source_Names is new GNAT.HTable.Simple_HTable
91 (Header_Num => Header_Num,
92 Element => Name_Location,
93 No_Element => No_Name_Location,
94 Key => File_Name_Type,
97 -- Hash table to store file names found in string list attribute
98 -- Source_Files or in a source list file, stored in hash table
99 -- Source_Names, used by procedure Get_Path_Names_And_Record_Sources.
101 package Recursive_Dirs is new GNAT.HTable.Simple_HTable
102 (Header_Num => Header_Num,
108 -- Hash table to store recursive source directories, to avoid looking
109 -- several times, and to avoid cycles that may be introduced by symbolic
112 type Ada_Naming_Exception_Id is new Nat;
113 No_Ada_Naming_Exception : constant Ada_Naming_Exception_Id := 0;
115 type Unit_Info is record
118 Next : Ada_Naming_Exception_Id := No_Ada_Naming_Exception;
120 -- No_Unit : constant Unit_Info :=
121 -- (Specification, No_Name, No_Ada_Naming_Exception);
123 package Ada_Naming_Exception_Table is new Table.Table
124 (Table_Component_Type => Unit_Info,
125 Table_Index_Type => Ada_Naming_Exception_Id,
126 Table_Low_Bound => 1,
128 Table_Increment => 100,
129 Table_Name => "Prj.Nmsc.Ada_Naming_Exception_Table");
131 package Ada_Naming_Exceptions is new GNAT.HTable.Simple_HTable
132 (Header_Num => Header_Num,
133 Element => Ada_Naming_Exception_Id,
134 No_Element => No_Ada_Naming_Exception,
135 Key => File_Name_Type,
138 -- A hash table to store naming exceptions for Ada. For each file name
139 -- there is one or several unit in table Ada_Naming_Exception_Table.
141 function Hash (Unit : Unit_Info) return Header_Num;
143 type Name_And_Index is record
144 Name : Name_Id := No_Name;
147 No_Name_And_Index : constant Name_And_Index :=
148 (Name => No_Name, Index => 0);
150 package Reverse_Ada_Naming_Exceptions is new GNAT.HTable.Simple_HTable
151 (Header_Num => Header_Num,
152 Element => Name_And_Index,
153 No_Element => No_Name_And_Index,
157 -- A table to check if a unit with an exceptional name will hide
158 -- a source with a file name following the naming convention.
162 Data : in out Project_Data;
163 In_Tree : Project_Tree_Ref);
164 -- Add a new source to the different lists: list of all sources in the
165 -- project tree, list of source of a project and list of sources of a
168 function ALI_File_Name (Source : String) return String;
169 -- Return the ALI file name corresponding to a source
171 procedure Check_Ada_Name (Name : String; Unit : out Name_Id);
172 -- Check that a name is a valid Ada unit name
174 procedure Check_Naming_Schemes
175 (Data : in out Project_Data;
176 Project : Project_Id;
177 In_Tree : Project_Tree_Ref);
178 -- Check the naming scheme part of Data
180 procedure Check_Ada_Naming_Scheme_Validity
181 (Project : Project_Id;
182 In_Tree : Project_Tree_Ref;
183 Naming : Naming_Data);
184 -- Check that the package Naming is correct
186 procedure Check_Configuration
187 (Project : Project_Id;
188 In_Tree : Project_Tree_Ref;
189 Data : in out Project_Data);
190 -- Check the configuration attributes for the project
192 procedure Check_For_Source
193 (File_Name : File_Name_Type;
194 Path_Name : Path_Name_Type;
195 Project : Project_Id;
196 In_Tree : Project_Tree_Ref;
197 Data : in out Project_Data;
198 Location : Source_Ptr;
199 Language : Language_Index;
201 Naming_Exception : Boolean);
202 -- Check if a file, with name File_Name and path Path_Name, in a source
203 -- directory is a source for language Language in project Project of
204 -- project tree In_Tree. ???
206 procedure Check_If_Externally_Built
207 (Project : Project_Id;
208 In_Tree : Project_Tree_Ref;
209 Data : in out Project_Data);
210 -- Check attribute Externally_Built of project Project in project tree
211 -- In_Tree and modify its data Data if it has the value "true".
213 procedure Check_Library_Attributes
214 (Project : Project_Id;
215 In_Tree : Project_Tree_Ref;
216 Data : in out Project_Data);
217 -- Check the library attributes of project Project in project tree In_Tree
218 -- and modify its data Data accordingly.
220 procedure Check_Package_Naming
221 (Project : Project_Id;
222 In_Tree : Project_Tree_Ref;
223 Data : in out Project_Data);
224 -- Check package Naming of project Project in project tree In_Tree and
225 -- modify its data Data accordingly.
227 procedure Check_Programming_Languages
228 (In_Tree : Project_Tree_Ref;
229 Project : Project_Id;
230 Data : in out Project_Data);
231 -- Check attribute Languages for the project with data Data in project
232 -- tree In_Tree and set the components of Data for all the programming
233 -- languages indicated in attribute Languages, if any.
235 function Check_Project
237 Root_Project : Project_Id;
238 In_Tree : Project_Tree_Ref;
239 Extending : Boolean) return Boolean;
240 -- Returns True if P is Root_Project or, if Extending is True, a project
241 -- extended by Root_Project.
243 procedure Check_Stand_Alone_Library
244 (Project : Project_Id;
245 In_Tree : Project_Tree_Ref;
246 Data : in out Project_Data;
247 Extending : Boolean);
248 -- Check if project Project in project tree In_Tree is a Stand-Alone
249 -- Library project, and modify its data Data accordingly if it is one.
251 function Compute_Directory_Last (Dir : String) return Natural;
252 -- Return the index of the last significant character in Dir. This is used
253 -- to avoid duplicates '/' at the end of directory names
256 (Project : Project_Id;
257 In_Tree : Project_Tree_Ref;
259 Flag_Location : Source_Ptr);
260 -- Output an error message. If Error_Report is null, simply call
261 -- Prj.Err.Error_Msg. Otherwise, disregard Flag_Location and use
264 procedure Find_Ada_Sources
265 (Project : Project_Id;
266 In_Tree : Project_Tree_Ref;
267 Data : in out Project_Data;
268 Follow_Links : Boolean := False);
269 -- Find all the Ada sources in all of the source directories of a project
271 procedure Find_Sources
272 (Project : Project_Id;
273 In_Tree : Project_Tree_Ref;
274 Data : in out Project_Data;
275 For_Language : Language_Index;
276 Follow_Links : Boolean := False);
277 -- Find all the sources in all of the source directories of a project for
278 -- a specified language.
280 procedure Free_Ada_Naming_Exceptions;
281 -- Free the internal hash tables used for checking naming exceptions
283 procedure Get_Directories
284 (Project : Project_Id;
285 In_Tree : Project_Tree_Ref;
286 Data : in out Project_Data);
287 -- Get the object directory, the exec directory and the source directories
291 (Project : Project_Id;
292 In_Tree : Project_Tree_Ref;
293 Data : in out Project_Data);
294 -- Get the mains of a project from attribute Main, if it exists, and put
295 -- them in the project data.
297 procedure Get_Sources_From_File
299 Location : Source_Ptr;
300 Project : Project_Id;
301 In_Tree : Project_Tree_Ref);
302 -- Get the list of sources from a text file and put them in hash table
306 (In_Tree : Project_Tree_Ref;
307 Canonical_File_Name : File_Name_Type;
308 Naming : Naming_Data;
309 Exception_Id : out Ada_Naming_Exception_Id;
310 Unit_Name : out Name_Id;
311 Unit_Kind : out Spec_Or_Body;
312 Needs_Pragma : out Boolean);
313 -- Find out, from a file name, the unit name, the unit kind and if a
314 -- specific SFN pragma is needed. If the file name corresponds to no
315 -- unit, then Unit_Name will be No_Name. If the file is a multi-unit source
316 -- or an exception to the naming scheme, then Exception_Id is set to
317 -- the unit or units that the source contains.
319 function Is_Illegal_Suffix
321 Dot_Replacement_Is_A_Single_Dot : Boolean) return Boolean;
322 -- Returns True if the string Suffix cannot be used as
323 -- a spec suffix, a body suffix or a separate suffix.
325 procedure Locate_Directory
326 (Project : Project_Id;
327 In_Tree : Project_Tree_Ref;
328 Name : File_Name_Type;
329 Parent : Path_Name_Type;
330 Dir : out Path_Name_Type;
331 Display : out Path_Name_Type;
332 Create : String := "";
333 Location : Source_Ptr := No_Location);
334 -- Locate a directory. Name is the directory name. Parent is the root
335 -- directory, if Name a relative path name. Dir is set to the canonical
336 -- case path name of the directory, and Display is the directory path name
337 -- for display purposes. If the directory does not exist and Project_Setup
338 -- is True and Create is a non null string, an attempt is made to create
339 -- the directory. If the directory does not exist and Project_Setup is
340 -- false, then Dir and Display are set to No_Name.
342 procedure Look_For_Sources
343 (Project : Project_Id;
344 In_Tree : Project_Tree_Ref;
345 Data : in out Project_Data;
346 Follow_Links : Boolean);
347 -- Find all the sources of project Project in project tree In_Tree and
348 -- update its Data accordingly. Resolve symbolic links in the path names
349 -- if Follow_Links is True.
351 function Path_Name_Of
352 (File_Name : File_Name_Type;
353 Directory : Path_Name_Type) return String;
354 -- Returns the path name of a (non project) file.
355 -- Returns an empty string if file cannot be found.
357 procedure Prepare_Ada_Naming_Exceptions
358 (List : Array_Element_Id;
359 In_Tree : Project_Tree_Ref;
360 Kind : Spec_Or_Body);
361 -- Prepare the internal hash tables used for checking naming exceptions
362 -- for Ada. Insert all elements of List in the tables.
364 function Project_Extends
365 (Extending : Project_Id;
366 Extended : Project_Id;
367 In_Tree : Project_Tree_Ref) return Boolean;
368 -- Returns True if Extending is extending Extended either directly or
371 procedure Record_Ada_Source
372 (File_Name : File_Name_Type;
373 Path_Name : Path_Name_Type;
374 Project : Project_Id;
375 In_Tree : Project_Tree_Ref;
376 Data : in out Project_Data;
377 Location : Source_Ptr;
378 Current_Source : in out String_List_Id;
379 Source_Recorded : in out Boolean;
380 Follow_Links : Boolean);
381 -- Put a unit in the list of units of a project, if the file name
382 -- corresponds to a valid unit name.
384 procedure Record_Other_Sources
385 (Project : Project_Id;
386 In_Tree : Project_Tree_Ref;
387 Data : in out Project_Data;
388 Language : Language_Index;
389 Naming_Exceptions : Boolean);
390 -- Record the sources of a language in a project.
391 -- When Naming_Exceptions is True, mark the found sources as such, to
392 -- later remove those that are not named in a list of sources.
394 procedure Remove_Source
396 Replaced_By : Source_Id;
397 Project : Project_Id;
398 Data : in out Project_Data;
399 In_Tree : Project_Tree_Ref);
401 procedure Report_No_Sources
402 (Project : Project_Id;
404 In_Tree : Project_Tree_Ref;
405 Location : Source_Ptr);
406 -- Report an error or a warning depending on the value of When_No_Sources
407 -- when there are no sources for language Lang_Name.
409 procedure Show_Source_Dirs
410 (Data : Project_Data; In_Tree : Project_Tree_Ref);
411 -- List all the source directories of a project
414 (Language : Language_Index;
415 Naming : Naming_Data;
416 In_Tree : Project_Tree_Ref) return File_Name_Type;
417 -- Get the suffix for the source of a language from a package naming.
418 -- If not specified, return the default for the language.
420 procedure Warn_If_Not_Sources
421 (Project : Project_Id;
422 In_Tree : Project_Tree_Ref;
423 Conventions : Array_Element_Id;
425 Extending : Boolean);
426 -- Check that individual naming conventions apply to immediate
427 -- sources of the project; if not, issue a warning.
435 Data : in out Project_Data;
436 In_Tree : Project_Tree_Ref)
438 Language : constant Language_Index :=
439 In_Tree.Sources.Table (Id).Language;
444 -- Add the source to the global list
446 In_Tree.Sources.Table (Id).Next_In_Sources := In_Tree.First_Source;
447 In_Tree.First_Source := Id;
449 -- Add the source to the project list
451 Source := Data.Last_Source;
453 if Source = No_Source then
454 Data.First_Source := Id;
456 In_Tree.Sources.Table (Source).Next_In_Project := Id;
459 Data.Last_Source := Id;
461 -- Add the source to the language list
463 In_Tree.Sources.Table (Id).Next_In_Lang :=
464 In_Tree.Languages_Data.Table (Language).First_Source;
465 In_Tree.Languages_Data.Table (Language).First_Source := Id;
472 function ALI_File_Name (Source : String) return String is
474 -- If the source name has an extension, then replace it with
477 for Index in reverse Source'First + 1 .. Source'Last loop
478 if Source (Index) = '.' then
479 return Source (Source'First .. Index - 1) & ALI_Suffix;
483 -- If there is no dot, or if it is the first character, just add the
486 return Source & ALI_Suffix;
494 (Project : Project_Id;
495 In_Tree : Project_Tree_Ref;
496 Report_Error : Put_Line_Access;
497 Follow_Links : Boolean;
498 When_No_Sources : Error_Warning)
500 Data : Project_Data := In_Tree.Projects.Table (Project);
501 Extending : Boolean := False;
503 Lang_Proc_Pkg : Package_Id;
504 Linker_Name : Variable_Value;
507 Nmsc.When_No_Sources := When_No_Sources;
508 Error_Report := Report_Error;
510 Recursive_Dirs.Reset;
512 Check_If_Externally_Built (Project, In_Tree, Data);
514 -- Object, exec and source directories
516 Get_Directories (Project, In_Tree, Data);
518 -- Get the programming languages
520 Check_Programming_Languages (In_Tree, Project, Data);
522 -- Check configuration in multi language mode
524 if Get_Mode = Multi_Language then
525 Check_Configuration (Project, In_Tree, Data);
528 -- Library attributes
530 Check_Library_Attributes (Project, In_Tree, Data);
532 if Current_Verbosity = High then
533 Show_Source_Dirs (Data, In_Tree);
536 Check_Package_Naming (Project, In_Tree, Data);
538 Extending := Data.Extends /= No_Project;
540 Check_Naming_Schemes (Data, Project, In_Tree);
542 if Get_Mode = Ada_Only then
543 Prepare_Ada_Naming_Exceptions
544 (Data.Naming.Bodies, In_Tree, Body_Part);
545 Prepare_Ada_Naming_Exceptions
546 (Data.Naming.Specs, In_Tree, Specification);
551 if Data.Source_Dirs /= Nil_String then
552 Look_For_Sources (Project, In_Tree, Data, Follow_Links);
554 if Get_Mode = Ada_Only then
556 -- Check that all individual naming conventions apply to sources
557 -- of this project file.
560 (Project, In_Tree, Data.Naming.Bodies,
562 Extending => Extending);
564 (Project, In_Tree, Data.Naming.Specs,
566 Extending => Extending);
568 elsif Get_Mode = Multi_Language and then
569 (not Data.Externally_Built) and then
573 Language : Language_Index;
575 Src_Data : Source_Data;
576 Alt_Lang : Alternate_Language_Id;
577 Alt_Lang_Data : Alternate_Language_Data;
580 Language := Data.First_Language_Processing;
581 while Language /= No_Language_Index loop
582 Source := Data.First_Source;
583 Source_Loop : while Source /= No_Source loop
584 Src_Data := In_Tree.Sources.Table (Source);
586 exit Source_Loop when Src_Data.Language = Language;
588 Alt_Lang := Src_Data.Alternate_Languages;
591 while Alt_Lang /= No_Alternate_Language loop
593 In_Tree.Alt_Langs.Table (Alt_Lang);
595 when Alt_Lang_Data.Language = Language;
596 Alt_Lang := Alt_Lang_Data.Next;
597 end loop Alternate_Loop;
599 Source := Src_Data.Next_In_Project;
600 end loop Source_Loop;
602 if Source = No_Source then
606 (In_Tree.Languages_Data.Table
607 (Language).Display_Name),
612 Language := In_Tree.Languages_Data.Table (Language).Next;
618 -- If it is a library project file, check if it is a standalone library
621 Check_Stand_Alone_Library (Project, In_Tree, Data, Extending);
624 -- Put the list of Mains, if any, in the project data
626 Get_Mains (Project, In_Tree, Data);
628 -- In multi-language mode, check if there is a linker specified
630 if Get_Mode = Multi_Language then
632 Value_Of (Name_Language_Processing, Data.Decl.Packages, In_Tree);
634 if Lang_Proc_Pkg /= No_Package then
637 (Variable_Name => Name_Linker,
639 In_Tree.Packages.Table (Lang_Proc_Pkg).Decl.Attributes,
642 if Linker_Name /= Nil_Variable_Value then
643 Get_Name_String (Linker_Name.Value);
646 -- A non empty linker name was specified
648 Data.Linker_Name := File_Name_Type (Linker_Name.Value);
655 -- Update the project data in the Projects table
657 In_Tree.Projects.Table (Project) := Data;
659 Free_Ada_Naming_Exceptions;
666 procedure Check_Ada_Name (Name : String; Unit : out Name_Id) is
667 The_Name : String := Name;
669 Need_Letter : Boolean := True;
670 Last_Underscore : Boolean := False;
671 OK : Boolean := The_Name'Length > 0;
676 Name_Len := The_Name'Length;
677 Name_Buffer (1 .. Name_Len) := The_Name;
679 -- Special cases of children of packages A, G, I and S on VMS
681 if OpenVMS_On_Target and then
682 Name_Len > 3 and then
683 Name_Buffer (2 .. 3) = "__" and then
684 ((Name_Buffer (1) = 'a') or else (Name_Buffer (1) = 'g') or else
685 (Name_Buffer (1) = 'i') or else (Name_Buffer (1) = 's'))
687 Name_Buffer (2) := '.';
688 Name_Buffer (3 .. Name_Len - 1) := Name_Buffer (4 .. Name_Len);
689 Name_Len := Name_Len - 1;
692 Real_Name := Name_Find;
694 -- Check first that the given name is not an Ada 95 reserved word. The
695 -- reason for the Ada 95 here is that we do not want to exclude the case
696 -- of an Ada 95 unit called Interface (for example). In Ada 2005, such
697 -- a unit name would be rejected anyway by the compiler, so there is no
698 -- requirement that the project file parser reject this.
700 if Get_Name_Table_Byte (Real_Name) /= 0
701 and then Real_Name /= Name_Project
702 and then Real_Name /= Name_Extends
703 and then Real_Name /= Name_External
704 and then Real_Name not in Ada_2005_Reserved_Words
708 if Current_Verbosity = High then
709 Write_Str (The_Name);
710 Write_Line (" is an Ada reserved word.");
716 for Index in The_Name'Range loop
719 -- We need a letter (at the beginning, and following a dot),
720 -- but we don't have one.
722 if Is_Letter (The_Name (Index)) then
723 Need_Letter := False;
728 if Current_Verbosity = High then
729 Write_Int (Types.Int (Index));
731 Write_Char (The_Name (Index));
732 Write_Line ("' is not a letter.");
738 elsif Last_Underscore
739 and then (The_Name (Index) = '_' or else The_Name (Index) = '.')
741 -- Two underscores are illegal, and a dot cannot follow
746 if Current_Verbosity = High then
747 Write_Int (Types.Int (Index));
749 Write_Char (The_Name (Index));
750 Write_Line ("' is illegal here.");
755 elsif The_Name (Index) = '.' then
757 -- We need a letter after a dot
761 elsif The_Name (Index) = '_' then
762 Last_Underscore := True;
765 -- We need an letter or a digit
767 Last_Underscore := False;
769 if not Is_Alphanumeric (The_Name (Index)) then
772 if Current_Verbosity = High then
773 Write_Int (Types.Int (Index));
775 Write_Char (The_Name (Index));
776 Write_Line ("' is not alphanumeric.");
784 -- Cannot end with an underscore or a dot
786 OK := OK and then not Need_Letter and then not Last_Underscore;
792 -- Signal a problem with No_Name
798 --------------------------------------
799 -- Check_Ada_Naming_Scheme_Validity --
800 --------------------------------------
802 procedure Check_Ada_Naming_Scheme_Validity
803 (Project : Project_Id;
804 In_Tree : Project_Tree_Ref;
805 Naming : Naming_Data)
808 -- Only check if we are not using the Default naming scheme
810 if Naming /= In_Tree.Private_Part.Default_Naming then
812 Dot_Replacement : constant String :=
814 (Naming.Dot_Replacement);
816 Spec_Suffix : constant String :=
817 Spec_Suffix_Of (In_Tree, "ada", Naming);
819 Body_Suffix : constant String :=
820 Body_Suffix_Of (In_Tree, "ada", Naming);
822 Separate_Suffix : constant String :=
824 (Naming.Separate_Suffix);
827 -- Dot_Replacement cannot
829 -- - start or end with an alphanumeric
831 -- - start with an '_' followed by an alphanumeric
832 -- - contain a '.' except if it is "."
834 if Dot_Replacement'Length = 0
835 or else Is_Alphanumeric
836 (Dot_Replacement (Dot_Replacement'First))
837 or else Is_Alphanumeric
838 (Dot_Replacement (Dot_Replacement'Last))
839 or else (Dot_Replacement (Dot_Replacement'First) = '_'
841 (Dot_Replacement'Length = 1
844 (Dot_Replacement (Dot_Replacement'First + 1))))
845 or else (Dot_Replacement'Length > 1
847 Index (Source => Dot_Replacement,
848 Pattern => ".") /= 0)
852 '"' & Dot_Replacement &
853 """ is illegal for Dot_Replacement.",
854 Naming.Dot_Repl_Loc);
861 (Spec_Suffix, Dot_Replacement = ".")
863 Err_Vars.Error_Msg_File_1 :=
864 Spec_Suffix_Id_Of (In_Tree, "ada", Naming);
867 "{ is illegal for Spec_Suffix",
868 Naming.Ada_Spec_Suffix_Loc);
872 (Body_Suffix, Dot_Replacement = ".")
874 Err_Vars.Error_Msg_File_1 :=
875 Body_Suffix_Id_Of (In_Tree, "ada", Naming);
878 "{ is illegal for Body_Suffix",
879 Naming.Ada_Body_Suffix_Loc);
882 if Body_Suffix /= Separate_Suffix then
884 (Separate_Suffix, Dot_Replacement = ".")
886 Err_Vars.Error_Msg_File_1 := Naming.Separate_Suffix;
889 "{ is illegal for Separate_Suffix",
890 Naming.Sep_Suffix_Loc);
894 -- Spec_Suffix cannot have the same termination as
895 -- Body_Suffix or Separate_Suffix
897 if Spec_Suffix'Length <= Body_Suffix'Length
899 Body_Suffix (Body_Suffix'Last -
900 Spec_Suffix'Length + 1 ..
901 Body_Suffix'Last) = Spec_Suffix
907 """) cannot end with" &
909 Spec_Suffix & """).",
910 Naming.Ada_Body_Suffix_Loc);
913 if Body_Suffix /= Separate_Suffix
914 and then Spec_Suffix'Length <= Separate_Suffix'Length
917 (Separate_Suffix'Last - Spec_Suffix'Length + 1
919 Separate_Suffix'Last) = Spec_Suffix
923 "Separate_Suffix (""" &
925 """) cannot end with" &
927 Spec_Suffix & """).",
928 Naming.Sep_Suffix_Loc);
932 end Check_Ada_Naming_Scheme_Validity;
934 -------------------------
935 -- Check_Configuration --
936 -------------------------
938 procedure Check_Configuration
939 (Project : Project_Id;
940 In_Tree : Project_Tree_Ref;
941 Data : in out Project_Data)
943 Compiler_Pkg : constant Package_Id :=
944 Value_Of (Name_Compiler, Data.Decl.Packages, In_Tree);
945 Binder_Pkg : constant Package_Id :=
946 Value_Of (Name_Binder, Data.Decl.Packages, In_Tree);
947 Element : Package_Element;
950 Current_Array : Array_Data;
951 Arr_Elmt_Id : Array_Element_Id;
952 Arr_Element : Array_Element;
953 List : String_List_Id;
955 Current_Language_Index : Language_Index;
957 procedure Get_Language (Name : Name_Id);
958 -- Check if this is the name of a language of the project and
959 -- set Current_Language_Index accordingly.
965 procedure Get_Language (Name : Name_Id) is
966 Real_Language : Name_Id;
969 Get_Name_String (Name);
970 To_Lower (Name_Buffer (1 .. Name_Len));
971 Real_Language := Name_Find;
973 Current_Language_Index := Data.First_Language_Processing;
975 exit when Current_Language_Index = No_Language_Index or else
976 In_Tree.Languages_Data.Table (Current_Language_Index).Name =
978 Current_Language_Index :=
979 In_Tree.Languages_Data.Table (Current_Language_Index).Next;
983 -- Start of processing for Check_Configuration
986 if Compiler_Pkg /= No_Package then
987 Element := In_Tree.Packages.Table (Compiler_Pkg);
989 Arrays := Element.Decl.Arrays;
990 while Arrays /= No_Array loop
991 Current_Array := In_Tree.Arrays.Table (Arrays);
993 Arr_Elmt_Id := Current_Array.Value;
994 while Arr_Elmt_Id /= No_Array_Element loop
995 Arr_Element := In_Tree.Array_Elements.Table (Arr_Elmt_Id);
996 Get_Language (Arr_Element.Index);
998 if Current_Language_Index /= No_Language_Index then
999 case Current_Array.Name is
1000 when Name_Dependency_Switches =>
1001 List := Arr_Element.Value.Values;
1003 if List = Nil_String then
1006 "dependency option cannot be null",
1007 Arr_Element.Value.Location);
1011 In_Tree.Languages_Data.Table
1012 (Current_Language_Index)
1013 .Config.Dependency_Option,
1015 In_Tree => In_Tree);
1017 when Name_Dependency_Driver =>
1019 -- Attribute Dependency_Driver (<language>)
1021 List := Arr_Element.Value.Values;
1023 if List = Nil_String then
1026 "compute dependency cannot be null",
1027 Arr_Element.Value.Location);
1031 In_Tree.Languages_Data.Table
1032 (Current_Language_Index)
1033 .Config.Compute_Dependency,
1035 In_Tree => In_Tree);
1037 when Name_Include_Option =>
1039 -- Attribute Include_Option (<language>)
1041 List := Arr_Element.Value.Values;
1043 if List = Nil_String then
1046 "include option cannot be null",
1047 Arr_Element.Value.Location);
1051 In_Tree.Languages_Data.Table
1052 (Current_Language_Index).Config.Include_Option,
1054 In_Tree => In_Tree);
1056 when Name_Include_Path =>
1058 -- Attribute Include_Path (<language>)
1060 In_Tree.Languages_Data.Table
1061 (Current_Language_Index).Config.Include_Path :=
1062 Arr_Element.Value.Value;
1064 when Name_Include_Path_File =>
1066 -- Attribute Include_Path_File (<language>)
1068 In_Tree.Languages_Data.Table
1069 (Current_Language_Index).Config.Include_Path_File :=
1070 Arr_Element.Value.Value;
1074 -- Attribute Driver (<language>)
1076 Get_Name_String (Arr_Element.Value.Value);
1078 if Name_Len = 0 then
1081 "compiler driver name cannot be empty",
1082 Arr_Element.Value.Location);
1085 In_Tree.Languages_Data.Table
1086 (Current_Language_Index).Config.Compiler_Driver :=
1087 File_Name_Type (Arr_Element.Value.Value);
1089 when Name_Switches =>
1091 -- Attribute Minimum_Compiler_Options (<language>)
1093 List := Arr_Element.Value.Values;
1096 In_Tree.Languages_Data.Table
1097 (Current_Language_Index).Config.
1098 Compiler_Min_Options,
1100 In_Tree => In_Tree);
1102 when Name_Pic_Option =>
1104 -- Attribute Pic_Option (<language>)
1106 List := Arr_Element.Value.Values;
1108 if List = Nil_String then
1111 "compiler PIC option cannot be null",
1112 Arr_Element.Value.Location);
1116 In_Tree.Languages_Data.Table
1117 (Current_Language_Index).Config.
1118 Compilation_PIC_Option,
1120 In_Tree => In_Tree);
1122 when Name_Mapping_File_Switches =>
1124 -- Attribute Mapping_File_Switches (<language>)
1126 List := Arr_Element.Value.Values;
1128 if List = Nil_String then
1131 "mapping file switches cannot be null",
1132 Arr_Element.Value.Location);
1136 In_Tree.Languages_Data.Table
1137 (Current_Language_Index).Config.
1138 Mapping_File_Switches,
1140 In_Tree => In_Tree);
1142 when Name_Mapping_Spec_Suffix =>
1144 -- Attribute Mapping_Spec_Suffix (<language>)
1146 In_Tree.Languages_Data.Table
1147 (Current_Language_Index)
1148 .Config.Mapping_Spec_Suffix :=
1149 File_Name_Type (Arr_Element.Value.Value);
1151 when Name_Mapping_Body_Suffix =>
1153 -- Attribute Mapping_Body_Suffix (<language>)
1155 In_Tree.Languages_Data.Table
1156 (Current_Language_Index)
1157 .Config.Mapping_Body_Suffix :=
1158 File_Name_Type (Arr_Element.Value.Value);
1160 when Name_Config_File_Switches =>
1162 -- Attribute Config_File_Switches (<language>)
1164 List := Arr_Element.Value.Values;
1166 if List = Nil_String then
1169 "config file switches cannot be null",
1170 Arr_Element.Value.Location);
1174 In_Tree.Languages_Data.Table
1175 (Current_Language_Index).Config.
1176 Config_File_Switches,
1178 In_Tree => In_Tree);
1180 when Name_Config_Body_File_Name =>
1182 -- Attribute Config_Body_File_Name (<language>)
1184 In_Tree.Languages_Data.Table
1185 (Current_Language_Index).Config.Config_Body :=
1186 Arr_Element.Value.Value;
1188 when Name_Config_Body_File_Name_Pattern =>
1190 -- Attribute Config_Body_File_Name_Pattern
1193 In_Tree.Languages_Data.Table
1194 (Current_Language_Index)
1195 .Config.Config_Body_Pattern :=
1196 Arr_Element.Value.Value;
1198 when Name_Config_Spec_File_Name =>
1200 -- Attribute Config_Spec_File_Name (<language>)
1202 In_Tree.Languages_Data.Table
1203 (Current_Language_Index).Config.Config_Spec :=
1204 Arr_Element.Value.Value;
1206 when Name_Config_Spec_File_Name_Pattern =>
1208 -- Attribute Config_Spec_File_Name_Pattern
1211 In_Tree.Languages_Data.Table
1212 (Current_Language_Index)
1213 .Config.Config_Spec_Pattern :=
1214 Arr_Element.Value.Value;
1216 when Name_Config_File_Unique =>
1218 -- Attribute Config_File_Unique (<language>)
1221 In_Tree.Languages_Data.Table
1222 (Current_Language_Index)
1223 .Config.Config_File_Unique :=
1225 (Get_Name_String (Arr_Element.Value.Value));
1227 when Constraint_Error =>
1230 "illegal value gor Config_File_Unique",
1231 Arr_Element.Value.Location);
1239 Arr_Elmt_Id := Arr_Element.Next;
1242 Arrays := Current_Array.Next;
1246 -- Comment needed here ???
1248 if Binder_Pkg /= No_Package then
1249 Element := In_Tree.Packages.Table (Binder_Pkg);
1250 Arrays := Element.Decl.Arrays;
1251 while Arrays /= No_Array loop
1252 Current_Array := In_Tree.Arrays.Table (Arrays);
1254 Arr_Elmt_Id := Current_Array.Value;
1255 while Arr_Elmt_Id /= No_Array_Element loop
1256 Arr_Element := In_Tree.Array_Elements.Table (Arr_Elmt_Id);
1258 Get_Language (Arr_Element.Index);
1260 if Current_Language_Index /= No_Language_Index then
1261 case Current_Array.Name is
1264 -- Attribute Driver (<language>)
1266 In_Tree.Languages_Data.Table
1267 (Current_Language_Index).Config.Binder_Driver :=
1268 File_Name_Type (Arr_Element.Value.Value);
1270 when Name_Objects_Path =>
1272 -- Attribute Objects_Path (<language>)
1274 In_Tree.Languages_Data.Table
1275 (Current_Language_Index).Config.Objects_Path :=
1276 Arr_Element.Value.Value;
1278 when Name_Objects_Path_File =>
1280 -- Attribute Objects_Path_File (<language>)
1282 In_Tree.Languages_Data.Table
1283 (Current_Language_Index).Config.Objects_Path_File :=
1284 Arr_Element.Value.Value;
1288 -- Attribute Prefix (<language>)
1290 In_Tree.Languages_Data.Table
1291 (Current_Language_Index).Config.Binder_Prefix :=
1292 Arr_Element.Value.Value;
1299 Arr_Elmt_Id := Arr_Element.Next;
1302 Arrays := Current_Array.Next;
1305 end Check_Configuration;
1307 ----------------------
1308 -- Check_For_Source --
1309 ----------------------
1311 procedure Check_For_Source
1312 (File_Name : File_Name_Type;
1313 Path_Name : Path_Name_Type;
1314 Project : Project_Id;
1315 In_Tree : Project_Tree_Ref;
1316 Data : in out Project_Data;
1317 Location : Source_Ptr;
1318 Language : Language_Index;
1320 Naming_Exception : Boolean)
1322 Name : String := Get_Name_String (File_Name);
1323 Real_Location : Source_Ptr := Location;
1326 Canonical_Case_File_Name (Name);
1328 -- A file is a source of a language if Naming_Exception is True (case
1329 -- of naming exceptions) or if its file name ends with the suffix.
1333 (Name'Length > Suffix'Length
1335 Name (Name'Last - Suffix'Length + 1 .. Name'Last) = Suffix)
1337 if Real_Location = No_Location then
1338 Real_Location := Data.Location;
1342 Path : constant String := Get_Name_String (Path_Name);
1343 C_Path : String := Path;
1345 Path_Id : Path_Name_Type;
1346 C_Path_Id : Path_Name_Type;
1347 -- The path name id (in canonical case)
1349 File_Id : File_Name_Type;
1350 -- The file name id (in canonical case)
1352 Obj_Id : File_Name_Type;
1353 -- The object file name
1355 Obj_Path_Id : Path_Name_Type;
1356 -- The object path name
1358 Dep_Id : File_Name_Type;
1359 -- The dependency file name
1361 Dep_Path_Id : Path_Name_Type;
1362 -- The dependency path name
1364 Dot_Pos : Natural := 0;
1365 -- Position of the last dot in Name
1367 Source : Other_Source;
1368 Source_Id : Other_Source_Id := Data.First_Other_Source;
1371 Canonical_Case_File_Name (C_Path);
1373 -- Get the file name id
1375 Name_Len := Name'Length;
1376 Name_Buffer (1 .. Name_Len) := Name;
1377 File_Id := Name_Find;
1379 -- Get the path name id
1381 Name_Len := Path'Length;
1382 Name_Buffer (1 .. Name_Len) := Path;
1383 Path_Id := Name_Find;
1385 Name_Len := C_Path'Length;
1386 Name_Buffer (1 .. Name_Len) := C_Path;
1387 C_Path_Id := Name_Find;
1389 -- Find the position of the last dot
1391 for J in reverse Name'Range loop
1392 if Name (J) = '.' then
1398 if Dot_Pos <= Name'First then
1399 Dot_Pos := Name'Last + 1;
1402 -- Compute the object file name
1404 Get_Name_String (File_Id);
1405 Name_Len := Dot_Pos - Name'First;
1407 for J in Object_Suffix'Range loop
1408 Name_Len := Name_Len + 1;
1409 Name_Buffer (Name_Len) := Object_Suffix (J);
1412 Obj_Id := Name_Find;
1414 -- Compute the object path name
1416 Get_Name_String (Data.Display_Object_Dir);
1418 if Name_Buffer (Name_Len) /= Directory_Separator
1419 and then Name_Buffer (Name_Len) /= '/'
1421 Name_Len := Name_Len + 1;
1422 Name_Buffer (Name_Len) := Directory_Separator;
1425 Add_Str_To_Name_Buffer (Get_Name_String (Obj_Id));
1426 Obj_Path_Id := Name_Find;
1428 -- Compute the dependency file name
1430 Get_Name_String (File_Id);
1431 Name_Len := Dot_Pos - Name'First + 1;
1432 Name_Buffer (Name_Len) := '.';
1433 Name_Len := Name_Len + 1;
1434 Name_Buffer (Name_Len) := 'd';
1435 Dep_Id := Name_Find;
1437 -- Compute the dependency path name
1439 Get_Name_String (Data.Display_Object_Dir);
1441 if Name_Buffer (Name_Len) /= Directory_Separator
1442 and then Name_Buffer (Name_Len) /= '/'
1444 Name_Len := Name_Len + 1;
1445 Name_Buffer (Name_Len) := Directory_Separator;
1448 Add_Str_To_Name_Buffer (Get_Name_String (Dep_Id));
1449 Dep_Path_Id := Name_Find;
1451 -- Check if source is already in the list of source for this
1452 -- project: it may have already been specified as a naming
1453 -- exception for the same language or an other language, or
1454 -- they may be two identical file names in different source
1457 while Source_Id /= No_Other_Source loop
1458 Source := In_Tree.Other_Sources.Table (Source_Id);
1460 if Source.File_Name = File_Id then
1462 -- Two sources of different languages cannot have the same
1465 if Source.Language /= Language then
1466 Error_Msg_File_1 := File_Name;
1469 "{ cannot be a source of several languages",
1473 -- No problem if a file has already been specified as
1474 -- a naming exception of this language.
1476 elsif Source.Path_Name = C_Path_Id then
1478 -- Reset the naming exception flag, if this is not a
1479 -- naming exception.
1481 if not Naming_Exception then
1482 In_Tree.Other_Sources.Table
1483 (Source_Id).Naming_Exception := False;
1488 -- There are several files with the same names, but the
1489 -- order of the source directories is known (no /**):
1490 -- only the first one encountered is kept, the other ones
1493 elsif Data.Known_Order_Of_Source_Dirs then
1496 -- But it is an error if the order of the source directories
1500 Error_Msg_File_1 := File_Name;
1503 "{ is found in several source directories",
1508 -- Two sources with different file names cannot have the same
1509 -- object file name.
1511 elsif Source.Object_Name = Obj_Id then
1512 Error_Msg_File_1 := File_Id;
1513 Error_Msg_File_2 := Source.File_Name;
1514 Error_Msg_File_3 := Obj_Id;
1517 "{ and { have the same object file {",
1522 Source_Id := Source.Next;
1525 if Current_Verbosity = High then
1526 Write_Str (" found ");
1527 Display_Language_Name (Language);
1528 Write_Str (" source """);
1529 Write_Str (Get_Name_String (File_Name));
1531 Write_Str (" object path = ");
1532 Write_Line (Get_Name_String (Obj_Path_Id));
1535 -- Create the Other_Source record
1538 (Language => Language,
1539 File_Name => File_Id,
1540 Path_Name => Path_Id,
1541 Source_TS => File_Stamp (Path_Id),
1542 Object_Name => Obj_Id,
1543 Object_Path => Obj_Path_Id,
1544 Object_TS => File_Stamp (Obj_Path_Id),
1546 Dep_Path => Dep_Path_Id,
1547 Dep_TS => File_Stamp (Dep_Path_Id),
1548 Naming_Exception => Naming_Exception,
1549 Next => No_Other_Source);
1551 -- And add it to the Other_Sources table
1553 Other_Source_Table.Increment_Last (In_Tree.Other_Sources);
1554 In_Tree.Other_Sources.Table
1555 (Other_Source_Table.Last (In_Tree.Other_Sources)) := Source;
1557 -- There are sources of languages other than Ada in this project
1559 Data.Other_Sources_Present := True;
1561 -- And there are sources of this language in this project
1563 Set (Language, True, Data, In_Tree);
1565 -- Add this source to the list of sources of languages other than
1566 -- Ada of the project.
1568 if Data.First_Other_Source = No_Other_Source then
1569 Data.First_Other_Source :=
1570 Other_Source_Table.Last (In_Tree.Other_Sources);
1573 In_Tree.Other_Sources.Table (Data.Last_Other_Source).Next :=
1574 Other_Source_Table.Last (In_Tree.Other_Sources);
1577 Data.Last_Other_Source :=
1578 Other_Source_Table.Last (In_Tree.Other_Sources);
1581 end Check_For_Source;
1583 -------------------------------
1584 -- Check_If_Externally_Built --
1585 -------------------------------
1587 procedure Check_If_Externally_Built
1588 (Project : Project_Id;
1589 In_Tree : Project_Tree_Ref;
1590 Data : in out Project_Data)
1592 Externally_Built : constant Variable_Value :=
1594 (Name_Externally_Built,
1595 Data.Decl.Attributes, In_Tree);
1598 if not Externally_Built.Default then
1599 Get_Name_String (Externally_Built.Value);
1600 To_Lower (Name_Buffer (1 .. Name_Len));
1602 if Name_Buffer (1 .. Name_Len) = "true" then
1603 Data.Externally_Built := True;
1605 elsif Name_Buffer (1 .. Name_Len) /= "false" then
1606 Error_Msg (Project, In_Tree,
1607 "Externally_Built may only be true or false",
1608 Externally_Built.Location);
1612 if Current_Verbosity = High then
1613 Write_Str ("Project is ");
1615 if not Data.Externally_Built then
1619 Write_Line ("externally built.");
1621 end Check_If_Externally_Built;
1623 -----------------------------
1624 -- Check_Naming_Schemes --
1625 -----------------------------
1627 procedure Check_Naming_Schemes
1628 (Data : in out Project_Data;
1629 Project : Project_Id;
1630 In_Tree : Project_Tree_Ref)
1632 Naming_Id : constant Package_Id :=
1633 Util.Value_Of (Name_Naming, Data.Decl.Packages, In_Tree);
1634 Naming : Package_Element;
1636 procedure Check_Unit_Names (List : Array_Element_Id);
1637 -- Check that a list of unit names contains only valid names
1639 procedure Get_Exceptions (Kind : Source_Kind);
1641 procedure Get_Unit_Exceptions (Kind : Source_Kind);
1643 ----------------------
1644 -- Check_Unit_Names --
1645 ----------------------
1647 procedure Check_Unit_Names (List : Array_Element_Id) is
1648 Current : Array_Element_Id;
1649 Element : Array_Element;
1650 Unit_Name : Name_Id;
1653 -- Loop through elements of the string list
1656 while Current /= No_Array_Element loop
1657 Element := In_Tree.Array_Elements.Table (Current);
1659 -- Put file name in canonical case
1661 Get_Name_String (Element.Value.Value);
1662 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
1663 Element.Value.Value := Name_Find;
1665 -- Check that it contains a valid unit name
1667 Get_Name_String (Element.Index);
1668 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit_Name);
1670 if Unit_Name = No_Name then
1671 Err_Vars.Error_Msg_Name_1 := Element.Index;
1674 "%% is not a valid unit name.",
1675 Element.Value.Location);
1678 if Current_Verbosity = High then
1679 Write_Str (" Unit (""");
1680 Write_Str (Get_Name_String (Unit_Name));
1684 Element.Index := Unit_Name;
1685 In_Tree.Array_Elements.Table (Current) := Element;
1688 Current := Element.Next;
1690 end Check_Unit_Names;
1692 --------------------
1693 -- Get_Exceptions --
1694 --------------------
1696 procedure Get_Exceptions (Kind : Source_Kind) is
1697 Exceptions : Array_Element_Id;
1698 Exception_List : Variable_Value;
1699 Element_Id : String_List_Id;
1700 Element : String_Element;
1701 File_Name : File_Name_Type;
1702 Lang_Id : Language_Index;
1710 (Name_Implementation_Exceptions,
1711 In_Arrays => Naming.Decl.Arrays,
1712 In_Tree => In_Tree);
1717 (Name_Specification_Exceptions,
1718 In_Arrays => Naming.Decl.Arrays,
1719 In_Tree => In_Tree);
1722 Lang_Id := Data.First_Language_Processing;
1723 while Lang_Id /= No_Language_Index loop
1724 if In_Tree.Languages_Data.Table (Lang_Id).Config.Kind =
1727 Lang := In_Tree.Languages_Data.Table (Lang_Id).Name;
1729 Exception_List := Value_Of
1731 In_Array => Exceptions,
1732 In_Tree => In_Tree);
1734 if Exception_List /= Nil_Variable_Value then
1735 Element_Id := Exception_List.Values;
1737 while Element_Id /= Nil_String loop
1739 In_Tree.String_Elements.Table (Element_Id);
1740 Get_Name_String (Element.Value);
1741 Canonical_Case_File_Name
1742 (Name_Buffer (1 .. Name_Len));
1743 File_Name := Name_Find;
1745 Source := Data.First_Source;
1746 while Source /= No_Source
1748 In_Tree.Sources.Table (Source).File /= File_Name
1751 In_Tree.Sources.Table (Source).Next_In_Project;
1754 if Source = No_Source then
1756 -- This is a new source. Create an entry for it
1757 -- in the Sources table.
1759 Source_Data_Table.Increment_Last (In_Tree.Sources);
1760 Source := Source_Data_Table.Last (In_Tree.Sources);
1762 if Current_Verbosity = High then
1763 Write_Str ("Adding source #");
1764 Write_Str (Source'Img);
1765 Write_Str (", File : ");
1766 Write_Line (Get_Name_String (File_Name));
1770 Src_Data : Source_Data := No_Source_Data;
1772 Src_Data.Project := Project;
1773 Src_Data.Language_Name := Lang;
1774 Src_Data.Language := Lang_Id;
1775 Src_Data.Kind := Kind;
1776 Src_Data.File := File_Name;
1777 Src_Data.Display_File :=
1778 File_Name_Type (Element.Value);
1779 Src_Data.Object := Object_Name (File_Name);
1780 Src_Data.Dependency :=
1781 In_Tree.Languages_Data.Table
1782 (Lang_Id).Config.Dependency_Kind;
1783 Src_Data.Dep_Name :=
1784 Dependency_Name (File_Name, Src_Data.Dependency);
1785 Src_Data.Switches := Switches_Name (File_Name);
1786 Src_Data.Naming_Exception := True;
1787 In_Tree.Sources.Table (Source) := Src_Data;
1790 Add_Source (Source, Data, In_Tree);
1793 -- Check if the file name is already recorded for
1794 -- another language or another kind.
1797 In_Tree.Sources.Table (Source).Language /= Lang_Id
1802 "the same file cannot be a source " &
1806 elsif In_Tree.Sources.Table (Source).Kind /= Kind then
1810 "the same file cannot be a source " &
1815 -- If the file is already recorded for the same
1816 -- language and the same kind, it means that the file
1817 -- name appears several times in the *_Exceptions
1818 -- attribute; so there is nothing to do.
1822 Element_Id := Element.Next;
1827 Lang_Id := In_Tree.Languages_Data.Table (Lang_Id).Next;
1831 -------------------------
1832 -- Get_Unit_Exceptions --
1833 -------------------------
1835 procedure Get_Unit_Exceptions (Kind : Source_Kind) is
1836 Exceptions : Array_Element_Id;
1837 Element : Array_Element;
1840 File_Name : File_Name_Type;
1841 Lang_Id : constant Language_Index :=
1842 Data.Unit_Based_Language_Index;
1843 Lang : constant Name_Id :=
1844 Data.Unit_Based_Language_Name;
1847 Source_To_Replace : Source_Id := No_Source;
1849 Other_Project : Project_Id;
1850 Other_Part : Source_Id;
1853 if Lang_Id = No_Language_Index or else Lang = No_Name then
1858 Exceptions := Value_Of
1860 In_Arrays => Naming.Decl.Arrays,
1861 In_Tree => In_Tree);
1863 if Exceptions = No_Array_Element then
1866 (Name_Implementation,
1867 In_Arrays => Naming.Decl.Arrays,
1868 In_Tree => In_Tree);
1875 In_Arrays => Naming.Decl.Arrays,
1876 In_Tree => In_Tree);
1878 if Exceptions = No_Array_Element then
1879 Exceptions := Value_Of
1880 (Name_Specification,
1881 In_Arrays => Naming.Decl.Arrays,
1882 In_Tree => In_Tree);
1887 while Exceptions /= No_Array_Element loop
1888 Element := In_Tree.Array_Elements.Table (Exceptions);
1890 Get_Name_String (Element.Value.Value);
1891 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
1892 File_Name := Name_Find;
1894 Get_Name_String (Element.Index);
1895 To_Lower (Name_Buffer (1 .. Name_Len));
1898 Index := Element.Value.Index;
1900 -- For Ada, check if it is a valid unit name
1902 if Lang = Name_Ada then
1903 Get_Name_String (Element.Index);
1904 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit);
1906 if Unit = No_Name then
1907 Err_Vars.Error_Msg_Name_1 := Element.Index;
1910 "%% is not a valid unit name.",
1911 Element.Value.Location);
1915 if Unit /= No_Name then
1917 -- Check if the source already exists
1919 Source := In_Tree.First_Source;
1920 Source_To_Replace := No_Source;
1922 while Source /= No_Source and then
1923 (In_Tree.Sources.Table (Source).Unit /= Unit or else
1924 In_Tree.Sources.Table (Source).Index /= Index)
1926 Source := In_Tree.Sources.Table (Source).Next_In_Sources;
1929 if Source /= No_Source then
1930 if In_Tree.Sources.Table (Source).Kind /= Kind then
1931 Other_Part := Source;
1935 In_Tree.Sources.Table (Source).Next_In_Sources;
1937 exit when Source = No_Source or else
1938 (In_Tree.Sources.Table (Source).Unit = Unit
1940 In_Tree.Sources.Table (Source).Index = Index);
1944 if Source /= No_Source then
1945 Other_Project := In_Tree.Sources.Table (Source).Project;
1947 if Is_Extending (Project, Other_Project, In_Tree) then
1949 In_Tree.Sources.Table (Source).Other_Part;
1951 -- Record the source to be removed
1953 Source_To_Replace := Source;
1954 Source := No_Source;
1957 Error_Msg_Name_1 := Unit;
1962 "unit%% cannot belong to two projects " &
1964 Element.Value.Location);
1969 if Source = No_Source then
1970 Source_Data_Table.Increment_Last (In_Tree.Sources);
1971 Source := Source_Data_Table.Last (In_Tree.Sources);
1973 if Current_Verbosity = High then
1974 Write_Str ("Adding source #");
1975 Write_Str (Source'Img);
1976 Write_Str (", File : ");
1977 Write_Str (Get_Name_String (File_Name));
1978 Write_Str (", Unit : ");
1979 Write_Line (Get_Name_String (Unit));
1983 Src_Data : Source_Data := No_Source_Data;
1986 Src_Data.Project := Project;
1987 Src_Data.Language_Name := Lang;
1988 Src_Data.Language := Lang_Id;
1989 Src_Data.Kind := Kind;
1990 Src_Data.Other_Part := Other_Part;
1991 Src_Data.Unit := Unit;
1992 Src_Data.Index := Index;
1993 Src_Data.File := File_Name;
1994 Src_Data.Object := Object_Name (File_Name);
1995 Src_Data.Display_File :=
1996 File_Name_Type (Element.Value.Value);
1997 Src_Data.Dependency := In_Tree.Languages_Data.Table
1998 (Lang_Id).Config.Dependency_Kind;
1999 Src_Data.Dep_Name :=
2000 Dependency_Name (File_Name, Src_Data.Dependency);
2001 Src_Data.Switches := Switches_Name (File_Name);
2002 Src_Data.Naming_Exception := True;
2003 In_Tree.Sources.Table (Source) := Src_Data;
2006 Add_Source (Source, Data, In_Tree);
2008 if Source_To_Replace /= No_Source then
2010 (Source_To_Replace, Source, Project, Data, In_Tree);
2015 Exceptions := Element.Next;
2018 end Get_Unit_Exceptions;
2020 -- Start of processing for Check_Naming_Schemes
2023 if Get_Mode = Ada_Only then
2025 -- If there is a package Naming, we will put in Data.Naming what is
2026 -- in this package Naming.
2028 if Naming_Id /= No_Package then
2029 Naming := In_Tree.Packages.Table (Naming_Id);
2031 if Current_Verbosity = High then
2032 Write_Line ("Checking ""Naming"" for Ada.");
2036 Bodies : constant Array_Element_Id :=
2038 (Name_Body, Naming.Decl.Arrays, In_Tree);
2040 Specs : constant Array_Element_Id :=
2042 (Name_Spec, Naming.Decl.Arrays, In_Tree);
2045 if Bodies /= No_Array_Element then
2047 -- We have elements in the array Body_Part
2049 if Current_Verbosity = High then
2050 Write_Line ("Found Bodies.");
2053 Data.Naming.Bodies := Bodies;
2054 Check_Unit_Names (Bodies);
2057 if Current_Verbosity = High then
2058 Write_Line ("No Bodies.");
2062 if Specs /= No_Array_Element then
2064 -- We have elements in the array Specs
2066 if Current_Verbosity = High then
2067 Write_Line ("Found Specs.");
2070 Data.Naming.Specs := Specs;
2071 Check_Unit_Names (Specs);
2074 if Current_Verbosity = High then
2075 Write_Line ("No Specs.");
2080 -- We are now checking if variables Dot_Replacement, Casing,
2081 -- Spec_Suffix, Body_Suffix and/or Separate_Suffix exist.
2083 -- For each variable, if it does not exist, we do nothing,
2084 -- because we already have the default.
2086 -- Check Dot_Replacement
2089 Dot_Replacement : constant Variable_Value :=
2091 (Name_Dot_Replacement,
2092 Naming.Decl.Attributes, In_Tree);
2095 pragma Assert (Dot_Replacement.Kind = Single,
2096 "Dot_Replacement is not a single string");
2098 if not Dot_Replacement.Default then
2099 Get_Name_String (Dot_Replacement.Value);
2101 if Name_Len = 0 then
2104 "Dot_Replacement cannot be empty",
2105 Dot_Replacement.Location);
2108 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2109 Data.Naming.Dot_Replacement := Name_Find;
2110 Data.Naming.Dot_Repl_Loc := Dot_Replacement.Location;
2115 if Current_Verbosity = High then
2116 Write_Str (" Dot_Replacement = """);
2117 Write_Str (Get_Name_String (Data.Naming.Dot_Replacement));
2125 Casing_String : constant Variable_Value :=
2128 Naming.Decl.Attributes,
2132 pragma Assert (Casing_String.Kind = Single,
2133 "Casing is not a single string");
2135 if not Casing_String.Default then
2137 Casing_Image : constant String :=
2138 Get_Name_String (Casing_String.Value);
2141 Casing_Value : constant Casing_Type :=
2142 Value (Casing_Image);
2144 Data.Naming.Casing := Casing_Value;
2148 when Constraint_Error =>
2149 if Casing_Image'Length = 0 then
2152 "Casing cannot be an empty string",
2153 Casing_String.Location);
2156 Name_Len := Casing_Image'Length;
2157 Name_Buffer (1 .. Name_Len) := Casing_Image;
2158 Err_Vars.Error_Msg_Name_1 := Name_Find;
2161 "%% is not a correct Casing",
2162 Casing_String.Location);
2168 if Current_Verbosity = High then
2169 Write_Str (" Casing = ");
2170 Write_Str (Image (Data.Naming.Casing));
2175 -- Check Spec_Suffix
2178 Ada_Spec_Suffix : constant Variable_Value :=
2182 In_Array => Data.Naming.Spec_Suffix,
2183 In_Tree => In_Tree);
2186 if Ada_Spec_Suffix.Kind = Single
2187 and then Get_Name_String (Ada_Spec_Suffix.Value) /= ""
2189 Get_Name_String (Ada_Spec_Suffix.Value);
2190 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2191 Set_Spec_Suffix (In_Tree, "ada", Data.Naming, Name_Find);
2192 Data.Naming.Ada_Spec_Suffix_Loc := Ada_Spec_Suffix.Location;
2199 Default_Ada_Spec_Suffix);
2203 if Current_Verbosity = High then
2204 Write_Str (" Spec_Suffix = """);
2205 Write_Str (Spec_Suffix_Of (In_Tree, "ada", Data.Naming));
2210 -- Check Body_Suffix
2213 Ada_Body_Suffix : constant Variable_Value :=
2217 In_Array => Data.Naming.Body_Suffix,
2218 In_Tree => In_Tree);
2221 if Ada_Body_Suffix.Kind = Single
2222 and then Get_Name_String (Ada_Body_Suffix.Value) /= ""
2224 Get_Name_String (Ada_Body_Suffix.Value);
2225 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2226 Set_Body_Suffix (In_Tree, "ada", Data.Naming, Name_Find);
2227 Data.Naming.Ada_Body_Suffix_Loc := Ada_Body_Suffix.Location;
2234 Default_Ada_Body_Suffix);
2238 if Current_Verbosity = High then
2239 Write_Str (" Body_Suffix = """);
2240 Write_Str (Body_Suffix_Of (In_Tree, "ada", Data.Naming));
2245 -- Check Separate_Suffix
2248 Ada_Sep_Suffix : constant Variable_Value :=
2250 (Variable_Name => Name_Separate_Suffix,
2251 In_Variables => Naming.Decl.Attributes,
2252 In_Tree => In_Tree);
2255 if Ada_Sep_Suffix.Default then
2256 Data.Naming.Separate_Suffix :=
2257 Body_Suffix_Id_Of (In_Tree, "ada", Data.Naming);
2260 Get_Name_String (Ada_Sep_Suffix.Value);
2262 if Name_Len = 0 then
2265 "Separate_Suffix cannot be empty",
2266 Ada_Sep_Suffix.Location);
2269 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2270 Data.Naming.Separate_Suffix := Name_Find;
2271 Data.Naming.Sep_Suffix_Loc := Ada_Sep_Suffix.Location;
2276 if Current_Verbosity = High then
2277 Write_Str (" Separate_Suffix = """);
2278 Write_Str (Get_Name_String (Data.Naming.Separate_Suffix));
2283 -- Check if Data.Naming is valid
2285 Check_Ada_Naming_Scheme_Validity (Project, In_Tree, Data.Naming);
2288 elsif not In_Configuration then
2290 -- Look into package Naming, if there is one
2292 if Naming_Id /= No_Package then
2293 Naming := In_Tree.Packages.Table (Naming_Id);
2295 if Current_Verbosity = High then
2296 Write_Line ("Checking package Naming.");
2299 -- We are now checking if attribute Dot_Replacement, Casing,
2300 -- and/or Separate_Suffix exist.
2302 -- For each attribute, if it does not exist, we do nothing,
2303 -- because we already have the default.
2304 -- Otherwise, for all unit-based languages, we put the declared
2305 -- value in the language config.
2308 Dot_Repl : constant Variable_Value :=
2310 (Name_Dot_Replacement,
2311 Naming.Decl.Attributes, In_Tree);
2312 Dot_Replacement : File_Name_Type := No_File;
2314 Casing_String : constant Variable_Value :=
2317 Naming.Decl.Attributes,
2319 Casing : Casing_Type;
2320 Casing_Defined : Boolean := False;
2322 Sep_Suffix : constant Variable_Value :=
2324 (Variable_Name => Name_Separate_Suffix,
2325 In_Variables => Naming.Decl.Attributes,
2326 In_Tree => In_Tree);
2327 Separate_Suffix : File_Name_Type := No_File;
2329 Lang_Id : Language_Index;
2331 -- Check attribute Dot_Replacement
2333 if not Dot_Repl.Default then
2334 Get_Name_String (Dot_Repl.Value);
2336 if Name_Len = 0 then
2339 "Dot_Replacement cannot be empty",
2343 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2344 Dot_Replacement := Name_Find;
2346 if Current_Verbosity = High then
2347 Write_Str (" Dot_Replacement = """);
2348 Write_Str (Get_Name_String (Dot_Replacement));
2355 -- Check attribute Casing
2357 if not Casing_String.Default then
2359 Casing_Image : constant String :=
2360 Get_Name_String (Casing_String.Value);
2363 Casing_Value : constant Casing_Type :=
2364 Value (Casing_Image);
2366 Casing := Casing_Value;
2367 Casing_Defined := True;
2369 if Current_Verbosity = High then
2370 Write_Str (" Casing = ");
2371 Write_Str (Image (Casing));
2378 when Constraint_Error =>
2379 if Casing_Image'Length = 0 then
2382 "Casing cannot be an empty string",
2383 Casing_String.Location);
2386 Name_Len := Casing_Image'Length;
2387 Name_Buffer (1 .. Name_Len) := Casing_Image;
2388 Err_Vars.Error_Msg_Name_1 := Name_Find;
2391 "%% is not a correct Casing",
2392 Casing_String.Location);
2397 if not Sep_Suffix.Default then
2398 Get_Name_String (Sep_Suffix.Value);
2400 if Name_Len = 0 then
2403 "Separate_Suffix cannot be empty",
2404 Sep_Suffix.Location);
2407 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2408 Separate_Suffix := Name_Find;
2410 if Current_Verbosity = High then
2411 Write_Str (" Separate_Suffix = """);
2413 (Get_Name_String (Data.Naming.Separate_Suffix));
2420 -- For all unit based languages, if any, set the specified
2421 -- value of Dot_Replacement, Casing and/or Separate_Suffix.
2423 if Dot_Replacement /= No_File or else
2424 Casing_Defined or else
2425 Separate_Suffix /= No_File
2427 Lang_Id := Data.First_Language_Processing;
2429 while Lang_Id /= No_Language_Index loop
2430 if In_Tree.Languages_Data.Table
2431 (Lang_Id).Config.Kind = Unit_Based
2433 if Dot_Replacement /= No_File then
2434 In_Tree.Languages_Data.Table
2435 (Lang_Id).Config.Naming_Data.Dot_Replacement :=
2439 if Casing_Defined then
2440 In_Tree.Languages_Data.Table
2441 (Lang_Id).Config.Naming_Data.Casing := Casing;
2444 if Separate_Suffix /= No_File then
2445 In_Tree.Languages_Data.Table
2446 (Lang_Id).Config.Naming_Data.Separate_Suffix :=
2452 In_Tree.Languages_Data.Table (Lang_Id).Next;
2457 -- Next, get the spec and body suffixes
2460 Suffix : Variable_Value;
2462 Lang_Id : Language_Index := Data.First_Language_Processing;
2465 while Lang_Id /= No_Language_Index loop
2466 Lang := In_Tree.Languages_Data.Table (Lang_Id).Name;
2472 Attribute_Or_Array_Name => Name_Spec_Suffix,
2473 In_Package => Naming_Id,
2474 In_Tree => In_Tree);
2476 if Suffix = Nil_Variable_Value then
2479 Attribute_Or_Array_Name => Name_Specification_Suffix,
2480 In_Package => Naming_Id,
2481 In_Tree => In_Tree);
2484 if Suffix /= Nil_Variable_Value then
2485 In_Tree.Languages_Data.Table (Lang_Id).
2486 Config.Naming_Data.Spec_Suffix :=
2487 File_Name_Type (Suffix.Value);
2494 Attribute_Or_Array_Name => Name_Body_Suffix,
2495 In_Package => Naming_Id,
2496 In_Tree => In_Tree);
2498 if Suffix = Nil_Variable_Value then
2501 Attribute_Or_Array_Name => Name_Implementation_Suffix,
2502 In_Package => Naming_Id,
2503 In_Tree => In_Tree);
2506 if Suffix /= Nil_Variable_Value then
2507 In_Tree.Languages_Data.Table (Lang_Id).
2508 Config.Naming_Data.Body_Suffix :=
2509 File_Name_Type (Suffix.Value);
2512 Lang_Id := In_Tree.Languages_Data.Table (Lang_Id).Next;
2516 -- Get the exceptions for file based languages
2518 Get_Exceptions (Spec);
2519 Get_Exceptions (Impl);
2521 -- Get the exceptions for unit based languages
2523 Get_Unit_Exceptions (Spec);
2524 Get_Unit_Exceptions (Impl);
2528 end Check_Naming_Schemes;
2530 ------------------------------
2531 -- Check_Library_Attributes --
2532 ------------------------------
2534 procedure Check_Library_Attributes
2535 (Project : Project_Id;
2536 In_Tree : Project_Tree_Ref;
2537 Data : in out Project_Data)
2539 Attributes : constant Prj.Variable_Id := Data.Decl.Attributes;
2541 Lib_Dir : constant Prj.Variable_Value :=
2543 (Snames.Name_Library_Dir, Attributes, In_Tree);
2545 Lib_Name : constant Prj.Variable_Value :=
2547 (Snames.Name_Library_Name, Attributes, In_Tree);
2549 Lib_Version : constant Prj.Variable_Value :=
2551 (Snames.Name_Library_Version, Attributes, In_Tree);
2553 Lib_ALI_Dir : constant Prj.Variable_Value :=
2555 (Snames.Name_Library_Ali_Dir, Attributes, In_Tree);
2557 The_Lib_Kind : constant Prj.Variable_Value :=
2559 (Snames.Name_Library_Kind, Attributes, In_Tree);
2561 Imported_Project_List : Project_List := Empty_Project_List;
2563 Continuation : String_Access := No_Continuation_String'Access;
2565 Support_For_Libraries : Library_Support;
2567 procedure Check_Library (Proj : Project_Id; Extends : Boolean);
2568 -- Check if an imported or extended project if also a library project
2574 procedure Check_Library (Proj : Project_Id; Extends : Boolean) is
2575 Proj_Data : Project_Data;
2578 if Proj /= No_Project then
2579 Proj_Data := In_Tree.Projects.Table (Proj);
2581 if not Proj_Data.Library then
2582 -- The only not library projects that are OK are those that
2585 if Proj_Data.Source_Dirs /= Nil_String then
2587 Error_Msg_Name_1 := Data.Name;
2588 Error_Msg_Name_2 := Proj_Data.Name;
2594 "library project %% cannot extend project %% " &
2595 "that is not a library project",
2602 "library project %% cannot import project %% " &
2603 "that is not a library project",
2607 Continuation := Continuation_String'Access;
2610 elsif Data.Library_Kind /= Static and then
2611 Proj_Data.Library_Kind = Static
2613 Error_Msg_Name_1 := Data.Name;
2614 Error_Msg_Name_2 := Proj_Data.Name;
2620 "shared library project %% cannot extend static " &
2621 "library project %%",
2628 "shared library project %% cannot import static " &
2629 "library project %%",
2633 Continuation := Continuation_String'Access;
2639 -- Special case of extending project
2641 if Data.Extends /= No_Project then
2643 Extended_Data : constant Project_Data :=
2644 In_Tree.Projects.Table (Data.Extends);
2647 -- If the project extended is a library project, we inherit
2648 -- the library name, if it is not redefined; we check that
2649 -- the library directory is specified.
2651 if Extended_Data.Library then
2652 if Lib_Name.Default then
2653 Data.Library_Name := Extended_Data.Library_Name;
2656 if Lib_Dir.Default then
2657 if not Data.Virtual then
2660 "a project extending a library project must " &
2661 "specify an attribute Library_Dir",
2669 pragma Assert (Lib_Dir.Kind = Single);
2671 if Lib_Dir.Value = Empty_String then
2672 if Current_Verbosity = High then
2673 Write_Line ("No library directory");
2677 -- Find path name, check that it is a directory
2682 File_Name_Type (Lib_Dir.Value),
2683 Data.Display_Directory,
2685 Data.Display_Library_Dir,
2686 Create => "library",
2687 Location => Lib_Dir.Location);
2689 if Data.Library_Dir = No_Path then
2691 -- Get the absolute name of the library directory that
2692 -- does not exist, to report an error.
2695 Dir_Name : constant String := Get_Name_String (Lib_Dir.Value);
2698 if Is_Absolute_Path (Dir_Name) then
2699 Err_Vars.Error_Msg_File_1 := File_Name_Type (Lib_Dir.Value);
2702 Get_Name_String (Data.Display_Directory);
2704 if Name_Buffer (Name_Len) /= Directory_Separator then
2705 Name_Len := Name_Len + 1;
2706 Name_Buffer (Name_Len) := Directory_Separator;
2710 (Name_Len + 1 .. Name_Len + Dir_Name'Length) :=
2712 Name_Len := Name_Len + Dir_Name'Length;
2713 Err_Vars.Error_Msg_File_1 := Name_Find;
2720 "library directory { does not exist",
2724 -- The library directory cannot be the same as the Object directory
2726 elsif Data.Library_Dir = Data.Object_Directory then
2729 "library directory cannot be the same " &
2730 "as object directory",
2732 Data.Library_Dir := No_Path;
2733 Data.Display_Library_Dir := No_Path;
2737 OK : Boolean := True;
2738 Dirs_Id : String_List_Id;
2739 Dir_Elem : String_Element;
2742 -- The library directory cannot be the same as a source
2743 -- directory of the current project.
2745 Dirs_Id := Data.Source_Dirs;
2746 while Dirs_Id /= Nil_String loop
2747 Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id);
2748 Dirs_Id := Dir_Elem.Next;
2750 if Data.Library_Dir = Path_Name_Type (Dir_Elem.Value) then
2751 Err_Vars.Error_Msg_File_1 :=
2752 File_Name_Type (Dir_Elem.Value);
2755 "library directory cannot be the same " &
2756 "as source directory {",
2765 -- The library directory cannot be the same as a source
2766 -- directory of another project either.
2769 for Pid in 1 .. Project_Table.Last (In_Tree.Projects) loop
2770 if Pid /= Project then
2771 Dirs_Id := In_Tree.Projects.Table (Pid).Source_Dirs;
2773 Dir_Loop : while Dirs_Id /= Nil_String loop
2774 Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id);
2775 Dirs_Id := Dir_Elem.Next;
2777 if Data.Library_Dir =
2778 Path_Name_Type (Dir_Elem.Value)
2780 Err_Vars.Error_Msg_File_1 :=
2781 File_Name_Type (Dir_Elem.Value);
2782 Err_Vars.Error_Msg_Name_1 :=
2783 In_Tree.Projects.Table (Pid).Name;
2787 "library directory cannot be the same " &
2788 "as source directory { of project %%",
2795 end loop Project_Loop;
2799 Data.Library_Dir := No_Path;
2800 Data.Display_Library_Dir := No_Path;
2802 elsif Current_Verbosity = High then
2804 -- Display the Library directory in high verbosity
2806 Write_Str ("Library directory =""");
2807 Write_Str (Get_Name_String (Data.Display_Library_Dir));
2814 pragma Assert (Lib_Name.Kind = Single);
2816 if Lib_Name.Value = Empty_String then
2817 if Current_Verbosity = High
2818 and then Data.Library_Name = No_Name
2820 Write_Line ("No library name");
2824 -- There is no restriction on the syntax of library names
2826 Data.Library_Name := Lib_Name.Value;
2829 if Data.Library_Name /= No_Name
2830 and then Current_Verbosity = High
2832 Write_Str ("Library name = """);
2833 Write_Str (Get_Name_String (Data.Library_Name));
2838 Data.Library_Dir /= No_Path
2840 Data.Library_Name /= No_Name;
2842 if Data.Library then
2843 if Get_Mode = Multi_Language then
2844 Support_For_Libraries := In_Tree.Config.Lib_Support;
2847 Support_For_Libraries := MLib.Tgt.Support_For_Libraries;
2850 if Support_For_Libraries = Prj.None then
2853 "?libraries are not supported on this platform",
2855 Data.Library := False;
2858 if Lib_ALI_Dir.Value = Empty_String then
2859 if Current_Verbosity = High then
2860 Write_Line ("No library 'A'L'I directory specified");
2862 Data.Library_ALI_Dir := Data.Library_Dir;
2863 Data.Display_Library_ALI_Dir := Data.Display_Library_Dir;
2866 -- Find path name, check that it is a directory
2871 File_Name_Type (Lib_ALI_Dir.Value),
2872 Data.Display_Directory,
2873 Data.Library_ALI_Dir,
2874 Data.Display_Library_ALI_Dir,
2875 Create => "library ALI",
2876 Location => Lib_ALI_Dir.Location);
2878 if Data.Library_ALI_Dir = No_Path then
2880 -- Get the absolute name of the library ALI directory that
2881 -- does not exist, to report an error.
2884 Dir_Name : constant String :=
2885 Get_Name_String (Lib_ALI_Dir.Value);
2888 if Is_Absolute_Path (Dir_Name) then
2889 Err_Vars.Error_Msg_File_1 :=
2890 File_Name_Type (Lib_Dir.Value);
2893 Get_Name_String (Data.Display_Directory);
2895 if Name_Buffer (Name_Len) /= Directory_Separator then
2896 Name_Len := Name_Len + 1;
2897 Name_Buffer (Name_Len) := Directory_Separator;
2901 (Name_Len + 1 .. Name_Len + Dir_Name'Length) :=
2903 Name_Len := Name_Len + Dir_Name'Length;
2904 Err_Vars.Error_Msg_File_1 := Name_Find;
2911 "library 'A'L'I directory { does not exist",
2912 Lib_ALI_Dir.Location);
2916 if Data.Library_ALI_Dir /= Data.Library_Dir then
2918 -- The library ALI directory cannot be the same as the
2919 -- Object directory.
2921 if Data.Library_ALI_Dir = Data.Object_Directory then
2924 "library 'A'L'I directory cannot be the same " &
2925 "as object directory",
2926 Lib_ALI_Dir.Location);
2927 Data.Library_ALI_Dir := No_Path;
2928 Data.Display_Library_ALI_Dir := No_Path;
2932 OK : Boolean := True;
2933 Dirs_Id : String_List_Id;
2934 Dir_Elem : String_Element;
2937 -- The library ALI directory cannot be the same as
2938 -- a source directory of the current project.
2940 Dirs_Id := Data.Source_Dirs;
2941 while Dirs_Id /= Nil_String loop
2942 Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id);
2943 Dirs_Id := Dir_Elem.Next;
2945 if Data.Library_ALI_Dir =
2946 Path_Name_Type (Dir_Elem.Value)
2948 Err_Vars.Error_Msg_File_1 :=
2949 File_Name_Type (Dir_Elem.Value);
2952 "library 'A'L'I directory cannot be " &
2953 "the same as source directory {",
2954 Lib_ALI_Dir.Location);
2962 -- The library ALI directory cannot be the same as
2963 -- a source directory of another project either.
2967 Pid in 1 .. Project_Table.Last (In_Tree.Projects)
2969 if Pid /= Project then
2971 In_Tree.Projects.Table (Pid).Source_Dirs;
2974 while Dirs_Id /= Nil_String loop
2976 In_Tree.String_Elements.Table (Dirs_Id);
2977 Dirs_Id := Dir_Elem.Next;
2979 if Data.Library_ALI_Dir =
2980 Path_Name_Type (Dir_Elem.Value)
2982 Err_Vars.Error_Msg_File_1 :=
2983 File_Name_Type (Dir_Elem.Value);
2984 Err_Vars.Error_Msg_Name_1 :=
2985 In_Tree.Projects.Table (Pid).Name;
2989 "library 'A'L'I directory cannot " &
2990 "be the same as source directory " &
2992 Lib_ALI_Dir.Location);
2994 exit ALI_Project_Loop;
2996 end loop ALI_Dir_Loop;
2998 end loop ALI_Project_Loop;
3002 Data.Library_ALI_Dir := No_Path;
3003 Data.Display_Library_ALI_Dir := No_Path;
3005 elsif Current_Verbosity = High then
3007 -- Display the Library ALI directory in high
3010 Write_Str ("Library ALI directory =""");
3012 (Get_Name_String (Data.Display_Library_ALI_Dir));
3020 pragma Assert (Lib_Version.Kind = Single);
3022 if Lib_Version.Value = Empty_String then
3023 if Current_Verbosity = High then
3024 Write_Line ("No library version specified");
3028 Data.Lib_Internal_Name := Lib_Version.Value;
3031 pragma Assert (The_Lib_Kind.Kind = Single);
3033 if The_Lib_Kind.Value = Empty_String then
3034 if Current_Verbosity = High then
3035 Write_Line ("No library kind specified");
3039 Get_Name_String (The_Lib_Kind.Value);
3042 Kind_Name : constant String :=
3043 To_Lower (Name_Buffer (1 .. Name_Len));
3045 OK : Boolean := True;
3048 if Kind_Name = "static" then
3049 Data.Library_Kind := Static;
3051 elsif Kind_Name = "dynamic" then
3052 Data.Library_Kind := Dynamic;
3054 elsif Kind_Name = "relocatable" then
3055 Data.Library_Kind := Relocatable;
3060 "illegal value for Library_Kind",
3061 The_Lib_Kind.Location);
3065 if Current_Verbosity = High and then OK then
3066 Write_Str ("Library kind = ");
3067 Write_Line (Kind_Name);
3070 if Data.Library_Kind /= Static and then
3071 Support_For_Libraries = Prj.Static_Only
3075 "only static libraries are supported " &
3077 The_Lib_Kind.Location);
3078 Data.Library := False;
3083 if Data.Library then
3084 if Current_Verbosity = High then
3085 Write_Line ("This is a library project file");
3088 if Get_Mode = Multi_Language then
3089 Check_Library (Data.Extends, Extends => True);
3091 Imported_Project_List := Data.Imported_Projects;
3092 while Imported_Project_List /= Empty_Project_List loop
3094 (In_Tree.Project_Lists.Table
3095 (Imported_Project_List).Project,
3097 Imported_Project_List :=
3098 In_Tree.Project_Lists.Table
3099 (Imported_Project_List).Next;
3107 if Data.Extends /= No_Project then
3108 In_Tree.Projects.Table (Data.Extends).Library := False;
3110 end Check_Library_Attributes;
3112 --------------------------
3113 -- Check_Package_Naming --
3114 --------------------------
3116 procedure Check_Package_Naming
3117 (Project : Project_Id;
3118 In_Tree : Project_Tree_Ref;
3119 Data : in out Project_Data)
3121 Naming_Id : constant Package_Id :=
3122 Util.Value_Of (Name_Naming, Data.Decl.Packages, In_Tree);
3124 Naming : Package_Element;
3127 -- If there is a package Naming, we will put in Data.Naming
3128 -- what is in this package Naming.
3130 if Naming_Id /= No_Package then
3131 Naming := In_Tree.Packages.Table (Naming_Id);
3133 if Current_Verbosity = High then
3134 Write_Line ("Checking ""Naming"".");
3137 -- Check Spec_Suffix
3140 Spec_Suffixs : Array_Element_Id :=
3146 Suffix : Array_Element_Id;
3147 Element : Array_Element;
3148 Suffix2 : Array_Element_Id;
3151 -- If some suffixs have been specified, we make sure that
3152 -- for each language for which a default suffix has been
3153 -- specified, there is a suffix specified, either the one
3154 -- in the project file or if there were none, the default.
3156 if Spec_Suffixs /= No_Array_Element then
3157 Suffix := Data.Naming.Spec_Suffix;
3159 while Suffix /= No_Array_Element loop
3161 In_Tree.Array_Elements.Table (Suffix);
3162 Suffix2 := Spec_Suffixs;
3164 while Suffix2 /= No_Array_Element loop
3165 exit when In_Tree.Array_Elements.Table
3166 (Suffix2).Index = Element.Index;
3167 Suffix2 := In_Tree.Array_Elements.Table
3171 -- There is a registered default suffix, but no
3172 -- suffix specified in the project file.
3173 -- Add the default to the array.
3175 if Suffix2 = No_Array_Element then
3176 Array_Element_Table.Increment_Last
3177 (In_Tree.Array_Elements);
3178 In_Tree.Array_Elements.Table
3179 (Array_Element_Table.Last
3180 (In_Tree.Array_Elements)) :=
3181 (Index => Element.Index,
3182 Src_Index => Element.Src_Index,
3183 Index_Case_Sensitive => False,
3184 Value => Element.Value,
3185 Next => Spec_Suffixs);
3186 Spec_Suffixs := Array_Element_Table.Last
3187 (In_Tree.Array_Elements);
3190 Suffix := Element.Next;
3193 -- Put the resulting array as the specification suffixs
3195 Data.Naming.Spec_Suffix := Spec_Suffixs;
3200 Current : Array_Element_Id := Data.Naming.Spec_Suffix;
3201 Element : Array_Element;
3204 while Current /= No_Array_Element loop
3205 Element := In_Tree.Array_Elements.Table (Current);
3206 Get_Name_String (Element.Value.Value);
3208 if Name_Len = 0 then
3211 "Spec_Suffix cannot be empty",
3212 Element.Value.Location);
3215 In_Tree.Array_Elements.Table (Current) := Element;
3216 Current := Element.Next;
3220 -- Check Body_Suffix
3223 Impl_Suffixs : Array_Element_Id :=
3229 Suffix : Array_Element_Id;
3230 Element : Array_Element;
3231 Suffix2 : Array_Element_Id;
3234 -- If some suffixes have been specified, we make sure that
3235 -- for each language for which a default suffix has been
3236 -- specified, there is a suffix specified, either the one
3237 -- in the project file or if there were none, the default.
3239 if Impl_Suffixs /= No_Array_Element then
3240 Suffix := Data.Naming.Body_Suffix;
3242 while Suffix /= No_Array_Element loop
3244 In_Tree.Array_Elements.Table (Suffix);
3245 Suffix2 := Impl_Suffixs;
3247 while Suffix2 /= No_Array_Element loop
3248 exit when In_Tree.Array_Elements.Table
3249 (Suffix2).Index = Element.Index;
3250 Suffix2 := In_Tree.Array_Elements.Table
3254 -- There is a registered default suffix, but no suffix was
3255 -- specified in the project file. Add the default to the
3258 if Suffix2 = No_Array_Element then
3259 Array_Element_Table.Increment_Last
3260 (In_Tree.Array_Elements);
3261 In_Tree.Array_Elements.Table
3262 (Array_Element_Table.Last
3263 (In_Tree.Array_Elements)) :=
3264 (Index => Element.Index,
3265 Src_Index => Element.Src_Index,
3266 Index_Case_Sensitive => False,
3267 Value => Element.Value,
3268 Next => Impl_Suffixs);
3269 Impl_Suffixs := Array_Element_Table.Last
3270 (In_Tree.Array_Elements);
3273 Suffix := Element.Next;
3276 -- Put the resulting array as the implementation suffixs
3278 Data.Naming.Body_Suffix := Impl_Suffixs;
3283 Current : Array_Element_Id := Data.Naming.Body_Suffix;
3284 Element : Array_Element;
3287 while Current /= No_Array_Element loop
3288 Element := In_Tree.Array_Elements.Table (Current);
3289 Get_Name_String (Element.Value.Value);
3291 if Name_Len = 0 then
3294 "Body_Suffix cannot be empty",
3295 Element.Value.Location);
3298 In_Tree.Array_Elements.Table (Current) := Element;
3299 Current := Element.Next;
3303 -- Get the exceptions, if any
3305 Data.Naming.Specification_Exceptions :=
3307 (Name_Specification_Exceptions,
3308 In_Arrays => Naming.Decl.Arrays,
3309 In_Tree => In_Tree);
3311 Data.Naming.Implementation_Exceptions :=
3313 (Name_Implementation_Exceptions,
3314 In_Arrays => Naming.Decl.Arrays,
3315 In_Tree => In_Tree);
3317 end Check_Package_Naming;
3319 ---------------------------------
3320 -- Check_Programming_Languages --
3321 ---------------------------------
3323 procedure Check_Programming_Languages
3324 (In_Tree : Project_Tree_Ref;
3325 Project : Project_Id;
3326 Data : in out Project_Data)
3328 Languages : Variable_Value := Nil_Variable_Value;
3329 Lang : Language_Index;
3333 Prj.Util.Value_Of (Name_Languages, Data.Decl.Attributes, In_Tree);
3334 Data.Ada_Sources_Present := Data.Source_Dirs /= Nil_String;
3335 Data.Other_Sources_Present := Data.Source_Dirs /= Nil_String;
3337 if Data.Source_Dirs /= Nil_String then
3339 -- Check if languages are specified in this project
3341 if Languages.Default then
3343 -- Attribute Languages is not specified. So, it defaults to
3344 -- a project of the default language only.
3346 Name_List_Table.Increment_Last (In_Tree.Name_Lists);
3347 Data.Languages := Name_List_Table.Last (In_Tree.Name_Lists);
3349 -- In Ada_Only mode, the default language is Ada
3351 if Get_Mode = Ada_Only then
3352 In_Tree.Name_Lists.Table (Data.Languages) :=
3353 (Name => Name_Ada, Next => No_Name_List);
3355 -- Attribute Languages is not specified. So, it defaults to
3356 -- a project of language Ada only.
3358 Data.Langs (Ada_Language_Index) := True;
3360 -- No sources of languages other than Ada
3362 Data.Other_Sources_Present := False;
3364 elsif In_Tree.Default_Language = No_Name then
3368 "no languages defined for this project",
3372 In_Tree.Name_Lists.Table (Data.Languages) :=
3373 (Name => In_Tree.Default_Language, Next => No_Name_List);
3374 Language_Data_Table.Increment_Last (In_Tree.Languages_Data);
3375 Data.First_Language_Processing :=
3376 Language_Data_Table.Last (In_Tree.Languages_Data);
3377 In_Tree.Languages_Data.Table
3378 (Data.First_Language_Processing) := No_Language_Data;
3379 In_Tree.Languages_Data.Table
3380 (Data.First_Language_Processing).Name :=
3381 In_Tree.Default_Language;
3382 Get_Name_String (In_Tree.Default_Language);
3383 Name_Buffer (1) := GNAT.Case_Util.To_Upper (Name_Buffer (1));
3384 In_Tree.Languages_Data.Table
3385 (Data.First_Language_Processing).Display_Name := Name_Find;
3387 Lang := In_Tree.First_Language;
3389 while Lang /= No_Language_Index loop
3390 if In_Tree.Languages_Data.Table (Lang).Name =
3391 In_Tree.Default_Language
3393 In_Tree.Languages_Data.Table
3394 (Data.First_Language_Processing).Config :=
3395 In_Tree.Languages_Data.Table (Lang).Config;
3397 if In_Tree.Languages_Data.Table (Lang).Config.Kind =
3400 Data.Unit_Based_Language_Name :=
3401 In_Tree.Default_Language;
3402 Data.Unit_Based_Language_Index :=
3403 Data.First_Language_Processing;
3409 Lang := In_Tree.Languages_Data.Table (Lang).Next;
3415 Current : String_List_Id := Languages.Values;
3416 Element : String_Element;
3417 Lang_Name : Name_Id;
3418 Display_Lang_Name : Name_Id;
3419 Index : Language_Index;
3420 Lang_Data : Language_Data;
3421 NL_Id : Name_List_Index := No_Name_List;
3422 Config : Language_Config;
3425 if Get_Mode = Ada_Only then
3426 -- Assume that there is no language specified yet
3428 Data.Other_Sources_Present := False;
3429 Data.Ada_Sources_Present := False;
3432 -- If there are no languages declared, there are no sources
3434 if Current = Nil_String then
3435 Data.Source_Dirs := Nil_String;
3438 -- Look through all the languages specified in attribute
3441 while Current /= Nil_String loop
3443 In_Tree.String_Elements.Table (Current);
3444 Display_Lang_Name := Element.Value;
3445 Get_Name_String (Element.Value);
3446 To_Lower (Name_Buffer (1 .. Name_Len));
3447 Lang_Name := Name_Find;
3449 Name_List_Table.Increment_Last (In_Tree.Name_Lists);
3451 if NL_Id = No_Name_List then
3453 Name_List_Table.Last (In_Tree.Name_Lists);
3456 In_Tree.Name_Lists.Table (NL_Id).Next :=
3457 Name_List_Table.Last (In_Tree.Name_Lists);
3460 NL_Id := Name_List_Table.Last (In_Tree.Name_Lists);
3461 In_Tree.Name_Lists.Table (NL_Id) :=
3462 (Lang_Name, No_Name_List);
3464 if Get_Mode = Ada_Only then
3465 Index := Language_Indexes.Get (Lang_Name);
3467 if Index = No_Language_Index then
3468 Add_Language_Name (Lang_Name);
3469 Index := Last_Language_Index;
3472 Set (Index, True, Data, In_Tree);
3473 Set (Language_Processing =>
3474 Default_Language_Processing_Data,
3475 For_Language => Index,
3477 In_Tree => In_Tree);
3479 if Index = Ada_Language_Index then
3480 Data.Ada_Sources_Present := True;
3483 Data.Other_Sources_Present := True;
3487 Index := Data.First_Language_Processing;
3489 while Index /= No_Language_Index loop
3492 In_Tree.Languages_Data.Table (Index).Name;
3493 Index := In_Tree.Languages_Data.Table (Index).Next;
3496 if Index = No_Language_Index then
3497 Language_Data_Table.Increment_Last
3498 (In_Tree.Languages_Data);
3500 Language_Data_Table.Last (In_Tree.Languages_Data);
3501 Lang_Data.Name := Lang_Name;
3502 Lang_Data.Display_Name := Element.Value;
3503 Lang_Data.Next := Data.First_Language_Processing;
3504 In_Tree.Languages_Data.Table (Index) := Lang_Data;
3505 Data.First_Language_Processing := Index;
3507 Index := In_Tree.First_Language;
3509 while Index /= No_Language_Index loop
3512 In_Tree.Languages_Data.Table (Index).Name;
3514 In_Tree.Languages_Data.Table (Index).Next;
3517 if Index = No_Language_Index then
3521 Get_Name_String (Display_Lang_Name) &
3522 """ not found in configuration",
3523 Languages.Location);
3527 In_Tree.Languages_Data.Table (Index).Config;
3529 -- Duplicate name lists
3532 (Config.Compiler_Min_Options, In_Tree);
3534 (Config.Compilation_PIC_Option, In_Tree);
3536 (Config.Mapping_File_Switches, In_Tree);
3538 (Config.Config_File_Switches, In_Tree);
3540 (Config.Dependency_Option, In_Tree);
3542 (Config.Compute_Dependency, In_Tree);
3544 (Config.Include_Option, In_Tree);
3546 (Config.Binder_Min_Options, In_Tree);
3548 In_Tree.Languages_Data.Table
3549 (Data.First_Language_Processing).Config :=
3552 if Config.Kind = Unit_Based then
3554 Data.Unit_Based_Language_Name = No_Name
3556 Data.Unit_Based_Language_Name := Lang_Name;
3557 Data.Unit_Based_Language_Index :=
3558 Language_Data_Table.Last
3559 (In_Tree.Languages_Data);
3564 "not allowed to have several " &
3565 "unit-based languages in the same " &
3567 Languages.Location);
3574 Current := Element.Next;
3580 end Check_Programming_Languages;
3586 function Check_Project
3588 Root_Project : Project_Id;
3589 In_Tree : Project_Tree_Ref;
3590 Extending : Boolean) return Boolean
3593 if P = Root_Project then
3596 elsif Extending then
3598 Data : Project_Data := In_Tree.Projects.Table (Root_Project);
3601 while Data.Extends /= No_Project loop
3602 if P = Data.Extends then
3606 Data := In_Tree.Projects.Table (Data.Extends);
3614 -------------------------------
3615 -- Check_Stand_Alone_Library --
3616 -------------------------------
3618 procedure Check_Stand_Alone_Library
3619 (Project : Project_Id;
3620 In_Tree : Project_Tree_Ref;
3621 Data : in out Project_Data;
3622 Extending : Boolean)
3624 Lib_Interfaces : constant Prj.Variable_Value :=
3626 (Snames.Name_Library_Interface,
3627 Data.Decl.Attributes,
3630 Lib_Auto_Init : constant Prj.Variable_Value :=
3632 (Snames.Name_Library_Auto_Init,
3633 Data.Decl.Attributes,
3636 Lib_Src_Dir : constant Prj.Variable_Value :=
3638 (Snames.Name_Library_Src_Dir,
3639 Data.Decl.Attributes,
3642 Lib_Symbol_File : constant Prj.Variable_Value :=
3644 (Snames.Name_Library_Symbol_File,
3645 Data.Decl.Attributes,
3648 Lib_Symbol_Policy : constant Prj.Variable_Value :=
3650 (Snames.Name_Library_Symbol_Policy,
3651 Data.Decl.Attributes,
3654 Lib_Ref_Symbol_File : constant Prj.Variable_Value :=
3656 (Snames.Name_Library_Reference_Symbol_File,
3657 Data.Decl.Attributes,
3660 Auto_Init_Supported : Boolean;
3662 OK : Boolean := True;
3665 Next_Proj : Project_Id;
3668 if Get_Mode = Multi_Language then
3669 Auto_Init_Supported := In_Tree.Config.Auto_Init_Supported;
3672 Auto_Init_Supported :=
3673 MLib.Tgt.Standalone_Library_Auto_Init_Is_Supported;
3676 pragma Assert (Lib_Interfaces.Kind = List);
3678 -- It is a stand-alone library project file if attribute
3679 -- Library_Interface is defined.
3681 if not Lib_Interfaces.Default then
3682 SAL_Library : declare
3683 Interfaces : String_List_Id := Lib_Interfaces.Values;
3684 Interface_ALIs : String_List_Id := Nil_String;
3686 The_Unit_Id : Unit_Index;
3687 The_Unit_Data : Unit_Data;
3689 procedure Add_ALI_For (Source : File_Name_Type);
3690 -- Add an ALI file name to the list of Interface ALIs
3696 procedure Add_ALI_For (Source : File_Name_Type) is
3698 Get_Name_String (Source);
3701 ALI : constant String :=
3702 ALI_File_Name (Name_Buffer (1 .. Name_Len));
3703 ALI_Name_Id : Name_Id;
3705 Name_Len := ALI'Length;
3706 Name_Buffer (1 .. Name_Len) := ALI;
3707 ALI_Name_Id := Name_Find;
3709 String_Element_Table.Increment_Last
3710 (In_Tree.String_Elements);
3711 In_Tree.String_Elements.Table
3712 (String_Element_Table.Last
3713 (In_Tree.String_Elements)) :=
3714 (Value => ALI_Name_Id,
3716 Display_Value => ALI_Name_Id,
3718 In_Tree.String_Elements.Table
3719 (Interfaces).Location,
3721 Next => Interface_ALIs);
3722 Interface_ALIs := String_Element_Table.Last
3723 (In_Tree.String_Elements);
3727 -- Start of processing for SAL_Library
3730 Data.Standalone_Library := True;
3732 -- Library_Interface cannot be an empty list
3734 if Interfaces = Nil_String then
3737 "Library_Interface cannot be an empty list",
3738 Lib_Interfaces.Location);
3741 -- Process each unit name specified in the attribute
3742 -- Library_Interface.
3744 while Interfaces /= Nil_String loop
3746 (In_Tree.String_Elements.Table (Interfaces).Value);
3747 To_Lower (Name_Buffer (1 .. Name_Len));
3749 if Name_Len = 0 then
3752 "an interface cannot be an empty string",
3753 In_Tree.String_Elements.Table (Interfaces).Location);
3757 Error_Msg_Name_1 := Unit;
3759 if Get_Mode = Ada_Only then
3761 Units_Htable.Get (In_Tree.Units_HT, Unit);
3763 if The_Unit_Id = No_Unit_Index then
3767 In_Tree.String_Elements.Table
3768 (Interfaces).Location);
3771 -- Check that the unit is part of the project
3774 In_Tree.Units.Table (The_Unit_Id);
3776 if The_Unit_Data.File_Names (Body_Part).Name /= No_File
3777 and then The_Unit_Data.File_Names (Body_Part).Path /=
3781 (The_Unit_Data.File_Names (Body_Part).Project,
3782 Project, In_Tree, Extending)
3784 -- There is a body for this unit.
3785 -- If there is no spec, we need to check
3786 -- that it is not a subunit.
3788 if The_Unit_Data.File_Names
3789 (Specification).Name = No_File
3792 Src_Ind : Source_File_Index;
3795 Src_Ind := Sinput.P.Load_Project_File
3797 (The_Unit_Data.File_Names
3800 if Sinput.P.Source_File_Is_Subunit
3805 "%% is a subunit; " &
3806 "it cannot be an interface",
3808 String_Elements.Table
3809 (Interfaces).Location);
3814 -- The unit is not a subunit, so we add
3815 -- to the Interface ALIs the ALI file
3816 -- corresponding to the body.
3819 (The_Unit_Data.File_Names (Body_Part).Name);
3824 "%% is not an unit of this project",
3825 In_Tree.String_Elements.Table
3826 (Interfaces).Location);
3829 elsif The_Unit_Data.File_Names
3830 (Specification).Name /= No_File
3831 and then The_Unit_Data.File_Names
3832 (Specification).Path /= Slash
3833 and then Check_Project
3834 (The_Unit_Data.File_Names
3835 (Specification).Project,
3836 Project, In_Tree, Extending)
3839 -- The unit is part of the project, it has
3840 -- a spec, but no body. We add to the Interface
3841 -- ALIs the ALI file corresponding to the spec.
3844 (The_Unit_Data.File_Names (Specification).Name);
3849 "%% is not an unit of this project",
3850 In_Tree.String_Elements.Table
3851 (Interfaces).Location);
3856 -- Multi_Language mode
3858 Next_Proj := Data.Extends;
3859 Source := Data.First_Source;
3862 while Source /= No_Source and then
3863 In_Tree.Sources.Table (Source).Unit /= Unit
3866 In_Tree.Sources.Table (Source).Next_In_Project;
3869 exit when Source /= No_Source or else
3870 Next_Proj = No_Project;
3873 In_Tree.Projects.Table (Next_Proj).First_Source;
3875 In_Tree.Projects.Table (Next_Proj).Extends;
3878 if Source /= No_Source then
3879 if In_Tree.Sources.Table (Source).Kind = Sep then
3880 Source := No_Source;
3882 elsif In_Tree.Sources.Table (Source).Kind = Spec
3884 In_Tree.Sources.Table (Source).Other_Part /=
3887 Source := In_Tree.Sources.Table (Source).Other_Part;
3891 if Source /= No_Source then
3892 if In_Tree.Sources.Table (Source).Project /= Project
3896 In_Tree.Sources.Table (Source).Project,
3899 Source := No_Source;
3903 if Source = No_Source then
3906 "%% is not an unit of this project",
3907 In_Tree.String_Elements.Table
3908 (Interfaces).Location);
3911 if In_Tree.Sources.Table (Source).Kind = Spec and then
3912 In_Tree.Sources.Table (Source).Other_Part /=
3916 In_Tree.Sources.Table (Source).Other_Part;
3919 String_Element_Table.Increment_Last
3920 (In_Tree.String_Elements);
3921 In_Tree.String_Elements.Table
3922 (String_Element_Table.Last
3923 (In_Tree.String_Elements)) :=
3925 Name_Id (In_Tree.Sources.Table (Source).Dep_Name),
3928 Name_Id (In_Tree.Sources.Table (Source).Dep_Name),
3930 In_Tree.String_Elements.Table
3931 (Interfaces).Location,
3933 Next => Interface_ALIs);
3934 Interface_ALIs := String_Element_Table.Last
3935 (In_Tree.String_Elements);
3943 In_Tree.String_Elements.Table (Interfaces).Next;
3946 -- Put the list of Interface ALIs in the project data
3948 Data.Lib_Interface_ALIs := Interface_ALIs;
3950 -- Check value of attribute Library_Auto_Init and set
3951 -- Lib_Auto_Init accordingly.
3953 if Lib_Auto_Init.Default then
3955 -- If no attribute Library_Auto_Init is declared, then
3956 -- set auto init only if it is supported.
3958 Data.Lib_Auto_Init := Auto_Init_Supported;
3961 Get_Name_String (Lib_Auto_Init.Value);
3962 To_Lower (Name_Buffer (1 .. Name_Len));
3964 if Name_Buffer (1 .. Name_Len) = "false" then
3965 Data.Lib_Auto_Init := False;
3967 elsif Name_Buffer (1 .. Name_Len) = "true" then
3968 if Auto_Init_Supported then
3969 Data.Lib_Auto_Init := True;
3972 -- Library_Auto_Init cannot be "true" if auto init
3977 "library auto init not supported " &
3979 Lib_Auto_Init.Location);
3985 "invalid value for attribute Library_Auto_Init",
3986 Lib_Auto_Init.Location);
3991 -- If attribute Library_Src_Dir is defined and not the
3992 -- empty string, check if the directory exist and is not
3993 -- the object directory or one of the source directories.
3994 -- This is the directory where copies of the interface
3995 -- sources will be copied. Note that this directory may be
3996 -- the library directory.
3998 if Lib_Src_Dir.Value /= Empty_String then
4000 Dir_Id : constant File_Name_Type :=
4001 File_Name_Type (Lib_Src_Dir.Value);
4008 Data.Display_Directory,
4009 Data.Library_Src_Dir,
4010 Data.Display_Library_Src_Dir,
4011 Create => "library source copy",
4012 Location => Lib_Src_Dir.Location);
4014 -- If directory does not exist, report an error
4016 if Data.Library_Src_Dir = No_Path then
4018 -- Get the absolute name of the library directory
4019 -- that does not exist, to report an error.
4022 Dir_Name : constant String :=
4023 Get_Name_String (Dir_Id);
4026 if Is_Absolute_Path (Dir_Name) then
4027 Err_Vars.Error_Msg_File_1 := Dir_Id;
4030 Get_Name_String (Data.Directory);
4032 if Name_Buffer (Name_Len) /=
4035 Name_Len := Name_Len + 1;
4036 Name_Buffer (Name_Len) :=
4037 Directory_Separator;
4042 Name_Len + Dir_Name'Length) :=
4044 Name_Len := Name_Len + Dir_Name'Length;
4045 Err_Vars.Error_Msg_Name_1 := Name_Find;
4052 "Directory { does not exist",
4053 Lib_Src_Dir.Location);
4056 -- Report an error if it is the same as the object
4059 elsif Data.Library_Src_Dir = Data.Object_Directory then
4062 "directory to copy interfaces cannot be " &
4063 "the object directory",
4064 Lib_Src_Dir.Location);
4065 Data.Library_Src_Dir := No_Path;
4069 Src_Dirs : String_List_Id;
4070 Src_Dir : String_Element;
4073 -- Interface copy directory cannot be one of the source
4074 -- directory of the current project.
4076 Src_Dirs := Data.Source_Dirs;
4077 while Src_Dirs /= Nil_String loop
4078 Src_Dir := In_Tree.String_Elements.Table
4081 -- Report error if it is one of the source directories
4083 if Data.Library_Src_Dir =
4084 Path_Name_Type (Src_Dir.Value)
4088 "directory to copy interfaces cannot " &
4089 "be one of the source directories",
4090 Lib_Src_Dir.Location);
4091 Data.Library_Src_Dir := No_Path;
4095 Src_Dirs := Src_Dir.Next;
4098 if Data.Library_Src_Dir /= No_Path then
4100 -- It cannot be a source directory of any other
4103 Project_Loop : for Pid in 1 ..
4104 Project_Table.Last (In_Tree.Projects)
4107 In_Tree.Projects.Table (Pid).Source_Dirs;
4108 Dir_Loop : while Src_Dirs /= Nil_String loop
4110 In_Tree.String_Elements.Table (Src_Dirs);
4112 -- Report error if it is one of the source
4115 if Data.Library_Src_Dir =
4116 Path_Name_Type (Src_Dir.Value)
4119 File_Name_Type (Src_Dir.Value);
4121 In_Tree.Projects.Table (Pid).Name;
4124 "directory to copy interfaces cannot " &
4125 "be the same as source directory { of " &
4127 Lib_Src_Dir.Location);
4128 Data.Library_Src_Dir := No_Path;
4132 Src_Dirs := Src_Dir.Next;
4134 end loop Project_Loop;
4138 -- In high verbosity, if there is a valid Library_Src_Dir,
4139 -- display its path name.
4141 if Data.Library_Src_Dir /= No_Path
4142 and then Current_Verbosity = High
4144 Write_Str ("Directory to copy interfaces =""");
4145 Write_Str (Get_Name_String (Data.Library_Src_Dir));
4152 -- Check the symbol related attributes
4154 -- First, the symbol policy
4156 if not Lib_Symbol_Policy.Default then
4158 Value : constant String :=
4160 (Get_Name_String (Lib_Symbol_Policy.Value));
4163 -- Symbol policy must hove one of a limited number of values
4165 if Value = "autonomous" or else Value = "default" then
4166 Data.Symbol_Data.Symbol_Policy := Autonomous;
4168 elsif Value = "compliant" then
4169 Data.Symbol_Data.Symbol_Policy := Compliant;
4171 elsif Value = "controlled" then
4172 Data.Symbol_Data.Symbol_Policy := Controlled;
4174 elsif Value = "restricted" then
4175 Data.Symbol_Data.Symbol_Policy := Restricted;
4177 elsif Value = "direct" then
4178 Data.Symbol_Data.Symbol_Policy := Direct;
4183 "illegal value for Library_Symbol_Policy",
4184 Lib_Symbol_Policy.Location);
4189 -- If attribute Library_Symbol_File is not specified, symbol policy
4190 -- cannot be Restricted.
4192 if Lib_Symbol_File.Default then
4193 if Data.Symbol_Data.Symbol_Policy = Restricted then
4196 "Library_Symbol_File needs to be defined when " &
4197 "symbol policy is Restricted",
4198 Lib_Symbol_Policy.Location);
4202 -- Library_Symbol_File is defined.
4204 Data.Symbol_Data.Symbol_File :=
4205 Path_Name_Type (Lib_Symbol_File.Value);
4207 Get_Name_String (Lib_Symbol_File.Value);
4209 if Name_Len = 0 then
4212 "symbol file name cannot be an empty string",
4213 Lib_Symbol_File.Location);
4216 OK := not Is_Absolute_Path (Name_Buffer (1 .. Name_Len));
4219 for J in 1 .. Name_Len loop
4220 if Name_Buffer (J) = '/'
4221 or else Name_Buffer (J) = Directory_Separator
4230 Error_Msg_File_1 := File_Name_Type (Lib_Symbol_File.Value);
4233 "symbol file name { is illegal. " &
4234 "Name canot include directory info.",
4235 Lib_Symbol_File.Location);
4240 -- If attribute Library_Reference_Symbol_File is not defined,
4241 -- symbol policy cannot be Compilant or Controlled.
4243 if Lib_Ref_Symbol_File.Default then
4244 if Data.Symbol_Data.Symbol_Policy = Compliant
4245 or else Data.Symbol_Data.Symbol_Policy = Controlled
4249 "a reference symbol file need to be defined",
4250 Lib_Symbol_Policy.Location);
4254 -- Library_Reference_Symbol_File is defined, check file exists
4256 Data.Symbol_Data.Reference :=
4257 Path_Name_Type (Lib_Ref_Symbol_File.Value);
4259 Get_Name_String (Lib_Ref_Symbol_File.Value);
4261 if Name_Len = 0 then
4264 "reference symbol file name cannot be an empty string",
4265 Lib_Symbol_File.Location);
4268 if not Is_Absolute_Path (Name_Buffer (1 .. Name_Len)) then
4270 Add_Str_To_Name_Buffer (Get_Name_String (Data.Directory));
4271 Add_Char_To_Name_Buffer (Directory_Separator);
4272 Add_Str_To_Name_Buffer
4273 (Get_Name_String (Lib_Ref_Symbol_File.Value));
4274 Data.Symbol_Data.Reference := Name_Find;
4277 if not Is_Regular_File
4278 (Get_Name_String (Data.Symbol_Data.Reference))
4281 File_Name_Type (Lib_Ref_Symbol_File.Value);
4283 -- For controlled and direct symbol policies, it is an error
4284 -- if the reference symbol file does not exist. For other
4285 -- symbol policies, this is just a warning
4288 Data.Symbol_Data.Symbol_Policy /= Controlled
4289 and then Data.Symbol_Data.Symbol_Policy /= Direct;
4293 "<library reference symbol file { does not exist",
4294 Lib_Ref_Symbol_File.Location);
4296 -- In addition in the non-controlled case, if symbol policy
4297 -- is Compliant, it is changed to Autonomous, because there
4298 -- is no reference to check against, and we don't want to
4299 -- fail in this case.
4301 if Data.Symbol_Data.Symbol_Policy /= Controlled then
4302 if Data.Symbol_Data.Symbol_Policy = Compliant then
4303 Data.Symbol_Data.Symbol_Policy := Autonomous;
4308 -- If both the reference symbol file and the symbol file are
4309 -- defined, then check that they are not the same file.
4311 if Data.Symbol_Data.Symbol_File /= No_Path then
4312 Get_Name_String (Data.Symbol_Data.Symbol_File);
4314 if Name_Len > 0 then
4316 Symb_Path : constant String :=
4319 (Data.Object_Directory) &
4320 Directory_Separator &
4321 Name_Buffer (1 .. Name_Len));
4322 Ref_Path : constant String :=
4325 (Data.Symbol_Data.Reference));
4327 if Symb_Path = Ref_Path then
4330 "library reference symbol file and library" &
4331 " symbol file cannot be the same file",
4332 Lib_Ref_Symbol_File.Location);
4340 end Check_Stand_Alone_Library;
4342 ----------------------------
4343 -- Compute_Directory_Last --
4344 ----------------------------
4346 function Compute_Directory_Last (Dir : String) return Natural is
4349 and then (Dir (Dir'Last - 1) = Directory_Separator
4350 or else Dir (Dir'Last - 1) = '/')
4352 return Dir'Last - 1;
4356 end Compute_Directory_Last;
4363 (Project : Project_Id;
4364 In_Tree : Project_Tree_Ref;
4366 Flag_Location : Source_Ptr)
4368 Real_Location : Source_Ptr := Flag_Location;
4369 Error_Buffer : String (1 .. 5_000);
4370 Error_Last : Natural := 0;
4371 Name_Number : Natural := 0;
4372 File_Number : Natural := 0;
4373 First : Positive := Msg'First;
4376 procedure Add (C : Character);
4377 -- Add a character to the buffer
4379 procedure Add (S : String);
4380 -- Add a string to the buffer
4383 -- Add a name to the buffer
4386 -- Add a file name to the buffer
4392 procedure Add (C : Character) is
4394 Error_Last := Error_Last + 1;
4395 Error_Buffer (Error_Last) := C;
4398 procedure Add (S : String) is
4400 Error_Buffer (Error_Last + 1 .. Error_Last + S'Length) := S;
4401 Error_Last := Error_Last + S'Length;
4408 procedure Add_File is
4409 File : File_Name_Type;
4412 File_Number := File_Number + 1;
4416 File := Err_Vars.Error_Msg_File_1;
4418 File := Err_Vars.Error_Msg_File_2;
4420 File := Err_Vars.Error_Msg_File_3;
4425 Get_Name_String (File);
4426 Add (Name_Buffer (1 .. Name_Len));
4434 procedure Add_Name is
4438 Name_Number := Name_Number + 1;
4442 Name := Err_Vars.Error_Msg_Name_1;
4444 Name := Err_Vars.Error_Msg_Name_2;
4446 Name := Err_Vars.Error_Msg_Name_3;
4451 Get_Name_String (Name);
4452 Add (Name_Buffer (1 .. Name_Len));
4456 -- Start of processing for Error_Msg
4459 -- If location of error is unknown, use the location of the project
4461 if Real_Location = No_Location then
4462 Real_Location := In_Tree.Projects.Table (Project).Location;
4465 if Error_Report = null then
4466 Prj.Err.Error_Msg (Msg, Real_Location);
4470 -- Ignore continuation character
4472 if Msg (First) = '\' then
4475 -- Warning character is always the first one in this package
4476 -- this is an undocumented kludge!!!
4478 elsif Msg (First) = '?' then
4482 elsif Msg (First) = '<' then
4485 if Err_Vars.Error_Msg_Warn then
4491 while Index <= Msg'Last loop
4492 if Msg (Index) = '{' then
4495 elsif Msg (Index) = '%' then
4496 if Index < Msg'Last and then Msg (Index + 1) = '%' then
4508 Error_Report (Error_Buffer (1 .. Error_Last), Project, In_Tree);
4511 ----------------------
4512 -- Find_Ada_Sources --
4513 ----------------------
4515 procedure Find_Ada_Sources
4516 (Project : Project_Id;
4517 In_Tree : Project_Tree_Ref;
4518 Data : in out Project_Data;
4519 Follow_Links : Boolean := False)
4521 Source_Dir : String_List_Id := Data.Source_Dirs;
4522 Element : String_Element;
4524 Current_Source : String_List_Id := Nil_String;
4525 Source_Recorded : Boolean := False;
4528 if Current_Verbosity = High then
4529 Write_Line ("Looking for sources:");
4532 -- For each subdirectory
4534 while Source_Dir /= Nil_String loop
4536 Source_Recorded := False;
4537 Element := In_Tree.String_Elements.Table (Source_Dir);
4538 if Element.Value /= No_Name then
4539 Get_Name_String (Element.Display_Value);
4542 Source_Directory : constant String :=
4543 Name_Buffer (1 .. Name_Len) & Directory_Separator;
4544 Dir_Last : constant Natural :=
4545 Compute_Directory_Last (Source_Directory);
4548 if Current_Verbosity = High then
4549 Write_Str ("Source_Dir = ");
4550 Write_Line (Source_Directory);
4553 -- We look to every entry in the source directory
4555 Open (Dir, Source_Directory
4556 (Source_Directory'First .. Dir_Last));
4559 Read (Dir, Name_Buffer, Name_Len);
4561 if Current_Verbosity = High then
4562 Write_Str (" Checking ");
4563 Write_Line (Name_Buffer (1 .. Name_Len));
4566 exit when Name_Len = 0;
4569 File_Name : constant File_Name_Type := Name_Find;
4570 Path : constant String :=
4572 (Name => Name_Buffer (1 .. Name_Len),
4573 Directory => Source_Directory
4574 (Source_Directory'First .. Dir_Last),
4575 Resolve_Links => Follow_Links,
4576 Case_Sensitive => True);
4577 Path_Name : Path_Name_Type;
4580 Name_Len := Path'Length;
4581 Name_Buffer (1 .. Name_Len) := Path;
4582 Path_Name := Name_Find;
4584 -- We attempt to register it as a source. However,
4585 -- there is no error if the file does not contain
4586 -- a valid source. But there is an error if we have
4587 -- a duplicate unit name.
4590 (File_Name => File_Name,
4591 Path_Name => Path_Name,
4595 Location => No_Location,
4596 Current_Source => Current_Source,
4597 Source_Recorded => Source_Recorded,
4598 Follow_Links => Follow_Links);
4607 when Directory_Error =>
4611 if Source_Recorded then
4612 In_Tree.String_Elements.Table (Source_Dir).Flag :=
4616 Source_Dir := Element.Next;
4619 if Current_Verbosity = High then
4620 Write_Line ("end Looking for sources.");
4623 -- If we have looked for sources and found none, then
4624 -- it is an error, except if it is an extending project.
4625 -- If a non extending project is not supposed to contain
4626 -- any source, then we never call Find_Ada_Sources.
4628 if Current_Source = Nil_String and then
4629 Data.Extends = No_Project
4631 Report_No_Sources (Project, "Ada", In_Tree, Data.Location);
4633 end Find_Ada_Sources;
4639 procedure Find_Sources
4640 (Project : Project_Id;
4641 In_Tree : Project_Tree_Ref;
4642 Data : in out Project_Data;
4643 For_Language : Language_Index;
4644 Follow_Links : Boolean := False)
4646 Source_Dir : String_List_Id := Data.Source_Dirs;
4647 Element : String_Element;
4649 Current_Source : String_List_Id := Nil_String;
4650 Source_Recorded : Boolean := False;
4653 if Current_Verbosity = High then
4654 Write_Line ("Looking for sources:");
4657 -- For each subdirectory
4659 while Source_Dir /= Nil_String loop
4661 Source_Recorded := False;
4662 Element := In_Tree.String_Elements.Table (Source_Dir);
4664 if Element.Value /= No_Name then
4665 Get_Name_String (Element.Display_Value);
4668 Source_Directory : constant String :=
4669 Name_Buffer (1 .. Name_Len) &
4670 Directory_Separator;
4672 Dir_Last : constant Natural :=
4673 Compute_Directory_Last (Source_Directory);
4676 if Current_Verbosity = High then
4677 Write_Str ("Source_Dir = ");
4678 Write_Line (Source_Directory);
4681 -- We look to every entry in the source directory
4683 Open (Dir, Source_Directory
4684 (Source_Directory'First .. Dir_Last));
4687 Read (Dir, Name_Buffer, Name_Len);
4689 if Current_Verbosity = High then
4690 Write_Str (" Checking ");
4691 Write_Line (Name_Buffer (1 .. Name_Len));
4694 exit when Name_Len = 0;
4697 File_Name : constant File_Name_Type := Name_Find;
4698 Path : constant String :=
4700 (Name => Name_Buffer (1 .. Name_Len),
4701 Directory => Source_Directory
4702 (Source_Directory'First .. Dir_Last),
4703 Resolve_Links => Follow_Links,
4704 Case_Sensitive => True);
4705 Path_Name : Path_Name_Type;
4708 Name_Len := Path'Length;
4709 Name_Buffer (1 .. Name_Len) := Path;
4710 Path_Name := Name_Find;
4712 if For_Language = Ada_Language_Index then
4714 -- We attempt to register it as a source. However,
4715 -- there is no error if the file does not contain
4716 -- a valid source. But there is an error if we have
4717 -- a duplicate unit name.
4720 (File_Name => File_Name,
4721 Path_Name => Path_Name,
4725 Location => No_Location,
4726 Current_Source => Current_Source,
4727 Source_Recorded => Source_Recorded,
4728 Follow_Links => Follow_Links);
4732 (File_Name => File_Name,
4733 Path_Name => Path_Name,
4737 Location => No_Location,
4738 Language => For_Language,
4740 Body_Suffix_Of (For_Language, Data, In_Tree),
4741 Naming_Exception => False);
4751 when Directory_Error =>
4755 if Source_Recorded then
4756 In_Tree.String_Elements.Table (Source_Dir).Flag :=
4760 Source_Dir := Element.Next;
4763 if Current_Verbosity = High then
4764 Write_Line ("end Looking for sources.");
4767 if For_Language = Ada_Language_Index then
4769 -- If we have looked for sources and found none, then
4770 -- it is an error, except if it is an extending project.
4771 -- If a non extending project is not supposed to contain
4772 -- any source, then we never call Find_Sources.
4774 if Current_Source /= Nil_String then
4775 Data.Ada_Sources_Present := True;
4777 elsif Data.Extends = No_Project then
4778 Report_No_Sources (Project, "Ada", In_Tree, Data.Location);
4783 --------------------------------
4784 -- Free_Ada_Naming_Exceptions --
4785 --------------------------------
4787 procedure Free_Ada_Naming_Exceptions is
4789 Ada_Naming_Exception_Table.Set_Last (0);
4790 Ada_Naming_Exceptions.Reset;
4791 Reverse_Ada_Naming_Exceptions.Reset;
4792 end Free_Ada_Naming_Exceptions;
4794 ---------------------
4795 -- Get_Directories --
4796 ---------------------
4798 procedure Get_Directories
4799 (Project : Project_Id;
4800 In_Tree : Project_Tree_Ref;
4801 Data : in out Project_Data)
4803 Object_Dir : constant Variable_Value :=
4805 (Name_Object_Dir, Data.Decl.Attributes, In_Tree);
4807 Exec_Dir : constant Variable_Value :=
4809 (Name_Exec_Dir, Data.Decl.Attributes, In_Tree);
4811 Source_Dirs : constant Variable_Value :=
4813 (Name_Source_Dirs, Data.Decl.Attributes, In_Tree);
4815 Excluded_Source_Dirs : constant Variable_Value :=
4817 (Name_Excluded_Source_Dirs,
4818 Data.Decl.Attributes,
4821 Source_Files : constant Variable_Value :=
4823 (Name_Source_Files, Data.Decl.Attributes, In_Tree);
4825 Last_Source_Dir : String_List_Id := Nil_String;
4827 procedure Find_Source_Dirs
4828 (From : File_Name_Type;
4829 Location : Source_Ptr;
4830 Removed : Boolean := False);
4831 -- Find one or several source directories, and add (or remove, if
4832 -- Removed is True) them to the list of source directories of the
4835 ----------------------
4836 -- Find_Source_Dirs --
4837 ----------------------
4839 procedure Find_Source_Dirs
4840 (From : File_Name_Type;
4841 Location : Source_Ptr;
4842 Removed : Boolean := False)
4844 Directory : constant String := Get_Name_String (From);
4845 Element : String_Element;
4847 procedure Recursive_Find_Dirs (Path : Name_Id);
4848 -- Find all the subdirectories (recursively) of Path and add them
4849 -- to the list of source directories of the project.
4851 -------------------------
4852 -- Recursive_Find_Dirs --
4853 -------------------------
4855 procedure Recursive_Find_Dirs (Path : Name_Id) is
4857 Name : String (1 .. 250);
4859 List : String_List_Id := Data.Source_Dirs;
4860 Prev : String_List_Id := Nil_String;
4861 Element : String_Element;
4862 Found : Boolean := False;
4864 Non_Canonical_Path : Name_Id := No_Name;
4865 Canonical_Path : Name_Id := No_Name;
4867 The_Path : constant String :=
4868 Normalize_Pathname (Get_Name_String (Path)) &
4869 Directory_Separator;
4871 The_Path_Last : constant Natural :=
4872 Compute_Directory_Last (The_Path);
4875 Name_Len := The_Path_Last - The_Path'First + 1;
4876 Name_Buffer (1 .. Name_Len) :=
4877 The_Path (The_Path'First .. The_Path_Last);
4878 Non_Canonical_Path := Name_Find;
4879 Get_Name_String (Non_Canonical_Path);
4880 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
4881 Canonical_Path := Name_Find;
4883 -- To avoid processing the same directory several times, check
4884 -- if the directory is already in Recursive_Dirs. If it is,
4885 -- then there is nothing to do, just return. If it is not, put
4886 -- it there and continue recursive processing.
4889 if Recursive_Dirs.Get (Canonical_Path) then
4892 Recursive_Dirs.Set (Canonical_Path, True);
4896 -- Check if directory is already in list
4898 while List /= Nil_String loop
4899 Element := In_Tree.String_Elements.Table (List);
4901 if Element.Value /= No_Name then
4902 Found := Element.Value = Canonical_Path;
4907 List := Element.Next;
4910 -- If directory is not already in list, put it there
4912 if (not Removed) and (not Found) then
4913 if Current_Verbosity = High then
4915 Write_Line (The_Path (The_Path'First .. The_Path_Last));
4918 String_Element_Table.Increment_Last
4919 (In_Tree.String_Elements);
4921 (Value => Canonical_Path,
4922 Display_Value => Non_Canonical_Path,
4923 Location => No_Location,
4928 -- Case of first source directory
4930 if Last_Source_Dir = Nil_String then
4931 Data.Source_Dirs := String_Element_Table.Last
4932 (In_Tree.String_Elements);
4934 -- Here we already have source directories
4937 -- Link the previous last to the new one
4939 In_Tree.String_Elements.Table
4940 (Last_Source_Dir).Next :=
4941 String_Element_Table.Last
4942 (In_Tree.String_Elements);
4945 -- And register this source directory as the new last
4947 Last_Source_Dir := String_Element_Table.Last
4948 (In_Tree.String_Elements);
4949 In_Tree.String_Elements.Table (Last_Source_Dir) :=
4952 elsif Removed and Found then
4953 if Prev = Nil_String then
4955 In_Tree.String_Elements.Table (List).Next;
4957 In_Tree.String_Elements.Table (Prev).Next :=
4958 In_Tree.String_Elements.Table (List).Next;
4962 -- Now look for subdirectories. We do that even when this
4963 -- directory is already in the list, because some of its
4964 -- subdirectories may not be in the list yet.
4966 Open (Dir, The_Path (The_Path'First .. The_Path_Last));
4969 Read (Dir, Name, Last);
4972 if Name (1 .. Last) /= "."
4973 and then Name (1 .. Last) /= ".."
4975 -- Avoid . and .. directories
4977 if Current_Verbosity = High then
4978 Write_Str (" Checking ");
4979 Write_Line (Name (1 .. Last));
4983 Path_Name : constant String :=
4985 (Name => Name (1 .. Last),
4988 (The_Path'First .. The_Path_Last),
4989 Resolve_Links => False,
4990 Case_Sensitive => True);
4993 if Is_Directory (Path_Name) then
4995 -- We have found a new subdirectory, call self
4997 Name_Len := Path_Name'Length;
4998 Name_Buffer (1 .. Name_Len) := Path_Name;
4999 Recursive_Find_Dirs (Name_Find);
5008 when Directory_Error =>
5010 end Recursive_Find_Dirs;
5012 -- Start of processing for Find_Source_Dirs
5015 if Current_Verbosity = High and then not Removed then
5016 Write_Str ("Find_Source_Dirs (""");
5017 Write_Str (Directory);
5021 -- First, check if we are looking for a directory tree, indicated
5022 -- by "/**" at the end.
5024 if Directory'Length >= 3
5025 and then Directory (Directory'Last - 1 .. Directory'Last) = "**"
5026 and then (Directory (Directory'Last - 2) = '/'
5028 Directory (Directory'Last - 2) = Directory_Separator)
5031 Data.Known_Order_Of_Source_Dirs := False;
5034 Name_Len := Directory'Length - 3;
5036 if Name_Len = 0 then
5038 -- Case of "/**": all directories in file system
5041 Name_Buffer (1) := Directory (Directory'First);
5044 Name_Buffer (1 .. Name_Len) :=
5045 Directory (Directory'First .. Directory'Last - 3);
5048 if Current_Verbosity = High then
5049 Write_Str ("Looking for all subdirectories of """);
5050 Write_Str (Name_Buffer (1 .. Name_Len));
5055 Base_Dir : constant File_Name_Type := Name_Find;
5056 Root_Dir : constant String :=
5058 (Name => Get_Name_String (Base_Dir),
5060 Get_Name_String (Data.Display_Directory),
5061 Resolve_Links => False,
5062 Case_Sensitive => True);
5065 if Root_Dir'Length = 0 then
5066 Err_Vars.Error_Msg_File_1 := Base_Dir;
5068 if Location = No_Location then
5071 "{ is not a valid directory.",
5076 "{ is not a valid directory.",
5081 -- We have an existing directory, we register it and all of
5082 -- its subdirectories.
5084 if Current_Verbosity = High then
5085 Write_Line ("Looking for source directories:");
5088 Name_Len := Root_Dir'Length;
5089 Name_Buffer (1 .. Name_Len) := Root_Dir;
5090 Recursive_Find_Dirs (Name_Find);
5092 if Current_Verbosity = High then
5093 Write_Line ("End of looking for source directories.");
5098 -- We have a single directory
5102 Path_Name : Path_Name_Type;
5103 Display_Path_Name : Path_Name_Type;
5104 List : String_List_Id;
5105 Prev : String_List_Id;
5112 Data.Display_Directory,
5116 if Path_Name = No_Path then
5117 Err_Vars.Error_Msg_File_1 := From;
5119 if Location = No_Location then
5122 "{ is not a valid directory",
5127 "{ is not a valid directory",
5133 Path : constant String :=
5134 Get_Name_String (Path_Name) &
5135 Directory_Separator;
5136 Last_Path : constant Natural :=
5137 Compute_Directory_Last (Path);
5139 Display_Path : constant String :=
5141 (Display_Path_Name) &
5142 Directory_Separator;
5143 Last_Display_Path : constant Natural :=
5144 Compute_Directory_Last
5146 Display_Path_Id : Name_Id;
5150 Add_Str_To_Name_Buffer (Path (Path'First .. Last_Path));
5151 Path_Id := Name_Find;
5153 Add_Str_To_Name_Buffer
5155 (Display_Path'First .. Last_Display_Path));
5156 Display_Path_Id := Name_Find;
5160 -- As it is an existing directory, we add it to the
5161 -- list of directories.
5163 String_Element_Table.Increment_Last
5164 (In_Tree.String_Elements);
5168 Display_Value => Display_Path_Id,
5169 Location => No_Location,
5171 Next => Nil_String);
5173 if Last_Source_Dir = Nil_String then
5175 -- This is the first source directory
5177 Data.Source_Dirs := String_Element_Table.Last
5178 (In_Tree.String_Elements);
5181 -- We already have source directories, link the
5182 -- previous last to the new one.
5184 In_Tree.String_Elements.Table
5185 (Last_Source_Dir).Next :=
5186 String_Element_Table.Last
5187 (In_Tree.String_Elements);
5190 -- And register this source directory as the new last
5192 Last_Source_Dir := String_Element_Table.Last
5193 (In_Tree.String_Elements);
5194 In_Tree.String_Elements.Table
5195 (Last_Source_Dir) := Element;
5198 -- Remove source dir, if present
5200 List := Data.Source_Dirs;
5203 -- Look for source dir in current list
5205 while List /= Nil_String loop
5206 Element := In_Tree.String_Elements.Table (List);
5207 exit when Element.Value = Path_Id;
5209 List := Element.Next;
5212 if List /= Nil_String then
5213 -- Source dir was found, remove it from the list
5215 if Prev = Nil_String then
5217 In_Tree.String_Elements.Table (List).Next;
5220 In_Tree.String_Elements.Table (Prev).Next :=
5221 In_Tree.String_Elements.Table (List).Next;
5229 end Find_Source_Dirs;
5231 -- Start of processing for Get_Directories
5234 if Current_Verbosity = High then
5235 Write_Line ("Starting to look for directories");
5238 -- Check the object directory
5240 pragma Assert (Object_Dir.Kind = Single,
5241 "Object_Dir is not a single string");
5243 -- We set the object directory to its default
5245 Data.Object_Directory := Data.Directory;
5246 Data.Display_Object_Dir := Data.Display_Directory;
5248 if Object_Dir.Value /= Empty_String then
5249 Get_Name_String (Object_Dir.Value);
5251 if Name_Len = 0 then
5254 "Object_Dir cannot be empty",
5255 Object_Dir.Location);
5258 -- We check that the specified object directory does exist
5263 File_Name_Type (Object_Dir.Value),
5264 Data.Display_Directory,
5265 Data.Object_Directory,
5266 Data.Display_Object_Dir,
5268 Location => Object_Dir.Location);
5270 if Data.Object_Directory = No_Path then
5272 -- The object directory does not exist, report an error if the
5273 -- project is not externally built.
5275 if not Data.Externally_Built then
5276 Err_Vars.Error_Msg_File_1 :=
5277 File_Name_Type (Object_Dir.Value);
5280 "the object directory { cannot be found",
5284 -- Do not keep a nil Object_Directory. Set it to the specified
5285 -- (relative or absolute) path. This is for the benefit of
5286 -- tools that recover from errors; for example, these tools
5287 -- could create the non existent directory.
5289 Data.Display_Object_Dir := Path_Name_Type (Object_Dir.Value);
5290 Get_Name_String (Object_Dir.Value);
5291 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
5292 Data.Object_Directory := Name_Find;
5297 if Current_Verbosity = High then
5298 if Data.Object_Directory = No_Path then
5299 Write_Line ("No object directory");
5301 Write_Str ("Object directory: """);
5302 Write_Str (Get_Name_String (Data.Display_Object_Dir));
5307 -- Check the exec directory
5309 pragma Assert (Exec_Dir.Kind = Single,
5310 "Exec_Dir is not a single string");
5312 -- We set the object directory to its default
5314 Data.Exec_Directory := Data.Object_Directory;
5315 Data.Display_Exec_Dir := Data.Display_Object_Dir;
5317 if Exec_Dir.Value /= Empty_String then
5318 Get_Name_String (Exec_Dir.Value);
5320 if Name_Len = 0 then
5323 "Exec_Dir cannot be empty",
5327 -- We check that the specified object directory does exist
5332 File_Name_Type (Exec_Dir.Value),
5333 Data.Display_Directory,
5334 Data.Exec_Directory,
5335 Data.Display_Exec_Dir,
5337 Location => Exec_Dir.Location);
5339 if Data.Exec_Directory = No_Path then
5340 Err_Vars.Error_Msg_File_1 := File_Name_Type (Exec_Dir.Value);
5343 "the exec directory { cannot be found",
5349 if Current_Verbosity = High then
5350 if Data.Exec_Directory = No_Path then
5351 Write_Line ("No exec directory");
5353 Write_Str ("Exec directory: """);
5354 Write_Str (Get_Name_String (Data.Display_Exec_Dir));
5359 -- Look for the source directories
5361 if Current_Verbosity = High then
5362 Write_Line ("Starting to look for source directories");
5365 pragma Assert (Source_Dirs.Kind = List, "Source_Dirs is not a list");
5367 if (not Source_Files.Default) and then
5368 Source_Files.Values = Nil_String
5370 Data.Source_Dirs := Nil_String;
5372 if Data.Extends = No_Project
5373 and then Data.Object_Directory = Data.Directory
5375 Data.Object_Directory := No_Path;
5378 elsif Source_Dirs.Default then
5380 -- No Source_Dirs specified: the single source directory is the one
5381 -- containing the project file
5383 String_Element_Table.Increment_Last
5384 (In_Tree.String_Elements);
5385 Data.Source_Dirs := String_Element_Table.Last
5386 (In_Tree.String_Elements);
5387 In_Tree.String_Elements.Table (Data.Source_Dirs) :=
5388 (Value => Name_Id (Data.Directory),
5389 Display_Value => Name_Id (Data.Display_Directory),
5390 Location => No_Location,
5395 if Current_Verbosity = High then
5396 Write_Line ("Single source directory:");
5398 Write_Str (Get_Name_String (Data.Display_Directory));
5402 elsif Source_Dirs.Values = Nil_String then
5404 -- If Source_Dirs is an empty string list, this means that this
5405 -- project contains no source. For projects that don't extend other
5406 -- projects, this also means that there is no need for an object
5407 -- directory, if not specified.
5409 if Data.Extends = No_Project
5410 and then Data.Object_Directory = Data.Directory
5412 Data.Object_Directory := No_Path;
5415 Data.Source_Dirs := Nil_String;
5419 Source_Dir : String_List_Id;
5420 Element : String_Element;
5423 -- Process the source directories for each element of the list
5425 Source_Dir := Source_Dirs.Values;
5426 while Source_Dir /= Nil_String loop
5428 In_Tree.String_Elements.Table (Source_Dir);
5430 (File_Name_Type (Element.Value), Element.Location);
5431 Source_Dir := Element.Next;
5436 if not Excluded_Source_Dirs.Default
5437 and then Excluded_Source_Dirs.Values /= Nil_String
5440 Source_Dir : String_List_Id;
5441 Element : String_Element;
5444 -- Process the source directories for each element of the list
5446 Source_Dir := Excluded_Source_Dirs.Values;
5447 while Source_Dir /= Nil_String loop
5449 In_Tree.String_Elements.Table (Source_Dir);
5451 (File_Name_Type (Element.Value),
5454 Source_Dir := Element.Next;
5459 if Current_Verbosity = High then
5460 Write_Line ("Putting source directories in canonical cases");
5464 Current : String_List_Id := Data.Source_Dirs;
5465 Element : String_Element;
5468 while Current /= Nil_String loop
5469 Element := In_Tree.String_Elements.Table (Current);
5470 if Element.Value /= No_Name then
5471 Get_Name_String (Element.Value);
5472 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
5473 Element.Value := Name_Find;
5474 In_Tree.String_Elements.Table (Current) := Element;
5477 Current := Element.Next;
5481 end Get_Directories;
5488 (Project : Project_Id;
5489 In_Tree : Project_Tree_Ref;
5490 Data : in out Project_Data)
5492 Mains : constant Variable_Value :=
5493 Prj.Util.Value_Of (Name_Main, Data.Decl.Attributes, In_Tree);
5496 Data.Mains := Mains.Values;
5498 -- If no Mains were specified, and if we are an extending project,
5499 -- inherit the Mains from the project we are extending.
5501 if Mains.Default then
5502 if Data.Extends /= No_Project then
5504 In_Tree.Projects.Table (Data.Extends).Mains;
5507 -- In a library project file, Main cannot be specified
5509 elsif Data.Library then
5512 "a library project file cannot have Main specified",
5517 ---------------------------
5518 -- Get_Sources_From_File --
5519 ---------------------------
5521 procedure Get_Sources_From_File
5523 Location : Source_Ptr;
5524 Project : Project_Id;
5525 In_Tree : Project_Tree_Ref)
5527 File : Prj.Util.Text_File;
5528 Line : String (1 .. 250);
5530 Source_Name : File_Name_Type;
5531 Name_Loc : Name_Location;
5534 if Get_Mode = Ada_Only then
5538 if Current_Verbosity = High then
5539 Write_Str ("Opening """);
5546 Prj.Util.Open (File, Path);
5548 if not Prj.Util.Is_Valid (File) then
5549 Error_Msg (Project, In_Tree, "file does not exist", Location);
5551 -- Read the lines one by one
5553 while not Prj.Util.End_Of_File (File) loop
5554 Prj.Util.Get_Line (File, Line, Last);
5556 -- A non empty, non comment line should contain a file name
5559 and then (Last = 1 or else Line (1 .. 2) /= "--")
5561 -- ??? we should check that there is no directory information
5564 Name_Buffer (1 .. Name_Len) := Line (1 .. Last);
5565 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
5566 Source_Name := Name_Find;
5567 Name_Loc := Source_Names.Get (Source_Name);
5569 if Name_Loc = No_Name_Location then
5571 (Name => Source_Name,
5572 Location => Location,
5573 Source => No_Source,
5578 Source_Names.Set (Source_Name, Name_Loc);
5582 Prj.Util.Close (File);
5585 end Get_Sources_From_File;
5592 (In_Tree : Project_Tree_Ref;
5593 Canonical_File_Name : File_Name_Type;
5594 Naming : Naming_Data;
5595 Exception_Id : out Ada_Naming_Exception_Id;
5596 Unit_Name : out Name_Id;
5597 Unit_Kind : out Spec_Or_Body;
5598 Needs_Pragma : out Boolean)
5600 Info_Id : Ada_Naming_Exception_Id :=
5601 Ada_Naming_Exceptions.Get (Canonical_File_Name);
5602 VMS_Name : File_Name_Type;
5605 if Info_Id = No_Ada_Naming_Exception then
5606 if Hostparm.OpenVMS then
5607 VMS_Name := Canonical_File_Name;
5608 Get_Name_String (VMS_Name);
5610 if Name_Buffer (Name_Len) = '.' then
5611 Name_Len := Name_Len - 1;
5612 VMS_Name := Name_Find;
5615 Info_Id := Ada_Naming_Exceptions.Get (VMS_Name);
5620 if Info_Id /= No_Ada_Naming_Exception then
5621 Exception_Id := Info_Id;
5622 Unit_Name := No_Name;
5623 Unit_Kind := Specification;
5624 Needs_Pragma := True;
5628 Needs_Pragma := False;
5629 Exception_Id := No_Ada_Naming_Exception;
5631 Get_Name_String (Canonical_File_Name);
5634 File : String := Name_Buffer (1 .. Name_Len);
5635 First : constant Positive := File'First;
5636 Last : Natural := File'Last;
5637 Standard_GNAT : Boolean;
5641 Spec_Suffix_Id_Of (In_Tree, "ada", Naming) = Default_Ada_Spec_Suffix
5643 Body_Suffix_Id_Of (In_Tree, "ada", Naming) = Default_Ada_Body_Suffix;
5645 -- Check if the end of the file name is Specification_Append
5647 Get_Name_String (Spec_Suffix_Id_Of (In_Tree, "ada", Naming));
5649 if File'Length > Name_Len
5650 and then File (Last - Name_Len + 1 .. Last) =
5651 Name_Buffer (1 .. Name_Len)
5655 Unit_Kind := Specification;
5656 Last := Last - Name_Len;
5658 if Current_Verbosity = High then
5659 Write_Str (" Specification: ");
5660 Write_Line (File (First .. Last));
5664 Get_Name_String (Body_Suffix_Id_Of (In_Tree, "ada", Naming));
5666 -- Check if the end of the file name is Body_Append
5668 if File'Length > Name_Len
5669 and then File (Last - Name_Len + 1 .. Last) =
5670 Name_Buffer (1 .. Name_Len)
5674 Unit_Kind := Body_Part;
5675 Last := Last - Name_Len;
5677 if Current_Verbosity = High then
5678 Write_Str (" Body: ");
5679 Write_Line (File (First .. Last));
5682 elsif Naming.Separate_Suffix /=
5683 Body_Suffix_Id_Of (In_Tree, "ada", Naming)
5685 Get_Name_String (Naming.Separate_Suffix);
5687 -- Check if the end of the file name is Separate_Append
5689 if File'Length > Name_Len
5690 and then File (Last - Name_Len + 1 .. Last) =
5691 Name_Buffer (1 .. Name_Len)
5693 -- We have a separate (a body)
5695 Unit_Kind := Body_Part;
5696 Last := Last - Name_Len;
5698 if Current_Verbosity = High then
5699 Write_Str (" Separate: ");
5700 Write_Line (File (First .. Last));
5714 -- This is not a source file
5716 Unit_Name := No_Name;
5717 Unit_Kind := Specification;
5719 if Current_Verbosity = High then
5720 Write_Line (" Not a valid file name.");
5726 Get_Name_String (Naming.Dot_Replacement);
5728 Standard_GNAT and then Name_Buffer (1 .. Name_Len) = "-";
5730 if Name_Buffer (1 .. Name_Len) /= "." then
5732 -- If Dot_Replacement is not a single dot, then there should not
5733 -- be any dot in the name.
5735 for Index in First .. Last loop
5736 if File (Index) = '.' then
5737 if Current_Verbosity = High then
5739 (" Not a valid file name (some dot not replaced).");
5742 Unit_Name := No_Name;
5748 -- Replace the substring Dot_Replacement with dots
5751 Index : Positive := First;
5754 while Index <= Last - Name_Len + 1 loop
5756 if File (Index .. Index + Name_Len - 1) =
5757 Name_Buffer (1 .. Name_Len)
5759 File (Index) := '.';
5761 if Name_Len > 1 and then Index < Last then
5762 File (Index + 1 .. Last - Name_Len + 1) :=
5763 File (Index + Name_Len .. Last);
5766 Last := Last - Name_Len + 1;
5774 -- Check if the casing is right
5777 Src : String := File (First .. Last);
5778 Src_Last : Positive := Last;
5781 case Naming.Casing is
5782 when All_Lower_Case =>
5785 Mapping => Lower_Case_Map);
5787 when All_Upper_Case =>
5790 Mapping => Upper_Case_Map);
5792 when Mixed_Case | Unknown =>
5796 if Src /= File (First .. Last) then
5797 if Current_Verbosity = High then
5798 Write_Line (" Not a valid file name (casing).");
5801 Unit_Name := No_Name;
5805 -- We put the name in lower case
5809 Mapping => Lower_Case_Map);
5811 -- In the standard GNAT naming scheme, check for special cases:
5812 -- children or separates of A, G, I or S, and run time sources.
5814 if Standard_GNAT and then Src'Length >= 3 then
5816 S1 : constant Character := Src (Src'First);
5817 S2 : constant Character := Src (Src'First + 1);
5818 S3 : constant Character := Src (Src'First + 2);
5826 -- Children or separates of packages A, G, I or S. These
5827 -- names are x__ ... or x~... (where x is a, g, i, or s).
5828 -- Both versions (x__... and x~...) are allowed in all
5829 -- platforms, because it is not possible to know the
5830 -- platform before processing of the project files.
5832 if S2 = '_' and then S3 = '_' then
5833 Src (Src'First + 1) := '.';
5834 Src_Last := Src_Last - 1;
5835 Src (Src'First + 2 .. Src_Last) :=
5836 Src (Src'First + 3 .. Src_Last + 1);
5839 Src (Src'First + 1) := '.';
5841 -- If it is potentially a run time source, disable
5842 -- filling of the mapping file to avoid warnings.
5845 Set_Mapping_File_Initial_State_To_Empty;
5851 if Current_Verbosity = High then
5853 Write_Line (Src (Src'First .. Src_Last));
5856 -- Now, we check if this name is a valid unit name
5859 (Name => Src (Src'First .. Src_Last), Unit => Unit_Name);
5869 function Hash (Unit : Unit_Info) return Header_Num is
5871 return Header_Num (Unit.Unit mod 2048);
5874 -----------------------
5875 -- Is_Illegal_Suffix --
5876 -----------------------
5878 function Is_Illegal_Suffix
5880 Dot_Replacement_Is_A_Single_Dot : Boolean) return Boolean
5883 if Suffix'Length = 0 or else Index (Suffix, ".") = 0 then
5887 -- If dot replacement is a single dot, and first character of suffix is
5890 if Dot_Replacement_Is_A_Single_Dot
5891 and then Suffix (Suffix'First) = '.'
5893 for Index in Suffix'First + 1 .. Suffix'Last loop
5895 -- If there is another dot
5897 if Suffix (Index) = '.' then
5899 -- It is illegal to have a letter following the initial dot
5901 return Is_Letter (Suffix (Suffix'First + 1));
5909 end Is_Illegal_Suffix;
5911 ----------------------
5912 -- Locate_Directory --
5913 ----------------------
5915 procedure Locate_Directory
5916 (Project : Project_Id;
5917 In_Tree : Project_Tree_Ref;
5918 Name : File_Name_Type;
5919 Parent : Path_Name_Type;
5920 Dir : out Path_Name_Type;
5921 Display : out Path_Name_Type;
5922 Create : String := "";
5923 Location : Source_Ptr := No_Location)
5925 The_Name : String := Get_Name_String (Name);
5927 The_Parent : constant String :=
5928 Get_Name_String (Parent) & Directory_Separator;
5930 The_Parent_Last : constant Natural :=
5931 Compute_Directory_Last (The_Parent);
5933 Full_Name : File_Name_Type;
5936 -- Convert '/' to directory separator (for Windows)
5938 for J in The_Name'Range loop
5939 if The_Name (J) = '/' then
5940 The_Name (J) := Directory_Separator;
5944 if Current_Verbosity = High then
5945 Write_Str ("Locate_Directory (""");
5946 Write_Str (The_Name);
5947 Write_Str (""", """);
5948 Write_Str (The_Parent);
5955 if Is_Absolute_Path (The_Name) then
5960 Add_Str_To_Name_Buffer
5961 (The_Parent (The_Parent'First .. The_Parent_Last));
5962 Add_Str_To_Name_Buffer (The_Name);
5963 Full_Name := Name_Find;
5967 Full_Path_Name : constant String := Get_Name_String (Full_Name);
5970 if Setup_Projects and then Create'Length > 0
5971 and then not Is_Directory (Full_Path_Name)
5974 Create_Path (Full_Path_Name);
5976 if not Quiet_Output then
5978 Write_Str (" directory """);
5979 Write_Str (Full_Path_Name);
5980 Write_Line (""" created");
5987 "could not create " & Create &
5988 " directory " & Full_Path_Name,
5993 if Is_Directory (Full_Path_Name) then
5995 Normed : constant String :=
5998 Resolve_Links => False,
5999 Case_Sensitive => True);
6001 Canonical_Path : constant String :=
6004 Resolve_Links => True,
6005 Case_Sensitive => False);
6008 Name_Len := Normed'Length;
6009 Name_Buffer (1 .. Name_Len) := Normed;
6010 Display := Name_Find;
6012 Name_Len := Canonical_Path'Length;
6013 Name_Buffer (1 .. Name_Len) := Canonical_Path;
6018 end Locate_Directory;
6020 ----------------------
6021 -- Look_For_Sources --
6022 ----------------------
6024 procedure Look_For_Sources
6025 (Project : Project_Id;
6026 In_Tree : Project_Tree_Ref;
6027 Data : in out Project_Data;
6028 Follow_Links : Boolean)
6030 procedure Get_Path_Names_And_Record_Sources (Follow_Links : Boolean);
6031 -- Find the path names of the source files in the Source_Names table
6032 -- in the source directories and record those that are Ada sources.
6034 procedure Get_Sources_From_File
6036 Location : Source_Ptr);
6037 -- Get the sources of a project from a text file
6039 procedure Search_Directories (For_All_Sources : Boolean);
6040 -- Search the source directories to find the sources.
6041 -- If For_All_Sources is True, check each regular file name against
6042 -- the naming schemes of the different languages. Otherwise consider
6043 -- only the file names in the hash table Source_Names.
6045 ---------------------------------------
6046 -- Get_Path_Names_And_Record_Sources --
6047 ---------------------------------------
6049 procedure Get_Path_Names_And_Record_Sources (Follow_Links : Boolean) is
6050 Source_Dir : String_List_Id := Data.Source_Dirs;
6051 Element : String_Element;
6052 Path : Path_Name_Type;
6055 Name : File_Name_Type;
6056 Canonical_Name : File_Name_Type;
6057 Name_Str : String (1 .. 1_024);
6058 Last : Natural := 0;
6060 Current_Source : String_List_Id := Nil_String;
6061 First_Error : Boolean := True;
6062 Source_Recorded : Boolean := False;
6065 -- We look in all source directories for the file names in the
6066 -- hash table Source_Names
6068 while Source_Dir /= Nil_String loop
6069 Source_Recorded := False;
6070 Element := In_Tree.String_Elements.Table (Source_Dir);
6073 Dir_Path : constant String :=
6074 Get_Name_String (Element.Display_Value);
6076 if Current_Verbosity = High then
6077 Write_Str ("checking directory """);
6078 Write_Str (Dir_Path);
6082 Open (Dir, Dir_Path);
6085 Read (Dir, Name_Str, Last);
6089 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
6092 Canonical_Case_File_Name (Name_Str (1 .. Last));
6093 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
6094 Canonical_Name := Name_Find;
6096 NL := Source_Names.Get (Canonical_Name);
6098 if NL /= No_Name_Location and then not NL.Found then
6100 Source_Names.Set (Canonical_Name, NL);
6101 Name_Len := Dir_Path'Length;
6102 Name_Buffer (1 .. Name_Len) := Dir_Path;
6104 if Name_Buffer (Name_Len) /= Directory_Separator then
6105 Add_Char_To_Name_Buffer (Directory_Separator);
6108 Add_Str_To_Name_Buffer (Name_Str (1 .. Last));
6111 if Current_Verbosity = High then
6112 Write_Str (" found ");
6113 Write_Line (Get_Name_String (Name));
6116 -- Register the source if it is an Ada compilation unit
6124 Location => NL.Location,
6125 Current_Source => Current_Source,
6126 Source_Recorded => Source_Recorded,
6127 Follow_Links => Follow_Links);
6134 if Source_Recorded then
6135 In_Tree.String_Elements.Table (Source_Dir).Flag :=
6139 Source_Dir := Element.Next;
6142 -- It is an error if a source file name in a source list or
6143 -- in a source list file is not found.
6145 NL := Source_Names.Get_First;
6146 while NL /= No_Name_Location loop
6147 if not NL.Found then
6148 Err_Vars.Error_Msg_File_1 := NL.Name;
6153 "source file { cannot be found",
6155 First_Error := False;
6160 "\source file { cannot be found",
6165 NL := Source_Names.Get_Next;
6167 end Get_Path_Names_And_Record_Sources;
6169 ---------------------------
6170 -- Get_Sources_From_File --
6171 ---------------------------
6173 procedure Get_Sources_From_File
6175 Location : Source_Ptr)
6178 -- Get the list of sources from the file and put them in hash table
6181 Get_Sources_From_File (Path, Location, Project, In_Tree);
6183 if Get_Mode = Ada_Only then
6184 -- Look in the source directories to find those sources
6186 Get_Path_Names_And_Record_Sources (Follow_Links);
6188 -- We should have found at least one source.
6189 -- If not, report an error.
6191 if Data.Ada_Sources = Nil_String then
6192 Report_No_Sources (Project, "Ada", In_Tree, Location);
6198 end Get_Sources_From_File;
6200 ------------------------
6201 -- Search_Directories --
6202 ------------------------
6204 procedure Search_Directories (For_All_Sources : Boolean) is
6205 Source_Dir : String_List_Id;
6206 Element : String_Element;
6208 Name : String (1 .. 1_000);
6211 File_Name : File_Name_Type;
6212 Display_File_Name : File_Name_Type;
6214 Source_To_Replace : Source_Id := No_Source;
6215 Src_Data : Source_Data;
6217 Name_Loc : Name_Location;
6218 Check_Name : Boolean;
6220 Language : Language_Index;
6221 Language_Name : Name_Id;
6222 Display_Language_Name : Name_Id;
6224 Kind : Source_Kind := Spec;
6225 Alternate_Languages : Alternate_Language_Id :=
6226 No_Alternate_Language;
6230 procedure Check_Naming_Schemes;
6231 -- Check if the file name File_Name conforms to one of the naming
6232 -- schemes of the project. If it does, set the global variables
6233 -- Language, Language_Name, Display_Language_Name, Unit and Kind
6234 -- appropriately. If it does not, set Language to No_Language_Index.
6236 --------------------------
6237 -- Check_Naming_Schemes --
6238 --------------------------
6240 procedure Check_Naming_Schemes is
6241 Filename : constant String := Get_Name_String (File_Name);
6242 Last : Positive := Filename'Last;
6243 Config : Language_Config;
6244 Lang : Name_List_Index;
6246 Header_File : Boolean := False;
6247 First_Language : Language_Index;
6252 Lang := Data.Languages;
6253 while Lang /= No_Name_List loop
6254 Language_Name := In_Tree.Name_Lists.Table (Lang).Name;
6256 Language := Data.First_Language_Processing;
6257 while Language /= No_Language_Index loop
6258 if In_Tree.Languages_Data.Table (Language).Name =
6261 Display_Language_Name :=
6262 In_Tree.Languages_Data.Table (Language).Display_Name;
6263 Config := In_Tree.Languages_Data.Table (Language).Config;
6265 if Config.Kind = File_Based then
6267 -- For file based languages, there is no Unit. Just
6268 -- check if the file name has the implementation or,
6269 -- if it is specified, the template suffix of the
6274 if not Header_File and then
6275 Config.Naming_Data.Body_Suffix /= No_File
6278 Impl_Suffix : constant String :=
6280 (Config.Naming_Data.Body_Suffix);
6283 if Filename'Length > Impl_Suffix'Length
6286 (Last - Impl_Suffix'Length + 1 .. Last) =
6291 if Current_Verbosity = High then
6292 Write_Str (" source of language ");
6295 (Display_Language_Name));
6303 if Config.Naming_Data.Spec_Suffix /= No_File then
6305 Spec_Suffix : constant String :=
6307 (Config.Naming_Data.Spec_Suffix);
6310 if Filename'Length > Spec_Suffix'Length
6313 (Last - Spec_Suffix'Length + 1 .. Last) =
6318 if Current_Verbosity = High then
6320 (" header file of language ");
6323 (Display_Language_Name));
6327 Alternate_Language_Table.Increment_Last
6328 (In_Tree.Alt_Langs);
6329 In_Tree.Alt_Langs.Table
6330 (Alternate_Language_Table.Last
6331 (In_Tree.Alt_Langs)) :=
6332 (Language => Language,
6333 Next => Alternate_Languages);
6334 Alternate_Languages :=
6335 Alternate_Language_Table.Last
6336 (In_Tree.Alt_Langs);
6338 Header_File := True;
6339 First_Language := Language;
6345 elsif not Header_File then
6347 -- Unit based language
6349 OK := Config.Naming_Data.Dot_Replacement /= No_File;
6355 case Config.Naming_Data.Casing is
6356 when All_Lower_Case =>
6357 for J in Filename'Range loop
6358 if Is_Letter (Filename (J)) then
6359 if not Is_Lower (Filename (J)) then
6366 when All_Upper_Case =>
6367 for J in Filename'Range loop
6368 if Is_Letter (Filename (J)) then
6369 if not Is_Upper (Filename (J)) then
6384 if Config.Naming_Data.Separate_Suffix /= No_File
6386 Config.Naming_Data.Separate_Suffix /=
6387 Config.Naming_Data.Body_Suffix
6390 Suffix : constant String :=
6392 (Config.Naming_Data.Separate_Suffix);
6394 if Filename'Length > Suffix'Length
6397 (Last - Suffix'Length + 1 .. Last) =
6401 Last := Last - Suffix'Length;
6408 Config.Naming_Data.Body_Suffix /= No_File
6411 Suffix : constant String :=
6413 (Config.Naming_Data.Body_Suffix);
6415 if Filename'Length > Suffix'Length
6418 (Last - Suffix'Length + 1 .. Last) =
6422 Last := Last - Suffix'Length;
6429 Config.Naming_Data.Spec_Suffix /= No_File
6432 Suffix : constant String :=
6434 (Config.Naming_Data.Spec_Suffix);
6436 if Filename'Length > Suffix'Length
6439 (Last - Suffix'Length + 1 .. Last) =
6443 Last := Last - Suffix'Length;
6452 -- Replace dot replacements with dots
6457 J : Positive := Filename'First;
6459 Dot_Replacement : constant String :=
6461 (Config.Naming_Data.
6464 Max : constant Positive :=
6465 Last - Dot_Replacement'Length + 1;
6469 Name_Len := Name_Len + 1;
6471 if J <= Max and then
6473 (J .. J + Dot_Replacement'Length - 1) =
6476 Name_Buffer (Name_Len) := '.';
6477 J := J + Dot_Replacement'Length;
6480 if Filename (J) = '.' then
6485 Name_Buffer (Name_Len) :=
6486 GNAT.Case_Util.To_Lower (Filename (J));
6497 -- The name buffer should contain the name of the
6498 -- the unit, if it is one.
6500 -- Check that this is a valid unit name
6502 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit);
6504 if Unit /= No_Name then
6506 if Current_Verbosity = High then
6508 Write_Str (" spec of ");
6511 Write_Str (" body of ");
6514 Write_Str (Get_Name_String (Unit));
6515 Write_Str (" (language ");
6517 (Get_Name_String (Display_Language_Name));
6527 Language := In_Tree.Languages_Data.Table (Language).Next;
6530 Lang := In_Tree.Name_Lists.Table (Lang).Next;
6534 Language := First_Language;
6537 Language := No_Language_Index;
6539 if Current_Verbosity = High then
6540 Write_Line (" not a source of any language");
6543 end Check_Naming_Schemes;
6545 -- Start of processing for Search_Directories
6548 if Current_Verbosity = High then
6549 Write_Line ("Looking for sources:");
6552 -- Loop through subdirectories
6554 Source_Dir := Data.Source_Dirs;
6555 while Source_Dir /= Nil_String loop
6557 Element := In_Tree.String_Elements.Table (Source_Dir);
6558 if Element.Value /= No_Name then
6559 Get_Name_String (Element.Display_Value);
6562 Source_Directory : constant String :=
6563 Name_Buffer (1 .. Name_Len) &
6564 Directory_Separator;
6565 Dir_Last : constant Natural :=
6566 Compute_Directory_Last
6570 if Current_Verbosity = High then
6571 Write_Str ("Source_Dir = ");
6572 Write_Line (Source_Directory);
6575 -- We look to every entry in the source directory
6577 Open (Dir, Source_Directory
6578 (Source_Directory'First .. Dir_Last));
6581 Read (Dir, Name, Last);
6586 (Source_Directory & Name (1 .. Last))
6588 if Current_Verbosity = High then
6589 Write_Str (" Checking ");
6590 Write_Line (Name (1 .. Last));
6593 Source_To_Replace := No_Source;
6596 Name_Buffer (1 .. Name_Len) := Name (1 .. Last);
6597 Display_File_Name := Name_Find;
6598 Canonical_Case_File_Name
6599 (Name_Buffer (1 .. Name_Len));
6600 File_Name := Name_Find;
6603 Display_Path : constant String :=
6609 (Source_Directory'First ..
6613 Case_Sensitive => True);
6614 Path : String := Display_Path;
6615 Path_Id : Path_Name_Type;
6616 Display_Path_Id : Path_Name_Type;
6619 Canonical_Case_File_Name (Path);
6620 Name_Len := Path'Length;
6621 Name_Buffer (1 .. Name_Len) := Path;
6622 Path_Id := Name_Find;
6624 Name_Len := Display_Path'Length;
6625 Name_Buffer (1 .. Name_Len) := Display_Path;
6626 Display_Path_Id := Name_Find;
6628 Name_Loc := Source_Names.Get (File_Name);
6629 Check_Name := False;
6631 if Name_Loc = No_Name_Location then
6632 Check_Name := For_All_Sources;
6635 if Name_Loc.Found then
6637 -- Check if it is OK to have the same file
6638 -- name in several source directories.
6641 not Data.Known_Order_Of_Source_Dirs
6643 Error_Msg_File_1 := File_Name;
6646 "{ is found in several " &
6647 "source directories",
6652 Name_Loc.Found := True;
6654 if Name_Loc.Source = No_Source then
6658 In_Tree.Sources.Table
6659 (Name_Loc.Source).Path := Path_Id;
6661 Source_Paths_Htable.Set
6662 (In_Tree.Source_Paths_HT,
6666 In_Tree.Sources.Table
6667 (Name_Loc.Source).Display_Path :=
6670 -- Check if this is a subunit
6672 if In_Tree.Sources.Table
6673 (Name_Loc.Source).Unit /= No_Name
6675 In_Tree.Sources.Table
6676 (Name_Loc.Source).Kind = Impl
6679 Src_Ind : Source_File_Index;
6683 Sinput.P.Load_Project_File
6684 (Get_Name_String (Path_Id));
6686 if Sinput.P.Source_File_Is_Subunit
6689 In_Tree.Sources.Table
6690 (Name_Loc.Source).Kind :=
6700 Alternate_Languages := No_Alternate_Language;
6701 Check_Naming_Schemes;
6703 if Language = No_Language_Index then
6704 if Name_Loc.Found then
6706 -- A file name in a list must be
6707 -- a source of a language.
6709 Error_Msg_File_1 := File_Name;
6712 "language unknown for {",
6717 -- Check if the same file name or unit
6718 -- is used in the project tree.
6720 Source := In_Tree.First_Source;
6723 while Source /= No_Source loop
6725 In_Tree.Sources.Table (Source);
6727 if (Unit /= No_Name and then
6728 Src_Data.Unit = Unit and then
6729 Src_Data.Kind = Kind)
6731 (Unit = No_Name and then
6732 Src_Data.File = File_Name)
6734 -- Duplication of file/unit in the
6735 -- same project is only allowed if
6736 -- the order of source directories
6739 if Project = Src_Data.Project then
6741 Data.Known_Order_Of_Source_Dirs
6745 elsif Unit /= No_Name then
6746 Error_Msg_Name_1 := Unit;
6749 "duplicate unit %%",
6754 Error_Msg_File_1 := File_Name;
6757 "duplicate source file " &
6763 -- Do not allow the same unit name
6764 -- in different projects, except if
6765 -- one is extending the other.
6767 -- For a file based language,
6768 -- the same file name replaces
6769 -- a file in a project being
6770 -- extended, but it is allowed
6771 -- to have the same file name in
6772 -- unrelated projects.
6779 Source_To_Replace := Source;
6781 elsif Unit /= No_Name then
6782 Error_Msg_Name_1 := Unit;
6785 "unit %% cannot belong to " &
6792 Source := Src_Data.Next_In_Sources;
6796 Source_Data_Table.Increment_Last
6798 Source := Source_Data_Table.Last
6804 Data.Project := Project;
6805 Data.Language_Name := Language_Name;
6806 Data.Language := Language;
6807 Data.Alternate_Languages :=
6808 Alternate_Languages;
6811 Data.File := File_Name;
6813 Object_Name (File_Name);
6815 In_Tree.Languages_Data.Table
6816 (Language).Config.Dependency_Kind;
6819 (File_Name, Data.Dependency);
6821 Switches_Name (File_Name);
6822 Data.Display_File :=
6824 Data.Path := Path_Id;
6825 Data.Display_Path :=
6827 In_Tree.Sources.Table (Source) :=
6831 Add_Source (Source, Data, In_Tree);
6833 Source_Paths_Htable.Set
6834 (In_Tree.Source_Paths_HT,
6838 if Source_To_Replace /= No_Source then
6858 when Directory_Error =>
6861 Source_Dir := Element.Next;
6864 if Current_Verbosity = High then
6865 Write_Line ("end Looking for sources.");
6867 end Search_Directories;
6869 -- Start of processing for Look_For_Sources
6872 if Get_Mode = Ada_Only and then
6873 Is_A_Language (In_Tree, Data, "ada")
6876 Sources : constant Variable_Value :=
6879 Data.Decl.Attributes,
6882 Source_List_File : constant Variable_Value :=
6884 (Name_Source_List_File,
6885 Data.Decl.Attributes,
6888 Excluded_Sources : Variable_Value :=
6890 (Name_Excluded_Source_Files,
6891 Data.Decl.Attributes,
6896 (Sources.Kind = List,
6897 "Source_Files is not a list");
6900 (Source_List_File.Kind = Single,
6901 "Source_List_File is not a single string");
6903 if not Sources.Default then
6904 if not Source_List_File.Default then
6907 "?both variables source_files and " &
6908 "source_list_file are present",
6909 Source_List_File.Location);
6912 -- Sources is a list of file names
6915 Current : String_List_Id := Sources.Values;
6916 Element : String_Element;
6917 Location : Source_Ptr;
6918 Name : File_Name_Type;
6923 Data.Ada_Sources_Present := Current /= Nil_String;
6925 if Current = Nil_String then
6926 Data.Source_Dirs := Nil_String;
6928 -- This project contains no source. For projects that
6929 -- don't extend other projects, this also means that
6930 -- there is no need for an object directory, if not
6933 if Data.Extends = No_Project
6934 and then Data.Object_Directory = Data.Directory
6936 Data.Object_Directory := No_Path;
6940 while Current /= Nil_String loop
6942 In_Tree.String_Elements.Table (Current);
6943 Get_Name_String (Element.Value);
6944 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
6947 -- If the element has no location, then use the
6948 -- location of Sources to report possible errors.
6950 if Element.Location = No_Location then
6951 Location := Sources.Location;
6953 Location := Element.Location;
6960 Location => Location,
6961 Source => No_Source,
6965 Current := Element.Next;
6968 Get_Path_Names_And_Record_Sources (Follow_Links);
6972 -- No source_files specified
6974 -- We check Source_List_File has been specified
6976 elsif not Source_List_File.Default then
6978 -- Source_List_File is the name of the file
6979 -- that contains the source file names
6982 Source_File_Path_Name : constant String :=
6985 (Source_List_File.Value),
6989 if Source_File_Path_Name'Length = 0 then
6990 Err_Vars.Error_Msg_File_1 :=
6991 File_Name_Type (Source_List_File.Value);
6994 "file with sources { does not exist",
6995 Source_List_File.Location);
6998 Get_Sources_From_File
6999 (Source_File_Path_Name,
7000 Source_List_File.Location);
7005 -- Neither Source_Files nor Source_List_File has been
7006 -- specified. Find all the files that satisfy the naming
7007 -- scheme in all the source directories.
7010 (Project, In_Tree, Data, Follow_Links);
7013 -- If Excluded_ource_Files is not declared, check
7014 -- Locally_Removed_Files.
7016 if Excluded_Sources.Default then
7019 (Name_Locally_Removed_Files,
7020 Data.Decl.Attributes,
7024 -- If there are sources that are locally removed, mark them as
7025 -- such in the Units table.
7027 if not Excluded_Sources.Default then
7030 Current : String_List_Id := Excluded_Sources.Values;
7031 Element : String_Element;
7032 Location : Source_Ptr;
7035 Name : File_Name_Type;
7036 Extended : Project_Id;
7039 while Current /= Nil_String loop
7040 Element := In_Tree.String_Elements.Table (Current);
7041 Get_Name_String (Element.Value);
7042 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7045 -- If the element has no location, then use the location
7046 -- of Excluded_Sources to report possible errors.
7048 if Element.Location = No_Location then
7049 Location := Excluded_Sources.Location;
7051 Location := Element.Location;
7056 for Index in Unit_Table.First ..
7057 Unit_Table.Last (In_Tree.Units)
7059 Unit := In_Tree.Units.Table (Index);
7061 if Unit.File_Names (Specification).Name = Name then
7064 -- Check that this is from the current project or
7065 -- that the current project extends.
7067 Extended := Unit.File_Names
7068 (Specification).Project;
7070 if Extended = Project or else
7071 Project_Extends (Project, Extended, In_Tree)
7074 (Specification).Path := Slash;
7076 (Specification).Needs_Pragma := False;
7077 In_Tree.Units.Table (Index) := Unit;
7078 Add_Forbidden_File_Name
7079 (Unit.File_Names (Specification).Name);
7085 "cannot remove a source from " &
7091 Unit.File_Names (Body_Part).Name = Name
7095 -- Check that this is from the current project or
7096 -- that the current project extends.
7098 Extended := Unit.File_Names
7099 (Body_Part).Project;
7101 if Extended = Project or else
7102 Project_Extends (Project, Extended, In_Tree)
7104 Unit.File_Names (Body_Part).Path := Slash;
7105 Unit.File_Names (Body_Part).Needs_Pragma
7107 In_Tree.Units.Table (Index) := Unit;
7108 Add_Forbidden_File_Name
7109 (Unit.File_Names (Body_Part).Name);
7117 Err_Vars.Error_Msg_File_1 := Name;
7119 (Project, In_Tree, "unknown file {", Location);
7122 Current := Element.Next;
7129 if Get_Mode = Ada_Only and then Data.Other_Sources_Present then
7131 -- Set Source_Present to False. It will be set back to True
7132 -- whenever a source is found.
7134 Data.Other_Sources_Present := False;
7135 for Lang in Ada_Language_Index + 1 .. Last_Language_Index loop
7137 -- For each language (other than Ada) in the project file
7139 if Is_Present (Lang, Data, In_Tree) then
7141 -- Reset the indication that there are sources of this
7142 -- language. It will be set back to True whenever we find
7143 -- a source of the language.
7145 Set (Lang, False, Data, In_Tree);
7147 -- First, get the source suffix for the language
7149 Set (Suffix => Suffix_For (Lang, Data.Naming, In_Tree),
7150 For_Language => Lang,
7152 In_Tree => In_Tree);
7154 -- Then, deal with the naming exceptions, if any
7159 Naming_Exceptions : constant Variable_Value :=
7161 (Index => Language_Names.Table (Lang),
7163 In_Array => Data.Naming.Implementation_Exceptions,
7164 In_Tree => In_Tree);
7165 Element_Id : String_List_Id;
7166 Element : String_Element;
7167 File_Id : File_Name_Type;
7168 Source_Found : Boolean := False;
7171 -- If there are naming exceptions, look through them one
7174 if Naming_Exceptions /= Nil_Variable_Value then
7175 Element_Id := Naming_Exceptions.Values;
7177 while Element_Id /= Nil_String loop
7178 Element := In_Tree.String_Elements.Table
7180 Get_Name_String (Element.Value);
7181 Canonical_Case_File_Name
7182 (Name_Buffer (1 .. Name_Len));
7183 File_Id := Name_Find;
7185 -- Put each naming exception in the Source_Names
7186 -- hash table, but if there are repetition, don't
7187 -- bother after the first instance.
7190 Source_Names.Get (File_Id) = No_Name_Location
7192 Source_Found := True;
7196 Location => Element.Location,
7197 Source => No_Source,
7202 Element_Id := Element.Next;
7205 -- If there is at least one naming exception, record
7206 -- those that are found in the source directories.
7208 if Source_Found then
7209 Record_Other_Sources
7210 (Project => Project,
7214 Naming_Exceptions => True);
7220 -- Now, check if a list of sources is declared either through
7221 -- a string list (attribute Source_Files) or a text file
7222 -- (attribute Source_List_File). If a source list is declared,
7223 -- we will consider only those naming exceptions that are
7227 Sources : constant Variable_Value :=
7230 Data.Decl.Attributes,
7233 Source_List_File : constant Variable_Value :=
7235 (Name_Source_List_File,
7236 Data.Decl.Attributes,
7241 (Sources.Kind = List,
7242 "Source_Files is not a list");
7245 (Source_List_File.Kind = Single,
7246 "Source_List_File is not a single string");
7248 if not Sources.Default then
7249 if not Source_List_File.Default then
7252 "?both variables source_files and " &
7253 "source_list_file are present",
7254 Source_List_File.Location);
7257 -- Sources is a list of file names
7260 Current : String_List_Id := Sources.Values;
7261 Element : String_Element;
7262 Location : Source_Ptr;
7263 Name : File_Name_Type;
7268 -- Put all the sources in the Source_Names hash table
7270 while Current /= Nil_String loop
7272 In_Tree.String_Elements.Table
7274 Get_Name_String (Element.Value);
7275 Canonical_Case_File_Name
7276 (Name_Buffer (1 .. Name_Len));
7279 -- If the element has no location, then use the
7280 -- location of Sources to report possible errors.
7282 if Element.Location = No_Location then
7283 Location := Sources.Location;
7285 Location := Element.Location;
7292 Location => Location,
7293 Source => No_Source,
7297 Current := Element.Next;
7300 -- And look for their directories
7302 Record_Other_Sources
7303 (Project => Project,
7307 Naming_Exceptions => False);
7310 -- No source_files specified
7312 -- We check if Source_List_File has been specified
7314 elsif not Source_List_File.Default then
7316 -- Source_List_File is the name of the file
7317 -- that contains the source file names
7320 Source_File_Path_Name : constant String :=
7322 (File_Name_Type (Source_List_File.Value),
7326 if Source_File_Path_Name'Length = 0 then
7327 Err_Vars.Error_Msg_File_1 :=
7328 File_Name_Type (Source_List_File.Value);
7332 "file with sources { does not exist",
7333 Source_List_File.Location);
7336 -- Read the file, putting each source in the
7337 -- Source_Names hash table.
7339 Get_Sources_From_File
7340 (Source_File_Path_Name,
7341 Source_List_File.Location,
7344 -- And look for their directories
7346 Record_Other_Sources
7347 (Project => Project,
7351 Naming_Exceptions => False);
7355 -- Neither Source_Files nor Source_List_File was specified
7358 -- Find all the files that satisfy the naming scheme in
7359 -- all the source directories. All the naming exceptions
7360 -- that effectively exist are also part of the source
7361 -- of this language.
7363 Find_Sources (Project, In_Tree, Data, Lang);
7370 if Get_Mode = Multi_Language and then
7371 Data.First_Language_Processing /= No_Language_Index
7373 -- First, put all the naming exceptions, if any, in the Source_Names
7380 Src_Data : Source_Data;
7381 Name_Loc : Name_Location;
7384 Source := Data.First_Source;
7386 while Source /= No_Source loop
7387 Src_Data := In_Tree.Sources.Table (Source);
7388 Name_Loc := (Name => Src_Data.File,
7389 Location => No_Location,
7391 Except => Src_Data.Unit /= No_Name,
7394 if Current_Verbosity = High then
7395 Write_Str ("Putting source #");
7396 Write_Str (Source'Img);
7397 Write_Str (", file ");
7398 Write_Str (Get_Name_String (Src_Data.File));
7399 Write_Line (" in Source_Names");
7403 (K => Src_Data.File,
7406 Source := Src_Data.Next_In_Project;
7410 -- Now check attributes Sources and Source_List_File
7413 Sources : constant Variable_Value :=
7416 Data.Decl.Attributes,
7419 Source_List_File : constant Variable_Value :=
7421 (Name_Source_List_File,
7422 Data.Decl.Attributes,
7425 Excluded_Sources : Variable_Value :=
7427 (Name_Excluded_Source_Files,
7428 Data.Decl.Attributes,
7430 Name_Loc : Name_Location;
7433 -- If Excluded_ource_Files is not declared, check
7434 -- Locally_Removed_Files.
7436 if Excluded_Sources.Default then
7439 (Name_Locally_Removed_Files,
7440 Data.Decl.Attributes,
7444 if not Sources.Default then
7445 if not Source_List_File.Default then
7448 "?both variables source_files and " &
7449 "source_list_file are present",
7450 Source_List_File.Location);
7453 -- Sources is a list of file names
7456 Current : String_List_Id := Sources.Values;
7457 Element : String_Element;
7458 Location : Source_Ptr;
7459 Name : File_Name_Type;
7462 if Current = Nil_String then
7463 Data.First_Language_Processing := No_Language_Index;
7465 -- This project contains no source. For projects that
7466 -- don't extend other projects, this also means that
7467 -- there is no need for an object directory, if not
7470 if Data.Extends = No_Project
7471 and then Data.Object_Directory = Data.Directory
7473 Data.Object_Directory := No_Path;
7477 while Current /= Nil_String loop
7479 In_Tree.String_Elements.Table (Current);
7480 Get_Name_String (Element.Value);
7481 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7484 -- If the element has no location, then use the
7485 -- location of Sources to report possible errors.
7487 if Element.Location = No_Location then
7488 Location := Sources.Location;
7490 Location := Element.Location;
7493 Name_Loc := Source_Names.Get (Name);
7495 if Name_Loc = No_Name_Location then
7498 Location => Location,
7499 Source => No_Source,
7502 Source_Names.Set (Name, Name_Loc);
7505 Current := Element.Next;
7509 elsif not Source_List_File.Default then
7511 -- Source_List_File is the name of the file
7512 -- that contains the source file names
7515 Source_File_Path_Name : constant String :=
7518 (Source_List_File.Value),
7522 if Source_File_Path_Name'Length = 0 then
7523 Err_Vars.Error_Msg_File_1 :=
7524 File_Name_Type (Source_List_File.Value);
7527 "file with sources { does not exist",
7528 Source_List_File.Location);
7531 Get_Sources_From_File
7532 (Source_File_Path_Name,
7533 Source_List_File.Location);
7540 Sources.Default and then Source_List_File.Default);
7542 -- If there are locally removed sources, mark them as such
7544 if not Excluded_Sources.Default then
7546 Current : String_List_Id;
7547 Element : String_Element;
7548 Location : Source_Ptr;
7550 Name : File_Name_Type;
7552 Src_Data : Source_Data;
7555 Current := Excluded_Sources.Values;
7556 while Current /= Nil_String loop
7558 In_Tree.String_Elements.Table (Current);
7559 Get_Name_String (Element.Value);
7560 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7563 -- If the element has no location, then use the location
7564 -- of Excluded_Sources to report possible errors.
7566 if Element.Location = No_Location then
7567 Location := Excluded_Sources.Location;
7569 Location := Element.Location;
7574 Source := In_Tree.First_Source;
7576 while Source /= No_Source loop
7577 Src_Data := In_Tree.Sources.Table (Source);
7579 if Src_Data.File = Name then
7581 -- Check that this is from this project or a
7582 -- project that the current project extends.
7584 if Src_Data.Project = Project or else
7586 (Project, Src_Data.Project, In_Tree)
7588 Src_Data.Locally_Removed := True;
7589 In_Tree.Sources.Table (Source) := Src_Data;
7590 Add_Forbidden_File_Name (Name);
7596 Source := Src_Data.Next_In_Sources;
7600 Err_Vars.Error_Msg_File_1 := Name;
7602 (Project, In_Tree, "unknown file {", Location);
7605 Current := Element.Next;
7611 end Look_For_Sources;
7617 function Path_Name_Of
7618 (File_Name : File_Name_Type;
7619 Directory : Path_Name_Type)
7622 Result : String_Access;
7624 The_Directory : constant String := Get_Name_String (Directory);
7627 Get_Name_String (File_Name);
7628 Result := Locate_Regular_File
7629 (File_Name => Name_Buffer (1 .. Name_Len),
7630 Path => The_Directory);
7632 if Result = null then
7635 Canonical_Case_File_Name (Result.all);
7640 -------------------------------
7641 -- Prepare_Ada_Naming_Exceptions --
7642 -------------------------------
7644 procedure Prepare_Ada_Naming_Exceptions
7645 (List : Array_Element_Id;
7646 In_Tree : Project_Tree_Ref;
7647 Kind : Spec_Or_Body)
7649 Current : Array_Element_Id;
7650 Element : Array_Element;
7654 -- Traverse the list
7657 while Current /= No_Array_Element loop
7658 Element := In_Tree.Array_Elements.Table (Current);
7660 if Element.Index /= No_Name then
7663 Unit => Element.Index,
7664 Next => No_Ada_Naming_Exception);
7665 Reverse_Ada_Naming_Exceptions.Set
7666 (Unit, (Element.Value.Value, Element.Value.Index));
7668 Ada_Naming_Exceptions.Get (File_Name_Type (Element.Value.Value));
7669 Ada_Naming_Exception_Table.Increment_Last;
7670 Ada_Naming_Exception_Table.Table
7671 (Ada_Naming_Exception_Table.Last) := Unit;
7672 Ada_Naming_Exceptions.Set
7673 (File_Name_Type (Element.Value.Value),
7674 Ada_Naming_Exception_Table.Last);
7677 Current := Element.Next;
7679 end Prepare_Ada_Naming_Exceptions;
7681 ---------------------
7682 -- Project_Extends --
7683 ---------------------
7685 function Project_Extends
7686 (Extending : Project_Id;
7687 Extended : Project_Id;
7688 In_Tree : Project_Tree_Ref) return Boolean
7690 Current : Project_Id := Extending;
7693 if Current = No_Project then
7696 elsif Current = Extended then
7700 Current := In_Tree.Projects.Table (Current).Extends;
7702 end Project_Extends;
7704 -----------------------
7705 -- Record_Ada_Source --
7706 -----------------------
7708 procedure Record_Ada_Source
7709 (File_Name : File_Name_Type;
7710 Path_Name : Path_Name_Type;
7711 Project : Project_Id;
7712 In_Tree : Project_Tree_Ref;
7713 Data : in out Project_Data;
7714 Location : Source_Ptr;
7715 Current_Source : in out String_List_Id;
7716 Source_Recorded : in out Boolean;
7717 Follow_Links : Boolean)
7719 Canonical_File_Name : File_Name_Type;
7720 Canonical_Path_Name : Path_Name_Type;
7722 Exception_Id : Ada_Naming_Exception_Id;
7723 Unit_Name : Name_Id;
7724 Unit_Kind : Spec_Or_Body;
7725 Unit_Ind : Int := 0;
7727 Name_Index : Name_And_Index;
7728 Needs_Pragma : Boolean;
7730 The_Location : Source_Ptr := Location;
7731 Previous_Source : constant String_List_Id := Current_Source;
7732 Except_Name : Name_And_Index := No_Name_And_Index;
7734 Unit_Prj : Unit_Project;
7736 File_Name_Recorded : Boolean := False;
7739 Get_Name_String (File_Name);
7740 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7741 Canonical_File_Name := Name_Find;
7744 Canonical_Path : constant String :=
7746 (Get_Name_String (Path_Name),
7747 Resolve_Links => Follow_Links,
7748 Case_Sensitive => False);
7751 Add_Str_To_Name_Buffer (Canonical_Path);
7752 Canonical_Path_Name := Name_Find;
7755 -- Find out the unit name, the unit kind and if it needs
7756 -- a specific SFN pragma.
7759 (In_Tree => In_Tree,
7760 Canonical_File_Name => Canonical_File_Name,
7761 Naming => Data.Naming,
7762 Exception_Id => Exception_Id,
7763 Unit_Name => Unit_Name,
7764 Unit_Kind => Unit_Kind,
7765 Needs_Pragma => Needs_Pragma);
7767 if Exception_Id = No_Ada_Naming_Exception and then
7770 if Current_Verbosity = High then
7772 Write_Str (Get_Name_String (Canonical_File_Name));
7773 Write_Line (""" is not a valid source file name (ignored).");
7777 -- Check to see if the source has been hidden by an exception,
7778 -- but only if it is not an exception.
7780 if not Needs_Pragma then
7782 Reverse_Ada_Naming_Exceptions.Get
7783 ((Unit_Kind, Unit_Name, No_Ada_Naming_Exception));
7785 if Except_Name /= No_Name_And_Index then
7786 if Current_Verbosity = High then
7788 Write_Str (Get_Name_String (Canonical_File_Name));
7789 Write_Str (""" contains a unit that is found in """);
7790 Write_Str (Get_Name_String (Except_Name.Name));
7791 Write_Line (""" (ignored).");
7794 -- The file is not included in the source of the project since
7795 -- it is hidden by the exception. So, nothing else to do.
7802 if Exception_Id /= No_Ada_Naming_Exception then
7803 Info := Ada_Naming_Exception_Table.Table (Exception_Id);
7804 Exception_Id := Info.Next;
7805 Info.Next := No_Ada_Naming_Exception;
7806 Name_Index := Reverse_Ada_Naming_Exceptions.Get (Info);
7808 Unit_Name := Info.Unit;
7809 Unit_Ind := Name_Index.Index;
7810 Unit_Kind := Info.Kind;
7813 -- Put the file name in the list of sources of the project
7815 String_Element_Table.Increment_Last
7816 (In_Tree.String_Elements);
7817 In_Tree.String_Elements.Table
7818 (String_Element_Table.Last
7819 (In_Tree.String_Elements)) :=
7820 (Value => Name_Id (Canonical_File_Name),
7821 Display_Value => Name_Id (File_Name),
7822 Location => No_Location,
7827 if Current_Source = Nil_String then
7828 Data.Ada_Sources := String_Element_Table.Last
7829 (In_Tree.String_Elements);
7830 Data.Sources := Data.Ada_Sources;
7832 In_Tree.String_Elements.Table
7833 (Current_Source).Next :=
7834 String_Element_Table.Last
7835 (In_Tree.String_Elements);
7838 Current_Source := String_Element_Table.Last
7839 (In_Tree.String_Elements);
7841 -- Put the unit in unit list
7844 The_Unit : Unit_Index :=
7845 Units_Htable.Get (In_Tree.Units_HT, Unit_Name);
7847 The_Unit_Data : Unit_Data;
7850 if Current_Verbosity = High then
7851 Write_Str ("Putting ");
7852 Write_Str (Get_Name_String (Unit_Name));
7853 Write_Line (" in the unit list.");
7856 -- The unit is already in the list, but may be it is
7857 -- only the other unit kind (spec or body), or what is
7858 -- in the unit list is a unit of a project we are extending.
7860 if The_Unit /= No_Unit_Index then
7861 The_Unit_Data := In_Tree.Units.Table (The_Unit);
7863 if (The_Unit_Data.File_Names (Unit_Kind).Name =
7866 The_Unit_Data.File_Names (Unit_Kind).Path = Slash)
7867 or else The_Unit_Data.File_Names (Unit_Kind).Name = No_File
7868 or else Project_Extends
7870 The_Unit_Data.File_Names (Unit_Kind).Project,
7873 if The_Unit_Data.File_Names (Unit_Kind).Path = Slash then
7874 Remove_Forbidden_File_Name
7875 (The_Unit_Data.File_Names (Unit_Kind).Name);
7878 -- Record the file name in the hash table Files_Htable
7880 Unit_Prj := (Unit => The_Unit, Project => Project);
7883 Canonical_File_Name,
7886 The_Unit_Data.File_Names (Unit_Kind) :=
7887 (Name => Canonical_File_Name,
7889 Display_Name => File_Name,
7890 Path => Canonical_Path_Name,
7891 Display_Path => Path_Name,
7893 Needs_Pragma => Needs_Pragma);
7894 In_Tree.Units.Table (The_Unit) :=
7896 Source_Recorded := True;
7898 elsif The_Unit_Data.File_Names (Unit_Kind).Project = Project
7899 and then (Data.Known_Order_Of_Source_Dirs or else
7900 The_Unit_Data.File_Names (Unit_Kind).Path =
7901 Canonical_Path_Name)
7903 if Previous_Source = Nil_String then
7904 Data.Ada_Sources := Nil_String;
7905 Data.Sources := Nil_String;
7907 In_Tree.String_Elements.Table
7908 (Previous_Source).Next := Nil_String;
7909 String_Element_Table.Decrement_Last
7910 (In_Tree.String_Elements);
7913 Current_Source := Previous_Source;
7916 -- It is an error to have two units with the same name
7917 -- and the same kind (spec or body).
7919 if The_Location = No_Location then
7921 In_Tree.Projects.Table
7925 Err_Vars.Error_Msg_Name_1 := Unit_Name;
7927 (Project, In_Tree, "duplicate source %%", The_Location);
7929 Err_Vars.Error_Msg_Name_1 :=
7930 In_Tree.Projects.Table
7931 (The_Unit_Data.File_Names (Unit_Kind).Project).Name;
7932 Err_Vars.Error_Msg_File_1 :=
7934 (The_Unit_Data.File_Names (Unit_Kind).Path);
7937 "\ project file %%, {", The_Location);
7939 Err_Vars.Error_Msg_Name_1 :=
7940 In_Tree.Projects.Table (Project).Name;
7941 Err_Vars.Error_Msg_File_1 :=
7942 File_Name_Type (Canonical_Path_Name);
7945 "\ project file %%, {", The_Location);
7948 -- It is a new unit, create a new record
7951 -- First, check if there is no other unit with this file
7952 -- name in another project. If it is, report an error.
7953 -- Of course, we do that only for the first unit in the
7956 Unit_Prj := Files_Htable.Get
7957 (In_Tree.Files_HT, Canonical_File_Name);
7959 if not File_Name_Recorded and then
7960 Unit_Prj /= No_Unit_Project
7962 Error_Msg_File_1 := File_Name;
7964 In_Tree.Projects.Table
7965 (Unit_Prj.Project).Name;
7968 "{ is already a source of project %%",
7972 Unit_Table.Increment_Last (In_Tree.Units);
7973 The_Unit := Unit_Table.Last (In_Tree.Units);
7975 (In_Tree.Units_HT, Unit_Name, The_Unit);
7976 Unit_Prj := (Unit => The_Unit, Project => Project);
7979 Canonical_File_Name,
7981 The_Unit_Data.Name := Unit_Name;
7982 The_Unit_Data.File_Names (Unit_Kind) :=
7983 (Name => Canonical_File_Name,
7985 Display_Name => File_Name,
7986 Path => Canonical_Path_Name,
7987 Display_Path => Path_Name,
7989 Needs_Pragma => Needs_Pragma);
7990 In_Tree.Units.Table (The_Unit) :=
7992 Source_Recorded := True;
7997 exit when Exception_Id = No_Ada_Naming_Exception;
7998 File_Name_Recorded := True;
8001 end Record_Ada_Source;
8003 --------------------------
8004 -- Record_Other_Sources --
8005 --------------------------
8007 procedure Record_Other_Sources
8008 (Project : Project_Id;
8009 In_Tree : Project_Tree_Ref;
8010 Data : in out Project_Data;
8011 Language : Language_Index;
8012 Naming_Exceptions : Boolean)
8014 Source_Dir : String_List_Id;
8015 Element : String_Element;
8016 Path : Path_Name_Type;
8018 Canonical_Name : File_Name_Type;
8019 Name_Str : String (1 .. 1_024);
8020 Last : Natural := 0;
8022 First_Error : Boolean := True;
8023 Suffix : constant String :=
8024 Body_Suffix_Of (Language, Data, In_Tree);
8027 Source_Dir := Data.Source_Dirs;
8028 while Source_Dir /= Nil_String loop
8029 Element := In_Tree.String_Elements.Table (Source_Dir);
8032 Dir_Path : constant String :=
8033 Get_Name_String (Element.Display_Value);
8035 if Current_Verbosity = High then
8036 Write_Str ("checking directory """);
8037 Write_Str (Dir_Path);
8038 Write_Str (""" for ");
8040 if Naming_Exceptions then
8041 Write_Str ("naming exceptions");
8044 Write_Str ("sources");
8047 Write_Str (" of Language ");
8048 Display_Language_Name (Language);
8051 Open (Dir, Dir_Path);
8054 Read (Dir, Name_Str, Last);
8058 (Dir_Path & Directory_Separator & Name_Str (1 .. Last))
8061 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
8062 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
8063 Canonical_Name := Name_Find;
8064 NL := Source_Names.Get (Canonical_Name);
8066 if NL /= No_Name_Location then
8068 if not Data.Known_Order_Of_Source_Dirs then
8069 Error_Msg_File_1 := Canonical_Name;
8072 "{ is found in several source directories",
8078 Source_Names.Set (Canonical_Name, NL);
8079 Name_Len := Dir_Path'Length;
8080 Name_Buffer (1 .. Name_Len) := Dir_Path;
8081 Add_Char_To_Name_Buffer (Directory_Separator);
8082 Add_Str_To_Name_Buffer (Name_Str (1 .. Last));
8086 (File_Name => Canonical_Name,
8091 Location => NL.Location,
8092 Language => Language,
8094 Naming_Exception => Naming_Exceptions);
8103 Source_Dir := Element.Next;
8106 if not Naming_Exceptions then
8107 NL := Source_Names.Get_First;
8109 -- It is an error if a source file name in a source list or
8110 -- in a source list file is not found.
8112 while NL /= No_Name_Location loop
8113 if not NL.Found then
8114 Err_Vars.Error_Msg_File_1 := NL.Name;
8119 "source file { cannot be found",
8121 First_Error := False;
8126 "\source file { cannot be found",
8131 NL := Source_Names.Get_Next;
8134 -- Any naming exception of this language that is not in a list
8135 -- of sources must be removed.
8138 Source_Id : Other_Source_Id := Data.First_Other_Source;
8139 Prev_Id : Other_Source_Id := No_Other_Source;
8140 Source : Other_Source;
8143 while Source_Id /= No_Other_Source loop
8144 Source := In_Tree.Other_Sources.Table (Source_Id);
8146 if Source.Language = Language
8147 and then Source.Naming_Exception
8149 if Current_Verbosity = High then
8150 Write_Str ("Naming exception """);
8151 Write_Str (Get_Name_String (Source.File_Name));
8152 Write_Str (""" is not in the list of sources,");
8153 Write_Line (" so it is removed.");
8156 if Prev_Id = No_Other_Source then
8157 Data.First_Other_Source := Source.Next;
8160 In_Tree.Other_Sources.Table
8161 (Prev_Id).Next := Source.Next;
8164 Source_Id := Source.Next;
8166 if Source_Id = No_Other_Source then
8167 Data.Last_Other_Source := Prev_Id;
8171 Prev_Id := Source_Id;
8172 Source_Id := Source.Next;
8177 end Record_Other_Sources;
8183 procedure Remove_Source
8185 Replaced_By : Source_Id;
8186 Project : Project_Id;
8187 Data : in out Project_Data;
8188 In_Tree : Project_Tree_Ref)
8190 Src_Data : constant Source_Data := In_Tree.Sources.Table (Id);
8195 if Current_Verbosity = High then
8196 Write_Str ("Removing source #");
8197 Write_Line (Id'Img);
8200 In_Tree.Sources.Table (Id).Replaced_By := Replaced_By;
8202 -- Remove the source from the global source list
8204 Source := In_Tree.First_Source;
8207 In_Tree.First_Source := Src_Data.Next_In_Sources;
8210 while In_Tree.Sources.Table (Source).Next_In_Sources /= Id loop
8211 Source := In_Tree.Sources.Table (Source).Next_In_Sources;
8214 In_Tree.Sources.Table (Source).Next_In_Sources :=
8215 Src_Data.Next_In_Sources;
8218 -- Remove the source from the project list
8220 if Src_Data.Project = Project then
8221 Source := Data.First_Source;
8224 Data.First_Source := Src_Data.Next_In_Project;
8226 if Src_Data.Next_In_Project = No_Source then
8227 Data.Last_Source := No_Source;
8231 while In_Tree.Sources.Table (Source).Next_In_Project /= Id loop
8232 Source := In_Tree.Sources.Table (Source).Next_In_Project;
8235 In_Tree.Sources.Table (Source).Next_In_Project :=
8236 Src_Data.Next_In_Project;
8238 if Src_Data.Next_In_Project = No_Source then
8239 In_Tree.Projects.Table (Src_Data.Project).Last_Source := Source;
8244 Source := In_Tree.Projects.Table (Src_Data.Project).First_Source;
8247 In_Tree.Projects.Table (Src_Data.Project).First_Source :=
8248 Src_Data.Next_In_Project;
8250 if Src_Data.Next_In_Project = No_Source then
8251 In_Tree.Projects.Table (Src_Data.Project).Last_Source :=
8256 while In_Tree.Sources.Table (Source).Next_In_Project /= Id loop
8257 Source := In_Tree.Sources.Table (Source).Next_In_Project;
8260 In_Tree.Sources.Table (Source).Next_In_Project :=
8261 Src_Data.Next_In_Project;
8263 if Src_Data.Next_In_Project = No_Source then
8264 In_Tree.Projects.Table (Src_Data.Project).Last_Source := Source;
8269 -- Remove source from the language list
8271 Source := In_Tree.Languages_Data.Table (Src_Data.Language).First_Source;
8274 In_Tree.Languages_Data.Table (Src_Data.Language).First_Source :=
8275 Src_Data.Next_In_Lang;
8278 while In_Tree.Sources.Table (Source).Next_In_Lang /= Id loop
8279 Source := In_Tree.Sources.Table (Source).Next_In_Lang;
8282 In_Tree.Sources.Table (Source).Next_In_Lang :=
8283 Src_Data.Next_In_Lang;
8287 -----------------------
8288 -- Report_No_Sources --
8289 -----------------------
8291 procedure Report_No_Sources
8292 (Project : Project_Id;
8294 In_Tree : Project_Tree_Ref;
8295 Location : Source_Ptr)
8298 case When_No_Sources is
8302 when Warning | Error =>
8303 Error_Msg_Warn := When_No_Sources = Warning;
8306 "<there are no " & Lang_Name & " sources in this project",
8309 end Report_No_Sources;
8311 ----------------------
8312 -- Show_Source_Dirs --
8313 ----------------------
8315 procedure Show_Source_Dirs
8316 (Data : Project_Data;
8317 In_Tree : Project_Tree_Ref)
8319 Current : String_List_Id;
8320 Element : String_Element;
8323 Write_Line ("Source_Dirs:");
8325 Current := Data.Source_Dirs;
8326 while Current /= Nil_String loop
8327 Element := In_Tree.String_Elements.Table (Current);
8329 Write_Line (Get_Name_String (Element.Value));
8330 Current := Element.Next;
8333 Write_Line ("end Source_Dirs.");
8334 end Show_Source_Dirs;
8341 (Language : Language_Index;
8342 Naming : Naming_Data;
8343 In_Tree : Project_Tree_Ref) return File_Name_Type
8345 Suffix : constant Variable_Value :=
8347 (Index => Language_Names.Table (Language),
8349 In_Array => Naming.Body_Suffix,
8350 In_Tree => In_Tree);
8352 -- If no suffix for this language in package Naming, use the default
8354 if Suffix = Nil_Variable_Value then
8358 when Ada_Language_Index =>
8359 Add_Str_To_Name_Buffer (".adb");
8361 when C_Language_Index =>
8362 Add_Str_To_Name_Buffer (".c");
8364 when C_Plus_Plus_Language_Index =>
8365 Add_Str_To_Name_Buffer (".cpp");
8371 -- Otherwise use the one specified
8374 Get_Name_String (Suffix.Value);
8377 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
8381 -------------------------
8382 -- Warn_If_Not_Sources --
8383 -------------------------
8385 -- comments needed in this body ???
8387 procedure Warn_If_Not_Sources
8388 (Project : Project_Id;
8389 In_Tree : Project_Tree_Ref;
8390 Conventions : Array_Element_Id;
8392 Extending : Boolean)
8394 Conv : Array_Element_Id := Conventions;
8396 The_Unit_Id : Unit_Index;
8397 The_Unit_Data : Unit_Data;
8398 Location : Source_Ptr;
8401 while Conv /= No_Array_Element loop
8402 Unit := In_Tree.Array_Elements.Table (Conv).Index;
8403 Error_Msg_Name_1 := Unit;
8404 Get_Name_String (Unit);
8405 To_Lower (Name_Buffer (1 .. Name_Len));
8407 The_Unit_Id := Units_Htable.Get
8408 (In_Tree.Units_HT, Unit);
8409 Location := In_Tree.Array_Elements.Table
8410 (Conv).Value.Location;
8412 if The_Unit_Id = No_Unit_Index then
8419 The_Unit_Data := In_Tree.Units.Table (The_Unit_Id);
8421 In_Tree.Array_Elements.Table (Conv).Value.Value;
8424 if not Check_Project
8425 (The_Unit_Data.File_Names (Specification).Project,
8426 Project, In_Tree, Extending)
8430 "?source of spec of unit %% (%%)" &
8431 " cannot be found in this project",
8436 if not Check_Project
8437 (The_Unit_Data.File_Names (Body_Part).Project,
8438 Project, In_Tree, Extending)
8442 "?source of body of unit %% (%%)" &
8443 " cannot be found in this project",
8449 Conv := In_Tree.Array_Elements.Table (Conv).Next;
8451 end Warn_If_Not_Sources;