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 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 ------------------------------------------------------------------------------
26 with GNAT.Case_Util; use GNAT.Case_Util;
27 with GNAT.Directory_Operations; use GNAT.Directory_Operations;
30 with Err_Vars; use Err_Vars;
35 with Osint; use Osint;
36 with Output; use Output;
37 with Prj.Env; use Prj.Env;
39 with Prj.Util; use Prj.Util;
41 with Snames; use Snames;
42 with Table; use Table;
43 with Targparm; use Targparm;
45 with Ada.Characters.Handling; use Ada.Characters.Handling;
46 with Ada.Directories; use Ada.Directories;
47 with Ada.Strings; use Ada.Strings;
48 with Ada.Strings.Fixed; use Ada.Strings.Fixed;
49 with Ada.Strings.Maps.Constants; use Ada.Strings.Maps.Constants;
51 package body Prj.Nmsc is
53 No_Continuation_String : aliased String := "";
54 Continuation_String : aliased String := "\";
55 -- Used in Check_Library for continuation error messages at the same
58 Error_Report : Put_Line_Access := null;
59 -- Set to point to error reporting procedure
61 When_No_Sources : Error_Warning := Error;
62 -- Indicates what should be done when there is no Ada sources in a non
63 -- extending Ada project.
65 ALI_Suffix : constant String := ".ali";
66 -- File suffix for ali files
68 Object_Suffix : constant String := Get_Target_Object_Suffix.all;
69 -- File suffix for object files
71 type Name_Location is record
72 Name : File_Name_Type;
73 Location : Source_Ptr;
74 Source : Source_Id := No_Source;
75 Except : Boolean := False;
76 Found : Boolean := False;
78 -- Information about file names found in string list attribute
79 -- Source_Files or in a source list file, stored in hash table
80 -- Source_Names, used by procedure Get_Path_Names_And_Record_Sources.
82 No_Name_Location : constant Name_Location :=
84 Location => No_Location,
89 package Source_Names is new GNAT.HTable.Simple_HTable
90 (Header_Num => Header_Num,
91 Element => Name_Location,
92 No_Element => No_Name_Location,
93 Key => File_Name_Type,
96 -- Hash table to store file names found in string list attribute
97 -- Source_Files or in a source list file, stored in hash table
98 -- Source_Names, used by procedure Get_Path_Names_And_Record_Sources.
100 package Recursive_Dirs is new GNAT.HTable.Simple_HTable
101 (Header_Num => Header_Num,
107 -- Hash table to store recursive source directories, to avoid looking
108 -- several times, and to avoid cycles that may be introduced by symbolic
111 type Ada_Naming_Exception_Id is new Nat;
112 No_Ada_Naming_Exception : constant Ada_Naming_Exception_Id := 0;
114 type Unit_Info is record
117 Next : Ada_Naming_Exception_Id := No_Ada_Naming_Exception;
119 -- No_Unit : constant Unit_Info :=
120 -- (Specification, No_Name, No_Ada_Naming_Exception);
122 package Ada_Naming_Exception_Table is new Table.Table
123 (Table_Component_Type => Unit_Info,
124 Table_Index_Type => Ada_Naming_Exception_Id,
125 Table_Low_Bound => 1,
127 Table_Increment => 100,
128 Table_Name => "Prj.Nmsc.Ada_Naming_Exception_Table");
130 package Ada_Naming_Exceptions is new GNAT.HTable.Simple_HTable
131 (Header_Num => Header_Num,
132 Element => Ada_Naming_Exception_Id,
133 No_Element => No_Ada_Naming_Exception,
134 Key => File_Name_Type,
137 -- A hash table to store naming exceptions for Ada. For each file name
138 -- there is one or several unit in table Ada_Naming_Exception_Table.
140 function Hash (Unit : Unit_Info) return Header_Num;
142 type Name_And_Index is record
143 Name : Name_Id := No_Name;
146 No_Name_And_Index : constant Name_And_Index :=
147 (Name => No_Name, Index => 0);
149 package Reverse_Ada_Naming_Exceptions is new GNAT.HTable.Simple_HTable
150 (Header_Num => Header_Num,
151 Element => Name_And_Index,
152 No_Element => No_Name_And_Index,
156 -- A table to check if a unit with an exceptional name will hide
157 -- a source with a file name following the naming convention.
161 Data : in out Project_Data;
162 In_Tree : Project_Tree_Ref);
163 -- Add a new source to the different lists: list of all sources in the
164 -- project tree, list of source of a project and list of sources of a
167 function ALI_File_Name (Source : String) return String;
168 -- Return the ALI file name corresponding to a source
170 procedure Check_Ada_Name (Name : String; Unit : out Name_Id);
171 -- Check that a name is a valid Ada unit name
173 procedure Check_Naming_Schemes
174 (Data : in out Project_Data;
175 Project : Project_Id;
176 In_Tree : Project_Tree_Ref);
177 -- Check the naming scheme part of Data
179 procedure Check_Ada_Naming_Scheme_Validity
180 (Project : Project_Id;
181 In_Tree : Project_Tree_Ref;
182 Naming : Naming_Data);
183 -- Check that the package Naming is correct
185 procedure Check_Configuration
186 (Project : Project_Id;
187 In_Tree : Project_Tree_Ref;
188 Data : in out Project_Data);
189 -- Check the configuration attributes for the project
191 procedure Check_For_Source
192 (File_Name : File_Name_Type;
193 Path_Name : Path_Name_Type;
194 Project : Project_Id;
195 In_Tree : Project_Tree_Ref;
196 Data : in out Project_Data;
197 Location : Source_Ptr;
198 Language : Language_Index;
200 Naming_Exception : Boolean);
201 -- Check if a file, with name File_Name and path Path_Name, in a source
202 -- directory is a source for language Language in project Project of
203 -- project tree In_Tree. ???
205 procedure Check_If_Externally_Built
206 (Project : Project_Id;
207 In_Tree : Project_Tree_Ref;
208 Data : in out Project_Data);
209 -- Check attribute Externally_Built of project Project in project tree
210 -- In_Tree and modify its data Data if it has the value "true".
212 procedure Check_Library_Attributes
213 (Project : Project_Id;
214 In_Tree : Project_Tree_Ref;
215 Data : in out Project_Data);
216 -- Check the library attributes of project Project in project tree In_Tree
217 -- and modify its data Data accordingly.
219 procedure Check_Package_Naming
220 (Project : Project_Id;
221 In_Tree : Project_Tree_Ref;
222 Data : in out Project_Data);
223 -- Check package Naming of project Project in project tree In_Tree and
224 -- modify its data Data accordingly.
226 procedure Check_Programming_Languages
227 (In_Tree : Project_Tree_Ref;
228 Project : Project_Id;
229 Data : in out Project_Data);
230 -- Check attribute Languages for the project with data Data in project
231 -- tree In_Tree and set the components of Data for all the programming
232 -- languages indicated in attribute Languages, if any.
234 function Check_Project
236 Root_Project : Project_Id;
237 In_Tree : Project_Tree_Ref;
238 Extending : Boolean) return Boolean;
239 -- Returns True if P is Root_Project or, if Extending is True, a project
240 -- extended by Root_Project.
242 procedure Check_Stand_Alone_Library
243 (Project : Project_Id;
244 In_Tree : Project_Tree_Ref;
245 Data : in out Project_Data;
246 Extending : Boolean);
247 -- Check if project Project in project tree In_Tree is a Stand-Alone
248 -- Library project, and modify its data Data accordingly if it is one.
250 function Compute_Directory_Last (Dir : String) return Natural;
251 -- Return the index of the last significant character in Dir. This is used
252 -- to avoid duplicates '/' at the end of directory names
255 (Project : Project_Id;
256 In_Tree : Project_Tree_Ref;
258 Flag_Location : Source_Ptr);
259 -- Output an error message. If Error_Report is null, simply call
260 -- Prj.Err.Error_Msg. Otherwise, disregard Flag_Location and use
263 procedure Find_Ada_Sources
264 (Project : Project_Id;
265 In_Tree : Project_Tree_Ref;
266 Data : in out Project_Data;
267 Follow_Links : Boolean := False);
268 -- Find all the Ada sources in all of the source directories of a project
270 procedure Find_Sources
271 (Project : Project_Id;
272 In_Tree : Project_Tree_Ref;
273 Data : in out Project_Data;
274 For_Language : Language_Index;
275 Follow_Links : Boolean := False);
276 -- Find all the sources in all of the source directories of a project for
277 -- a specified language.
279 procedure Free_Ada_Naming_Exceptions;
280 -- Free the internal hash tables used for checking naming exceptions
282 procedure Get_Directories
283 (Project : Project_Id;
284 In_Tree : Project_Tree_Ref;
285 Data : in out Project_Data);
286 -- Get the object directory, the exec directory and the source directories
290 (Project : Project_Id;
291 In_Tree : Project_Tree_Ref;
292 Data : in out Project_Data);
293 -- Get the mains of a project from attribute Main, if it exists, and put
294 -- them in the project data.
296 procedure Get_Sources_From_File
298 Location : Source_Ptr;
299 Project : Project_Id;
300 In_Tree : Project_Tree_Ref);
301 -- Get the list of sources from a text file and put them in hash table
305 (In_Tree : Project_Tree_Ref;
306 Canonical_File_Name : File_Name_Type;
307 Naming : Naming_Data;
308 Exception_Id : out Ada_Naming_Exception_Id;
309 Unit_Name : out Name_Id;
310 Unit_Kind : out Spec_Or_Body;
311 Needs_Pragma : out Boolean);
312 -- Find out, from a file name, the unit name, the unit kind and if a
313 -- specific SFN pragma is needed. If the file name corresponds to no
314 -- unit, then Unit_Name will be No_Name. If the file is a multi-unit source
315 -- or an exception to the naming scheme, then Exception_Id is set to
316 -- the unit or units that the source contains.
318 function Is_Illegal_Suffix
320 Dot_Replacement_Is_A_Single_Dot : Boolean) return Boolean;
321 -- Returns True if the string Suffix cannot be used as
322 -- a spec suffix, a body suffix or a separate suffix.
324 procedure Locate_Directory
325 (Project : Project_Id;
326 In_Tree : Project_Tree_Ref;
327 Name : File_Name_Type;
328 Parent : Path_Name_Type;
329 Dir : out Path_Name_Type;
330 Display : out Path_Name_Type;
331 Create : String := "";
332 Location : Source_Ptr := No_Location);
333 -- Locate a directory. Name is the directory name. Parent is the root
334 -- directory, if Name a relative path name. Dir is set to the canonical
335 -- case path name of the directory, and Display is the directory path name
336 -- for display purposes. If the directory does not exist and Project_Setup
337 -- is True and Create is a non null string, an attempt is made to create
338 -- the directory. If the directory does not exist and Project_Setup is
339 -- false, then Dir and Display are set to No_Name.
341 procedure Look_For_Sources
342 (Project : Project_Id;
343 In_Tree : Project_Tree_Ref;
344 Data : in out Project_Data;
345 Follow_Links : Boolean);
346 -- Find all the sources of project Project in project tree In_Tree and
347 -- update its Data accordingly. Resolve symbolic links in the path names
348 -- if Follow_Links is True.
350 function Path_Name_Of
351 (File_Name : File_Name_Type;
352 Directory : Path_Name_Type) return String;
353 -- Returns the path name of a (non project) file.
354 -- Returns an empty string if file cannot be found.
356 procedure Prepare_Ada_Naming_Exceptions
357 (List : Array_Element_Id;
358 In_Tree : Project_Tree_Ref;
359 Kind : Spec_Or_Body);
360 -- Prepare the internal hash tables used for checking naming exceptions
361 -- for Ada. Insert all elements of List in the tables.
363 function Project_Extends
364 (Extending : Project_Id;
365 Extended : Project_Id;
366 In_Tree : Project_Tree_Ref) return Boolean;
367 -- Returns True if Extending is extending Extended either directly or
370 procedure Record_Ada_Source
371 (File_Name : File_Name_Type;
372 Path_Name : Path_Name_Type;
373 Project : Project_Id;
374 In_Tree : Project_Tree_Ref;
375 Data : in out Project_Data;
376 Location : Source_Ptr;
377 Current_Source : in out String_List_Id;
378 Source_Recorded : in out Boolean;
379 Follow_Links : Boolean);
380 -- Put a unit in the list of units of a project, if the file name
381 -- corresponds to a valid unit name.
383 procedure Record_Other_Sources
384 (Project : Project_Id;
385 In_Tree : Project_Tree_Ref;
386 Data : in out Project_Data;
387 Language : Language_Index;
388 Naming_Exceptions : Boolean);
389 -- Record the sources of a language in a project.
390 -- When Naming_Exceptions is True, mark the found sources as such, to
391 -- later remove those that are not named in a list of sources.
393 procedure Remove_Source
395 Replaced_By : Source_Id;
396 Project : Project_Id;
397 Data : in out Project_Data;
398 In_Tree : Project_Tree_Ref);
400 procedure Report_No_Sources
401 (Project : Project_Id;
403 In_Tree : Project_Tree_Ref;
404 Location : Source_Ptr);
405 -- Report an error or a warning depending on the value of When_No_Sources
406 -- when there are no sources for language Lang_Name.
408 procedure Show_Source_Dirs
409 (Data : Project_Data; In_Tree : Project_Tree_Ref);
410 -- List all the source directories of a project
413 (Language : Language_Index;
414 Naming : Naming_Data;
415 In_Tree : Project_Tree_Ref) return File_Name_Type;
416 -- Get the suffix for the source of a language from a package naming.
417 -- If not specified, return the default for the language.
419 procedure Warn_If_Not_Sources
420 (Project : Project_Id;
421 In_Tree : Project_Tree_Ref;
422 Conventions : Array_Element_Id;
424 Extending : Boolean);
425 -- Check that individual naming conventions apply to immediate
426 -- sources of the project; if not, issue a warning.
434 Data : in out Project_Data;
435 In_Tree : Project_Tree_Ref)
437 Language : constant Language_Index :=
438 In_Tree.Sources.Table (Id).Language;
443 -- Add the source to the global list
445 In_Tree.Sources.Table (Id).Next_In_Sources := In_Tree.First_Source;
446 In_Tree.First_Source := Id;
448 -- Add the source to the project list
450 Source := Data.Last_Source;
452 if Source = No_Source then
453 Data.First_Source := Id;
455 In_Tree.Sources.Table (Source).Next_In_Project := Id;
458 Data.Last_Source := Id;
460 -- Add the source to the language list
462 In_Tree.Sources.Table (Id).Next_In_Lang :=
463 In_Tree.Languages_Data.Table (Language).First_Source;
464 In_Tree.Languages_Data.Table (Language).First_Source := Id;
471 function ALI_File_Name (Source : String) return String is
473 -- If the source name has an extension, then replace it with
476 for Index in reverse Source'First + 1 .. Source'Last loop
477 if Source (Index) = '.' then
478 return Source (Source'First .. Index - 1) & ALI_Suffix;
482 -- If there is no dot, or if it is the first character, just add the
485 return Source & ALI_Suffix;
493 (Project : Project_Id;
494 In_Tree : Project_Tree_Ref;
495 Report_Error : Put_Line_Access;
496 Follow_Links : Boolean;
497 When_No_Sources : Error_Warning)
499 Data : Project_Data := In_Tree.Projects.Table (Project);
500 Extending : Boolean := False;
502 Lang_Proc_Pkg : Package_Id;
503 Linker_Name : Variable_Value;
506 Nmsc.When_No_Sources := When_No_Sources;
507 Error_Report := Report_Error;
509 Recursive_Dirs.Reset;
511 Check_If_Externally_Built (Project, In_Tree, Data);
513 -- Object, exec and source directories
515 Get_Directories (Project, In_Tree, Data);
517 -- Get the programming languages
519 Check_Programming_Languages (In_Tree, Project, Data);
521 -- Check configuration in multi language mode
523 if Get_Mode = Multi_Language then
524 Check_Configuration (Project, In_Tree, Data);
527 -- Library attributes
529 Check_Library_Attributes (Project, In_Tree, Data);
531 if Current_Verbosity = High then
532 Show_Source_Dirs (Data, In_Tree);
535 Check_Package_Naming (Project, In_Tree, Data);
537 Extending := Data.Extends /= No_Project;
539 Check_Naming_Schemes (Data, Project, In_Tree);
541 if Get_Mode = Ada_Only then
542 Prepare_Ada_Naming_Exceptions
543 (Data.Naming.Bodies, In_Tree, Body_Part);
544 Prepare_Ada_Naming_Exceptions
545 (Data.Naming.Specs, In_Tree, Specification);
550 if Data.Source_Dirs /= Nil_String then
551 Look_For_Sources (Project, In_Tree, Data, Follow_Links);
553 if Get_Mode = Ada_Only then
555 -- Check that all individual naming conventions apply to sources
556 -- of this project file.
559 (Project, In_Tree, Data.Naming.Bodies,
561 Extending => Extending);
563 (Project, In_Tree, Data.Naming.Specs,
565 Extending => Extending);
567 elsif Get_Mode = Multi_Language and then
568 (not Data.Externally_Built) and then
572 Language : Language_Index;
574 Src_Data : Source_Data;
575 Alt_Lang : Alternate_Language_Id;
576 Alt_Lang_Data : Alternate_Language_Data;
579 Language := Data.First_Language_Processing;
580 while Language /= No_Language_Index loop
581 Source := Data.First_Source;
582 Source_Loop : while Source /= No_Source loop
583 Src_Data := In_Tree.Sources.Table (Source);
585 exit Source_Loop when Src_Data.Language = Language;
587 Alt_Lang := Src_Data.Alternate_Languages;
590 while Alt_Lang /= No_Alternate_Language loop
592 In_Tree.Alt_Langs.Table (Alt_Lang);
594 when Alt_Lang_Data.Language = Language;
595 Alt_Lang := Alt_Lang_Data.Next;
596 end loop Alternate_Loop;
598 Source := Src_Data.Next_In_Project;
599 end loop Source_Loop;
601 if Source = No_Source then
605 (In_Tree.Languages_Data.Table
606 (Language).Display_Name),
611 Language := In_Tree.Languages_Data.Table (Language).Next;
617 -- If it is a library project file, check if it is a standalone library
620 Check_Stand_Alone_Library (Project, In_Tree, Data, Extending);
623 -- Put the list of Mains, if any, in the project data
625 Get_Mains (Project, In_Tree, Data);
627 -- In multi-language mode, check if there is a linker specified
629 if Get_Mode = Multi_Language then
631 Value_Of (Name_Language_Processing, Data.Decl.Packages, In_Tree);
633 if Lang_Proc_Pkg /= No_Package then
636 (Variable_Name => Name_Linker,
638 In_Tree.Packages.Table (Lang_Proc_Pkg).Decl.Attributes,
641 if Linker_Name /= Nil_Variable_Value then
642 Get_Name_String (Linker_Name.Value);
645 -- A non empty linker name was specified
647 Data.Linker_Name := File_Name_Type (Linker_Name.Value);
654 -- Update the project data in the Projects table
656 In_Tree.Projects.Table (Project) := Data;
658 Free_Ada_Naming_Exceptions;
665 procedure Check_Ada_Name (Name : String; Unit : out Name_Id) is
666 The_Name : String := Name;
668 Need_Letter : Boolean := True;
669 Last_Underscore : Boolean := False;
670 OK : Boolean := The_Name'Length > 0;
675 Name_Len := The_Name'Length;
676 Name_Buffer (1 .. Name_Len) := The_Name;
678 -- Special cases of children of packages A, G, I and S on VMS
680 if OpenVMS_On_Target and then
681 Name_Len > 3 and then
682 Name_Buffer (2 .. 3) = "__" and then
683 ((Name_Buffer (1) = 'a') or else (Name_Buffer (1) = 'g') or else
684 (Name_Buffer (1) = 'i') or else (Name_Buffer (1) = 's'))
686 Name_Buffer (2) := '.';
687 Name_Buffer (3 .. Name_Len - 1) := Name_Buffer (4 .. Name_Len);
688 Name_Len := Name_Len - 1;
691 Real_Name := Name_Find;
693 -- Check first that the given name is not an Ada 95 reserved word. The
694 -- reason for the Ada 95 here is that we do not want to exclude the case
695 -- of an Ada 95 unit called Interface (for example). In Ada 2005, such
696 -- a unit name would be rejected anyway by the compiler, so there is no
697 -- requirement that the project file parser reject this.
699 if Get_Name_Table_Byte (Real_Name) /= 0
700 and then Real_Name /= Name_Project
701 and then Real_Name /= Name_Extends
702 and then Real_Name /= Name_External
703 and then Real_Name not in Ada_2005_Reserved_Words
707 if Current_Verbosity = High then
708 Write_Str (The_Name);
709 Write_Line (" is an Ada reserved word.");
715 for Index in The_Name'Range loop
718 -- We need a letter (at the beginning, and following a dot),
719 -- but we don't have one.
721 if Is_Letter (The_Name (Index)) then
722 Need_Letter := False;
727 if Current_Verbosity = High then
728 Write_Int (Types.Int (Index));
730 Write_Char (The_Name (Index));
731 Write_Line ("' is not a letter.");
737 elsif Last_Underscore
738 and then (The_Name (Index) = '_' or else The_Name (Index) = '.')
740 -- Two underscores are illegal, and a dot cannot follow
745 if Current_Verbosity = High then
746 Write_Int (Types.Int (Index));
748 Write_Char (The_Name (Index));
749 Write_Line ("' is illegal here.");
754 elsif The_Name (Index) = '.' then
756 -- We need a letter after a dot
760 elsif The_Name (Index) = '_' then
761 Last_Underscore := True;
764 -- We need an letter or a digit
766 Last_Underscore := False;
768 if not Is_Alphanumeric (The_Name (Index)) then
771 if Current_Verbosity = High then
772 Write_Int (Types.Int (Index));
774 Write_Char (The_Name (Index));
775 Write_Line ("' is not alphanumeric.");
783 -- Cannot end with an underscore or a dot
785 OK := OK and then not Need_Letter and then not Last_Underscore;
791 -- Signal a problem with No_Name
797 --------------------------------------
798 -- Check_Ada_Naming_Scheme_Validity --
799 --------------------------------------
801 procedure Check_Ada_Naming_Scheme_Validity
802 (Project : Project_Id;
803 In_Tree : Project_Tree_Ref;
804 Naming : Naming_Data)
807 -- Only check if we are not using the Default naming scheme
809 if Naming /= In_Tree.Private_Part.Default_Naming then
811 Dot_Replacement : constant String :=
813 (Naming.Dot_Replacement);
815 Spec_Suffix : constant String :=
816 Spec_Suffix_Of (In_Tree, "ada", Naming);
818 Body_Suffix : constant String :=
819 Body_Suffix_Of (In_Tree, "ada", Naming);
821 Separate_Suffix : constant String :=
823 (Naming.Separate_Suffix);
826 -- Dot_Replacement cannot
828 -- - start or end with an alphanumeric
830 -- - start with an '_' followed by an alphanumeric
831 -- - contain a '.' except if it is "."
833 if Dot_Replacement'Length = 0
834 or else Is_Alphanumeric
835 (Dot_Replacement (Dot_Replacement'First))
836 or else Is_Alphanumeric
837 (Dot_Replacement (Dot_Replacement'Last))
838 or else (Dot_Replacement (Dot_Replacement'First) = '_'
840 (Dot_Replacement'Length = 1
843 (Dot_Replacement (Dot_Replacement'First + 1))))
844 or else (Dot_Replacement'Length > 1
846 Index (Source => Dot_Replacement,
847 Pattern => ".") /= 0)
851 '"' & Dot_Replacement &
852 """ is illegal for Dot_Replacement.",
853 Naming.Dot_Repl_Loc);
860 (Spec_Suffix, Dot_Replacement = ".")
862 Err_Vars.Error_Msg_File_1 :=
863 Spec_Suffix_Id_Of (In_Tree, "ada", Naming);
866 "{ is illegal for Spec_Suffix",
867 Naming.Ada_Spec_Suffix_Loc);
871 (Body_Suffix, Dot_Replacement = ".")
873 Err_Vars.Error_Msg_File_1 :=
874 Body_Suffix_Id_Of (In_Tree, "ada", Naming);
877 "{ is illegal for Body_Suffix",
878 Naming.Ada_Body_Suffix_Loc);
881 if Body_Suffix /= Separate_Suffix then
883 (Separate_Suffix, Dot_Replacement = ".")
885 Err_Vars.Error_Msg_File_1 := Naming.Separate_Suffix;
888 "{ is illegal for Separate_Suffix",
889 Naming.Sep_Suffix_Loc);
893 -- Spec_Suffix cannot have the same termination as
894 -- Body_Suffix or Separate_Suffix
896 if Spec_Suffix'Length <= Body_Suffix'Length
898 Body_Suffix (Body_Suffix'Last -
899 Spec_Suffix'Length + 1 ..
900 Body_Suffix'Last) = Spec_Suffix
906 """) cannot end with" &
908 Spec_Suffix & """).",
909 Naming.Ada_Body_Suffix_Loc);
912 if Body_Suffix /= Separate_Suffix
913 and then Spec_Suffix'Length <= Separate_Suffix'Length
916 (Separate_Suffix'Last - Spec_Suffix'Length + 1
918 Separate_Suffix'Last) = Spec_Suffix
922 "Separate_Suffix (""" &
924 """) cannot end with" &
926 Spec_Suffix & """).",
927 Naming.Sep_Suffix_Loc);
931 end Check_Ada_Naming_Scheme_Validity;
933 -------------------------
934 -- Check_Configuration --
935 -------------------------
937 procedure Check_Configuration
938 (Project : Project_Id;
939 In_Tree : Project_Tree_Ref;
940 Data : in out Project_Data)
942 Compiler_Pkg : constant Package_Id :=
943 Value_Of (Name_Compiler, Data.Decl.Packages, In_Tree);
944 Binder_Pkg : constant Package_Id :=
945 Value_Of (Name_Binder, Data.Decl.Packages, In_Tree);
946 Element : Package_Element;
949 Current_Array : Array_Data;
950 Arr_Elmt_Id : Array_Element_Id;
951 Arr_Element : Array_Element;
952 List : String_List_Id;
954 Current_Language_Index : Language_Index;
956 procedure Get_Language (Name : Name_Id);
957 -- Check if this is the name of a language of the project and
958 -- set Current_Language_Index accordingly.
964 procedure Get_Language (Name : Name_Id) is
965 Real_Language : Name_Id;
968 Get_Name_String (Name);
969 To_Lower (Name_Buffer (1 .. Name_Len));
970 Real_Language := Name_Find;
972 Current_Language_Index := Data.First_Language_Processing;
974 exit when Current_Language_Index = No_Language_Index or else
975 In_Tree.Languages_Data.Table (Current_Language_Index).Name =
977 Current_Language_Index :=
978 In_Tree.Languages_Data.Table (Current_Language_Index).Next;
982 -- Start of processing for Check_Configuration
985 if Compiler_Pkg /= No_Package then
986 Element := In_Tree.Packages.Table (Compiler_Pkg);
988 Arrays := Element.Decl.Arrays;
989 while Arrays /= No_Array loop
990 Current_Array := In_Tree.Arrays.Table (Arrays);
992 Arr_Elmt_Id := Current_Array.Value;
993 while Arr_Elmt_Id /= No_Array_Element loop
994 Arr_Element := In_Tree.Array_Elements.Table (Arr_Elmt_Id);
995 Get_Language (Arr_Element.Index);
997 if Current_Language_Index /= No_Language_Index then
998 case Current_Array.Name is
999 when Name_Dependency_Switches =>
1000 List := Arr_Element.Value.Values;
1002 if List = Nil_String then
1005 "dependency option cannot be null",
1006 Arr_Element.Value.Location);
1010 In_Tree.Languages_Data.Table
1011 (Current_Language_Index)
1012 .Config.Dependency_Option,
1014 In_Tree => In_Tree);
1016 when Name_Dependency_Driver =>
1018 -- Attribute Dependency_Driver (<language>)
1020 List := Arr_Element.Value.Values;
1022 if List = Nil_String then
1025 "compute dependency cannot be null",
1026 Arr_Element.Value.Location);
1030 In_Tree.Languages_Data.Table
1031 (Current_Language_Index)
1032 .Config.Compute_Dependency,
1034 In_Tree => In_Tree);
1036 when Name_Include_Option =>
1038 -- Attribute Include_Option (<language>)
1040 List := Arr_Element.Value.Values;
1042 if List = Nil_String then
1045 "include option cannot be null",
1046 Arr_Element.Value.Location);
1050 In_Tree.Languages_Data.Table
1051 (Current_Language_Index).Config.Include_Option,
1053 In_Tree => In_Tree);
1055 when Name_Include_Path =>
1057 -- Attribute Include_Path (<language>)
1059 In_Tree.Languages_Data.Table
1060 (Current_Language_Index).Config.Include_Path :=
1061 Arr_Element.Value.Value;
1063 when Name_Include_Path_File =>
1065 -- Attribute Include_Path_File (<language>)
1067 In_Tree.Languages_Data.Table
1068 (Current_Language_Index).Config.Include_Path_File :=
1069 Arr_Element.Value.Value;
1073 -- Attribute Driver (<language>)
1075 Get_Name_String (Arr_Element.Value.Value);
1077 if Name_Len = 0 then
1080 "compiler driver name cannot be empty",
1081 Arr_Element.Value.Location);
1084 In_Tree.Languages_Data.Table
1085 (Current_Language_Index).Config.Compiler_Driver :=
1086 File_Name_Type (Arr_Element.Value.Value);
1088 when Name_Switches =>
1090 -- Attribute Minimum_Compiler_Options (<language>)
1092 List := Arr_Element.Value.Values;
1095 In_Tree.Languages_Data.Table
1096 (Current_Language_Index).Config.
1097 Compiler_Min_Options,
1099 In_Tree => In_Tree);
1101 when Name_Pic_Option =>
1103 -- Attribute Pic_Option (<language>)
1105 List := Arr_Element.Value.Values;
1107 if List = Nil_String then
1110 "compiler PIC option cannot be null",
1111 Arr_Element.Value.Location);
1115 In_Tree.Languages_Data.Table
1116 (Current_Language_Index).Config.
1117 Compilation_PIC_Option,
1119 In_Tree => In_Tree);
1121 when Name_Mapping_File_Switches =>
1123 -- Attribute Mapping_File_Switches (<language>)
1125 List := Arr_Element.Value.Values;
1127 if List = Nil_String then
1130 "mapping file switches cannot be null",
1131 Arr_Element.Value.Location);
1135 In_Tree.Languages_Data.Table
1136 (Current_Language_Index).Config.
1137 Mapping_File_Switches,
1139 In_Tree => In_Tree);
1141 when Name_Mapping_Spec_Suffix =>
1143 -- Attribute Mapping_Spec_Suffix (<language>)
1145 In_Tree.Languages_Data.Table
1146 (Current_Language_Index)
1147 .Config.Mapping_Spec_Suffix :=
1148 File_Name_Type (Arr_Element.Value.Value);
1150 when Name_Mapping_Body_Suffix =>
1152 -- Attribute Mapping_Body_Suffix (<language>)
1154 In_Tree.Languages_Data.Table
1155 (Current_Language_Index)
1156 .Config.Mapping_Body_Suffix :=
1157 File_Name_Type (Arr_Element.Value.Value);
1159 when Name_Config_File_Switches =>
1161 -- Attribute Config_File_Switches (<language>)
1163 List := Arr_Element.Value.Values;
1165 if List = Nil_String then
1168 "config file switches cannot be null",
1169 Arr_Element.Value.Location);
1173 In_Tree.Languages_Data.Table
1174 (Current_Language_Index).Config.
1175 Config_File_Switches,
1177 In_Tree => In_Tree);
1179 when Name_Config_Body_File_Name =>
1181 -- Attribute Config_Body_File_Name (<language>)
1183 In_Tree.Languages_Data.Table
1184 (Current_Language_Index).Config.Config_Body :=
1185 Arr_Element.Value.Value;
1187 when Name_Config_Body_File_Name_Pattern =>
1189 -- Attribute Config_Body_File_Name_Pattern
1192 In_Tree.Languages_Data.Table
1193 (Current_Language_Index)
1194 .Config.Config_Body_Pattern :=
1195 Arr_Element.Value.Value;
1197 when Name_Config_Spec_File_Name =>
1199 -- Attribute Config_Spec_File_Name (<language>)
1201 In_Tree.Languages_Data.Table
1202 (Current_Language_Index).Config.Config_Spec :=
1203 Arr_Element.Value.Value;
1205 when Name_Config_Spec_File_Name_Pattern =>
1207 -- Attribute Config_Spec_File_Name_Pattern
1210 In_Tree.Languages_Data.Table
1211 (Current_Language_Index)
1212 .Config.Config_Spec_Pattern :=
1213 Arr_Element.Value.Value;
1215 when Name_Config_File_Unique =>
1217 -- Attribute Config_File_Unique (<language>)
1220 In_Tree.Languages_Data.Table
1221 (Current_Language_Index)
1222 .Config.Config_File_Unique :=
1224 (Get_Name_String (Arr_Element.Value.Value));
1226 when Constraint_Error =>
1229 "illegal value gor Config_File_Unique",
1230 Arr_Element.Value.Location);
1238 Arr_Elmt_Id := Arr_Element.Next;
1241 Arrays := Current_Array.Next;
1245 -- Comment needed here ???
1247 if Binder_Pkg /= No_Package then
1248 Element := In_Tree.Packages.Table (Binder_Pkg);
1249 Arrays := Element.Decl.Arrays;
1250 while Arrays /= No_Array loop
1251 Current_Array := In_Tree.Arrays.Table (Arrays);
1253 Arr_Elmt_Id := Current_Array.Value;
1254 while Arr_Elmt_Id /= No_Array_Element loop
1255 Arr_Element := In_Tree.Array_Elements.Table (Arr_Elmt_Id);
1257 Get_Language (Arr_Element.Index);
1259 if Current_Language_Index /= No_Language_Index then
1260 case Current_Array.Name is
1263 -- Attribute Driver (<language>)
1265 In_Tree.Languages_Data.Table
1266 (Current_Language_Index).Config.Binder_Driver :=
1267 File_Name_Type (Arr_Element.Value.Value);
1269 when Name_Objects_Path =>
1271 -- Attribute Objects_Path (<language>)
1273 In_Tree.Languages_Data.Table
1274 (Current_Language_Index).Config.Objects_Path :=
1275 Arr_Element.Value.Value;
1277 when Name_Objects_Path_File =>
1279 -- Attribute Objects_Path_File (<language>)
1281 In_Tree.Languages_Data.Table
1282 (Current_Language_Index).Config.Objects_Path_File :=
1283 Arr_Element.Value.Value;
1287 -- Attribute Prefix (<language>)
1289 In_Tree.Languages_Data.Table
1290 (Current_Language_Index).Config.Binder_Prefix :=
1291 Arr_Element.Value.Value;
1298 Arr_Elmt_Id := Arr_Element.Next;
1301 Arrays := Current_Array.Next;
1304 end Check_Configuration;
1306 ----------------------
1307 -- Check_For_Source --
1308 ----------------------
1310 procedure Check_For_Source
1311 (File_Name : File_Name_Type;
1312 Path_Name : Path_Name_Type;
1313 Project : Project_Id;
1314 In_Tree : Project_Tree_Ref;
1315 Data : in out Project_Data;
1316 Location : Source_Ptr;
1317 Language : Language_Index;
1319 Naming_Exception : Boolean)
1321 Name : String := Get_Name_String (File_Name);
1322 Real_Location : Source_Ptr := Location;
1325 Canonical_Case_File_Name (Name);
1327 -- A file is a source of a language if Naming_Exception is True (case
1328 -- of naming exceptions) or if its file name ends with the suffix.
1332 (Name'Length > Suffix'Length
1334 Name (Name'Last - Suffix'Length + 1 .. Name'Last) = Suffix)
1336 if Real_Location = No_Location then
1337 Real_Location := Data.Location;
1341 Path : constant String := Get_Name_String (Path_Name);
1342 C_Path : String := Path;
1344 Path_Id : Path_Name_Type;
1345 C_Path_Id : Path_Name_Type;
1346 -- The path name id (in canonical case)
1348 File_Id : File_Name_Type;
1349 -- The file name id (in canonical case)
1351 Obj_Id : File_Name_Type;
1352 -- The object file name
1354 Obj_Path_Id : Path_Name_Type;
1355 -- The object path name
1357 Dep_Id : File_Name_Type;
1358 -- The dependency file name
1360 Dep_Path_Id : Path_Name_Type;
1361 -- The dependency path name
1363 Dot_Pos : Natural := 0;
1364 -- Position of the last dot in Name
1366 Source : Other_Source;
1367 Source_Id : Other_Source_Id := Data.First_Other_Source;
1370 Canonical_Case_File_Name (C_Path);
1372 -- Get the file name id
1374 Name_Len := Name'Length;
1375 Name_Buffer (1 .. Name_Len) := Name;
1376 File_Id := Name_Find;
1378 -- Get the path name id
1380 Name_Len := Path'Length;
1381 Name_Buffer (1 .. Name_Len) := Path;
1382 Path_Id := Name_Find;
1384 Name_Len := C_Path'Length;
1385 Name_Buffer (1 .. Name_Len) := C_Path;
1386 C_Path_Id := Name_Find;
1388 -- Find the position of the last dot
1390 for J in reverse Name'Range loop
1391 if Name (J) = '.' then
1397 if Dot_Pos <= Name'First then
1398 Dot_Pos := Name'Last + 1;
1401 -- Compute the object file name
1403 Get_Name_String (File_Id);
1404 Name_Len := Dot_Pos - Name'First;
1406 for J in Object_Suffix'Range loop
1407 Name_Len := Name_Len + 1;
1408 Name_Buffer (Name_Len) := Object_Suffix (J);
1411 Obj_Id := Name_Find;
1413 -- Compute the object path name
1415 Get_Name_String (Data.Display_Object_Dir);
1417 if Name_Buffer (Name_Len) /= Directory_Separator
1418 and then Name_Buffer (Name_Len) /= '/'
1420 Name_Len := Name_Len + 1;
1421 Name_Buffer (Name_Len) := Directory_Separator;
1424 Add_Str_To_Name_Buffer (Get_Name_String (Obj_Id));
1425 Obj_Path_Id := Name_Find;
1427 -- Compute the dependency file name
1429 Get_Name_String (File_Id);
1430 Name_Len := Dot_Pos - Name'First + 1;
1431 Name_Buffer (Name_Len) := '.';
1432 Name_Len := Name_Len + 1;
1433 Name_Buffer (Name_Len) := 'd';
1434 Dep_Id := Name_Find;
1436 -- Compute the dependency path name
1438 Get_Name_String (Data.Display_Object_Dir);
1440 if Name_Buffer (Name_Len) /= Directory_Separator
1441 and then Name_Buffer (Name_Len) /= '/'
1443 Name_Len := Name_Len + 1;
1444 Name_Buffer (Name_Len) := Directory_Separator;
1447 Add_Str_To_Name_Buffer (Get_Name_String (Dep_Id));
1448 Dep_Path_Id := Name_Find;
1450 -- Check if source is already in the list of source for this
1451 -- project: it may have already been specified as a naming
1452 -- exception for the same language or an other language, or
1453 -- they may be two identical file names in different source
1456 while Source_Id /= No_Other_Source loop
1457 Source := In_Tree.Other_Sources.Table (Source_Id);
1459 if Source.File_Name = File_Id then
1461 -- Two sources of different languages cannot have the same
1464 if Source.Language /= Language then
1465 Error_Msg_File_1 := File_Name;
1468 "{ cannot be a source of several languages",
1472 -- No problem if a file has already been specified as
1473 -- a naming exception of this language.
1475 elsif Source.Path_Name = C_Path_Id then
1477 -- Reset the naming exception flag, if this is not a
1478 -- naming exception.
1480 if not Naming_Exception then
1481 In_Tree.Other_Sources.Table
1482 (Source_Id).Naming_Exception := False;
1487 -- There are several files with the same names, but the
1488 -- order of the source directories is known (no /**):
1489 -- only the first one encountered is kept, the other ones
1492 elsif Data.Known_Order_Of_Source_Dirs then
1495 -- But it is an error if the order of the source directories
1499 Error_Msg_File_1 := File_Name;
1502 "{ is found in several source directories",
1507 -- Two sources with different file names cannot have the same
1508 -- object file name.
1510 elsif Source.Object_Name = Obj_Id then
1511 Error_Msg_File_1 := File_Id;
1512 Error_Msg_File_2 := Source.File_Name;
1513 Error_Msg_File_3 := Obj_Id;
1516 "{ and { have the same object file {",
1521 Source_Id := Source.Next;
1524 if Current_Verbosity = High then
1525 Write_Str (" found ");
1526 Display_Language_Name (Language);
1527 Write_Str (" source """);
1528 Write_Str (Get_Name_String (File_Name));
1530 Write_Str (" object path = ");
1531 Write_Line (Get_Name_String (Obj_Path_Id));
1534 -- Create the Other_Source record
1537 (Language => Language,
1538 File_Name => File_Id,
1539 Path_Name => Path_Id,
1540 Source_TS => File_Stamp (Path_Id),
1541 Object_Name => Obj_Id,
1542 Object_Path => Obj_Path_Id,
1543 Object_TS => File_Stamp (Obj_Path_Id),
1545 Dep_Path => Dep_Path_Id,
1546 Dep_TS => File_Stamp (Dep_Path_Id),
1547 Naming_Exception => Naming_Exception,
1548 Next => No_Other_Source);
1550 -- And add it to the Other_Sources table
1552 Other_Source_Table.Increment_Last (In_Tree.Other_Sources);
1553 In_Tree.Other_Sources.Table
1554 (Other_Source_Table.Last (In_Tree.Other_Sources)) := Source;
1556 -- There are sources of languages other than Ada in this project
1558 Data.Other_Sources_Present := True;
1560 -- And there are sources of this language in this project
1562 Set (Language, True, Data, In_Tree);
1564 -- Add this source to the list of sources of languages other than
1565 -- Ada of the project.
1567 if Data.First_Other_Source = No_Other_Source then
1568 Data.First_Other_Source :=
1569 Other_Source_Table.Last (In_Tree.Other_Sources);
1572 In_Tree.Other_Sources.Table (Data.Last_Other_Source).Next :=
1573 Other_Source_Table.Last (In_Tree.Other_Sources);
1576 Data.Last_Other_Source :=
1577 Other_Source_Table.Last (In_Tree.Other_Sources);
1580 end Check_For_Source;
1582 -------------------------------
1583 -- Check_If_Externally_Built --
1584 -------------------------------
1586 procedure Check_If_Externally_Built
1587 (Project : Project_Id;
1588 In_Tree : Project_Tree_Ref;
1589 Data : in out Project_Data)
1591 Externally_Built : constant Variable_Value :=
1593 (Name_Externally_Built,
1594 Data.Decl.Attributes, In_Tree);
1597 if not Externally_Built.Default then
1598 Get_Name_String (Externally_Built.Value);
1599 To_Lower (Name_Buffer (1 .. Name_Len));
1601 if Name_Buffer (1 .. Name_Len) = "true" then
1602 Data.Externally_Built := True;
1604 elsif Name_Buffer (1 .. Name_Len) /= "false" then
1605 Error_Msg (Project, In_Tree,
1606 "Externally_Built may only be true or false",
1607 Externally_Built.Location);
1611 if Current_Verbosity = High then
1612 Write_Str ("Project is ");
1614 if not Data.Externally_Built then
1618 Write_Line ("externally built.");
1620 end Check_If_Externally_Built;
1622 -----------------------------
1623 -- Check_Naming_Schemes --
1624 -----------------------------
1626 procedure Check_Naming_Schemes
1627 (Data : in out Project_Data;
1628 Project : Project_Id;
1629 In_Tree : Project_Tree_Ref)
1631 Naming_Id : constant Package_Id :=
1632 Util.Value_Of (Name_Naming, Data.Decl.Packages, In_Tree);
1633 Naming : Package_Element;
1635 procedure Check_Unit_Names (List : Array_Element_Id);
1636 -- Check that a list of unit names contains only valid names
1638 procedure Get_Exceptions (Kind : Source_Kind);
1640 procedure Get_Unit_Exceptions (Kind : Source_Kind);
1642 ----------------------
1643 -- Check_Unit_Names --
1644 ----------------------
1646 procedure Check_Unit_Names (List : Array_Element_Id) is
1647 Current : Array_Element_Id;
1648 Element : Array_Element;
1649 Unit_Name : Name_Id;
1652 -- Loop through elements of the string list
1655 while Current /= No_Array_Element loop
1656 Element := In_Tree.Array_Elements.Table (Current);
1658 -- Put file name in canonical case
1660 Get_Name_String (Element.Value.Value);
1661 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
1662 Element.Value.Value := Name_Find;
1664 -- Check that it contains a valid unit name
1666 Get_Name_String (Element.Index);
1667 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit_Name);
1669 if Unit_Name = No_Name then
1670 Err_Vars.Error_Msg_Name_1 := Element.Index;
1673 "%% is not a valid unit name.",
1674 Element.Value.Location);
1677 if Current_Verbosity = High then
1678 Write_Str (" Unit (""");
1679 Write_Str (Get_Name_String (Unit_Name));
1683 Element.Index := Unit_Name;
1684 In_Tree.Array_Elements.Table (Current) := Element;
1687 Current := Element.Next;
1689 end Check_Unit_Names;
1691 --------------------
1692 -- Get_Exceptions --
1693 --------------------
1695 procedure Get_Exceptions (Kind : Source_Kind) is
1696 Exceptions : Array_Element_Id;
1697 Exception_List : Variable_Value;
1698 Element_Id : String_List_Id;
1699 Element : String_Element;
1700 File_Name : File_Name_Type;
1701 Lang_Id : Language_Index;
1709 (Name_Implementation_Exceptions,
1710 In_Arrays => Naming.Decl.Arrays,
1711 In_Tree => In_Tree);
1716 (Name_Specification_Exceptions,
1717 In_Arrays => Naming.Decl.Arrays,
1718 In_Tree => In_Tree);
1721 Lang_Id := Data.First_Language_Processing;
1722 while Lang_Id /= No_Language_Index loop
1723 if In_Tree.Languages_Data.Table (Lang_Id).Config.Kind =
1726 Lang := In_Tree.Languages_Data.Table (Lang_Id).Name;
1728 Exception_List := Value_Of
1730 In_Array => Exceptions,
1731 In_Tree => In_Tree);
1733 if Exception_List /= Nil_Variable_Value then
1734 Element_Id := Exception_List.Values;
1736 while Element_Id /= Nil_String loop
1738 In_Tree.String_Elements.Table (Element_Id);
1739 Get_Name_String (Element.Value);
1740 Canonical_Case_File_Name
1741 (Name_Buffer (1 .. Name_Len));
1742 File_Name := Name_Find;
1744 Source := Data.First_Source;
1745 while Source /= No_Source
1747 In_Tree.Sources.Table (Source).File /= File_Name
1750 In_Tree.Sources.Table (Source).Next_In_Project;
1753 if Source = No_Source then
1755 -- This is a new source. Create an entry for it
1756 -- in the Sources table.
1758 Source_Data_Table.Increment_Last (In_Tree.Sources);
1759 Source := Source_Data_Table.Last (In_Tree.Sources);
1761 if Current_Verbosity = High then
1762 Write_Str ("Adding source #");
1763 Write_Str (Source'Img);
1764 Write_Str (", File : ");
1765 Write_Line (Get_Name_String (File_Name));
1769 Src_Data : Source_Data := No_Source_Data;
1771 Src_Data.Project := Project;
1772 Src_Data.Language_Name := Lang;
1773 Src_Data.Language := Lang_Id;
1774 Src_Data.Kind := Kind;
1775 Src_Data.File := File_Name;
1776 Src_Data.Display_File :=
1777 File_Name_Type (Element.Value);
1778 Src_Data.Object := Object_Name (File_Name);
1779 Src_Data.Dependency :=
1780 In_Tree.Languages_Data.Table
1781 (Lang_Id).Config.Dependency_Kind;
1782 Src_Data.Dep_Name :=
1783 Dependency_Name (File_Name, Src_Data.Dependency);
1784 Src_Data.Switches := Switches_Name (File_Name);
1785 Src_Data.Naming_Exception := True;
1786 In_Tree.Sources.Table (Source) := Src_Data;
1789 Add_Source (Source, Data, In_Tree);
1792 -- Check if the file name is already recorded for
1793 -- another language or another kind.
1796 In_Tree.Sources.Table (Source).Language /= Lang_Id
1801 "the same file cannot be a source " &
1805 elsif In_Tree.Sources.Table (Source).Kind /= Kind then
1809 "the same file cannot be a source " &
1814 -- If the file is already recorded for the same
1815 -- language and the same kind, it means that the file
1816 -- name appears several times in the *_Exceptions
1817 -- attribute; so there is nothing to do.
1821 Element_Id := Element.Next;
1826 Lang_Id := In_Tree.Languages_Data.Table (Lang_Id).Next;
1830 -------------------------
1831 -- Get_Unit_Exceptions --
1832 -------------------------
1834 procedure Get_Unit_Exceptions (Kind : Source_Kind) is
1835 Exceptions : Array_Element_Id;
1836 Element : Array_Element;
1839 File_Name : File_Name_Type;
1840 Lang_Id : constant Language_Index :=
1841 Data.Unit_Based_Language_Index;
1842 Lang : constant Name_Id :=
1843 Data.Unit_Based_Language_Name;
1846 Source_To_Replace : Source_Id := No_Source;
1848 Other_Project : Project_Id;
1849 Other_Part : Source_Id;
1852 if Lang_Id = No_Language_Index or else Lang = No_Name then
1857 Exceptions := Value_Of
1859 In_Arrays => Naming.Decl.Arrays,
1860 In_Tree => In_Tree);
1862 if Exceptions = No_Array_Element then
1865 (Name_Implementation,
1866 In_Arrays => Naming.Decl.Arrays,
1867 In_Tree => In_Tree);
1874 In_Arrays => Naming.Decl.Arrays,
1875 In_Tree => In_Tree);
1877 if Exceptions = No_Array_Element then
1878 Exceptions := Value_Of
1879 (Name_Specification,
1880 In_Arrays => Naming.Decl.Arrays,
1881 In_Tree => In_Tree);
1886 while Exceptions /= No_Array_Element loop
1887 Element := In_Tree.Array_Elements.Table (Exceptions);
1889 Get_Name_String (Element.Value.Value);
1890 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
1891 File_Name := Name_Find;
1893 Get_Name_String (Element.Index);
1894 To_Lower (Name_Buffer (1 .. Name_Len));
1897 Index := Element.Value.Index;
1899 -- For Ada, check if it is a valid unit name
1901 if Lang = Name_Ada then
1902 Get_Name_String (Element.Index);
1903 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit);
1905 if Unit = No_Name then
1906 Err_Vars.Error_Msg_Name_1 := Element.Index;
1909 "%% is not a valid unit name.",
1910 Element.Value.Location);
1914 if Unit /= No_Name then
1916 -- Check if the source already exists
1918 Source := In_Tree.First_Source;
1919 Source_To_Replace := No_Source;
1921 while Source /= No_Source and then
1922 (In_Tree.Sources.Table (Source).Unit /= Unit or else
1923 In_Tree.Sources.Table (Source).Index /= Index)
1925 Source := In_Tree.Sources.Table (Source).Next_In_Sources;
1928 if Source /= No_Source then
1929 if In_Tree.Sources.Table (Source).Kind /= Kind then
1930 Other_Part := Source;
1934 In_Tree.Sources.Table (Source).Next_In_Sources;
1936 exit when Source = No_Source or else
1937 (In_Tree.Sources.Table (Source).Unit = Unit
1939 In_Tree.Sources.Table (Source).Index = Index);
1943 if Source /= No_Source then
1944 Other_Project := In_Tree.Sources.Table (Source).Project;
1946 if Is_Extending (Project, Other_Project, In_Tree) then
1948 In_Tree.Sources.Table (Source).Other_Part;
1950 -- Record the source to be removed
1952 Source_To_Replace := Source;
1953 Source := No_Source;
1956 Error_Msg_Name_1 := Unit;
1961 "unit%% cannot belong to two projects " &
1963 Element.Value.Location);
1968 if Source = No_Source then
1969 Source_Data_Table.Increment_Last (In_Tree.Sources);
1970 Source := Source_Data_Table.Last (In_Tree.Sources);
1972 if Current_Verbosity = High then
1973 Write_Str ("Adding source #");
1974 Write_Str (Source'Img);
1975 Write_Str (", File : ");
1976 Write_Str (Get_Name_String (File_Name));
1977 Write_Str (", Unit : ");
1978 Write_Line (Get_Name_String (Unit));
1982 Src_Data : Source_Data := No_Source_Data;
1985 Src_Data.Project := Project;
1986 Src_Data.Language_Name := Lang;
1987 Src_Data.Language := Lang_Id;
1988 Src_Data.Kind := Kind;
1989 Src_Data.Other_Part := Other_Part;
1990 Src_Data.Unit := Unit;
1991 Src_Data.Index := Index;
1992 Src_Data.File := File_Name;
1993 Src_Data.Object := Object_Name (File_Name);
1994 Src_Data.Display_File :=
1995 File_Name_Type (Element.Value.Value);
1996 Src_Data.Dependency := In_Tree.Languages_Data.Table
1997 (Lang_Id).Config.Dependency_Kind;
1998 Src_Data.Dep_Name :=
1999 Dependency_Name (File_Name, Src_Data.Dependency);
2000 Src_Data.Switches := Switches_Name (File_Name);
2001 Src_Data.Naming_Exception := True;
2002 In_Tree.Sources.Table (Source) := Src_Data;
2005 Add_Source (Source, Data, In_Tree);
2007 if Source_To_Replace /= No_Source then
2009 (Source_To_Replace, Source, Project, Data, In_Tree);
2014 Exceptions := Element.Next;
2017 end Get_Unit_Exceptions;
2019 -- Start of processing for Check_Naming_Schemes
2022 if Get_Mode = Ada_Only then
2024 -- If there is a package Naming, we will put in Data.Naming what is
2025 -- in this package Naming.
2027 if Naming_Id /= No_Package then
2028 Naming := In_Tree.Packages.Table (Naming_Id);
2030 if Current_Verbosity = High then
2031 Write_Line ("Checking ""Naming"" for Ada.");
2035 Bodies : constant Array_Element_Id :=
2037 (Name_Body, Naming.Decl.Arrays, In_Tree);
2039 Specs : constant Array_Element_Id :=
2041 (Name_Spec, Naming.Decl.Arrays, In_Tree);
2044 if Bodies /= No_Array_Element then
2046 -- We have elements in the array Body_Part
2048 if Current_Verbosity = High then
2049 Write_Line ("Found Bodies.");
2052 Data.Naming.Bodies := Bodies;
2053 Check_Unit_Names (Bodies);
2056 if Current_Verbosity = High then
2057 Write_Line ("No Bodies.");
2061 if Specs /= No_Array_Element then
2063 -- We have elements in the array Specs
2065 if Current_Verbosity = High then
2066 Write_Line ("Found Specs.");
2069 Data.Naming.Specs := Specs;
2070 Check_Unit_Names (Specs);
2073 if Current_Verbosity = High then
2074 Write_Line ("No Specs.");
2079 -- We are now checking if variables Dot_Replacement, Casing,
2080 -- Spec_Suffix, Body_Suffix and/or Separate_Suffix exist.
2082 -- For each variable, if it does not exist, we do nothing,
2083 -- because we already have the default.
2085 -- Check Dot_Replacement
2088 Dot_Replacement : constant Variable_Value :=
2090 (Name_Dot_Replacement,
2091 Naming.Decl.Attributes, In_Tree);
2094 pragma Assert (Dot_Replacement.Kind = Single,
2095 "Dot_Replacement is not a single string");
2097 if not Dot_Replacement.Default then
2098 Get_Name_String (Dot_Replacement.Value);
2100 if Name_Len = 0 then
2103 "Dot_Replacement cannot be empty",
2104 Dot_Replacement.Location);
2107 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2108 Data.Naming.Dot_Replacement := Name_Find;
2109 Data.Naming.Dot_Repl_Loc := Dot_Replacement.Location;
2114 if Current_Verbosity = High then
2115 Write_Str (" Dot_Replacement = """);
2116 Write_Str (Get_Name_String (Data.Naming.Dot_Replacement));
2124 Casing_String : constant Variable_Value :=
2127 Naming.Decl.Attributes,
2131 pragma Assert (Casing_String.Kind = Single,
2132 "Casing is not a single string");
2134 if not Casing_String.Default then
2136 Casing_Image : constant String :=
2137 Get_Name_String (Casing_String.Value);
2140 Casing_Value : constant Casing_Type :=
2141 Value (Casing_Image);
2143 Data.Naming.Casing := Casing_Value;
2147 when Constraint_Error =>
2148 if Casing_Image'Length = 0 then
2151 "Casing cannot be an empty string",
2152 Casing_String.Location);
2155 Name_Len := Casing_Image'Length;
2156 Name_Buffer (1 .. Name_Len) := Casing_Image;
2157 Err_Vars.Error_Msg_Name_1 := Name_Find;
2160 "%% is not a correct Casing",
2161 Casing_String.Location);
2167 if Current_Verbosity = High then
2168 Write_Str (" Casing = ");
2169 Write_Str (Image (Data.Naming.Casing));
2174 -- Check Spec_Suffix
2177 Ada_Spec_Suffix : constant Variable_Value :=
2181 In_Array => Data.Naming.Spec_Suffix,
2182 In_Tree => In_Tree);
2185 if Ada_Spec_Suffix.Kind = Single
2186 and then Get_Name_String (Ada_Spec_Suffix.Value) /= ""
2188 Get_Name_String (Ada_Spec_Suffix.Value);
2189 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2190 Set_Spec_Suffix (In_Tree, "ada", Data.Naming, Name_Find);
2191 Data.Naming.Ada_Spec_Suffix_Loc := Ada_Spec_Suffix.Location;
2198 Default_Ada_Spec_Suffix);
2202 if Current_Verbosity = High then
2203 Write_Str (" Spec_Suffix = """);
2204 Write_Str (Spec_Suffix_Of (In_Tree, "ada", Data.Naming));
2209 -- Check Body_Suffix
2212 Ada_Body_Suffix : constant Variable_Value :=
2216 In_Array => Data.Naming.Body_Suffix,
2217 In_Tree => In_Tree);
2220 if Ada_Body_Suffix.Kind = Single
2221 and then Get_Name_String (Ada_Body_Suffix.Value) /= ""
2223 Get_Name_String (Ada_Body_Suffix.Value);
2224 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2225 Set_Body_Suffix (In_Tree, "ada", Data.Naming, Name_Find);
2226 Data.Naming.Ada_Body_Suffix_Loc := Ada_Body_Suffix.Location;
2233 Default_Ada_Body_Suffix);
2237 if Current_Verbosity = High then
2238 Write_Str (" Body_Suffix = """);
2239 Write_Str (Body_Suffix_Of (In_Tree, "ada", Data.Naming));
2244 -- Check Separate_Suffix
2247 Ada_Sep_Suffix : constant Variable_Value :=
2249 (Variable_Name => Name_Separate_Suffix,
2250 In_Variables => Naming.Decl.Attributes,
2251 In_Tree => In_Tree);
2254 if Ada_Sep_Suffix.Default then
2255 Data.Naming.Separate_Suffix :=
2256 Body_Suffix_Id_Of (In_Tree, "ada", Data.Naming);
2259 Get_Name_String (Ada_Sep_Suffix.Value);
2261 if Name_Len = 0 then
2264 "Separate_Suffix cannot be empty",
2265 Ada_Sep_Suffix.Location);
2268 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2269 Data.Naming.Separate_Suffix := Name_Find;
2270 Data.Naming.Sep_Suffix_Loc := Ada_Sep_Suffix.Location;
2275 if Current_Verbosity = High then
2276 Write_Str (" Separate_Suffix = """);
2277 Write_Str (Get_Name_String (Data.Naming.Separate_Suffix));
2282 -- Check if Data.Naming is valid
2284 Check_Ada_Naming_Scheme_Validity (Project, In_Tree, Data.Naming);
2287 elsif not In_Configuration then
2289 -- Look into package Naming, if there is one
2291 if Naming_Id /= No_Package then
2292 Naming := In_Tree.Packages.Table (Naming_Id);
2294 if Current_Verbosity = High then
2295 Write_Line ("Checking package Naming.");
2298 -- We are now checking if attribute Dot_Replacement, Casing,
2299 -- and/or Separate_Suffix exist.
2301 -- For each attribute, if it does not exist, we do nothing,
2302 -- because we already have the default.
2303 -- Otherwise, for all unit-based languages, we put the declared
2304 -- value in the language config.
2307 Dot_Repl : constant Variable_Value :=
2309 (Name_Dot_Replacement,
2310 Naming.Decl.Attributes, In_Tree);
2311 Dot_Replacement : File_Name_Type := No_File;
2313 Casing_String : constant Variable_Value :=
2316 Naming.Decl.Attributes,
2318 Casing : Casing_Type;
2319 Casing_Defined : Boolean := False;
2321 Sep_Suffix : constant Variable_Value :=
2323 (Variable_Name => Name_Separate_Suffix,
2324 In_Variables => Naming.Decl.Attributes,
2325 In_Tree => In_Tree);
2326 Separate_Suffix : File_Name_Type := No_File;
2328 Lang_Id : Language_Index;
2330 -- Check attribute Dot_Replacement
2332 if not Dot_Repl.Default then
2333 Get_Name_String (Dot_Repl.Value);
2335 if Name_Len = 0 then
2338 "Dot_Replacement cannot be empty",
2342 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2343 Dot_Replacement := Name_Find;
2345 if Current_Verbosity = High then
2346 Write_Str (" Dot_Replacement = """);
2347 Write_Str (Get_Name_String (Dot_Replacement));
2354 -- Check attribute Casing
2356 if not Casing_String.Default then
2358 Casing_Image : constant String :=
2359 Get_Name_String (Casing_String.Value);
2362 Casing_Value : constant Casing_Type :=
2363 Value (Casing_Image);
2365 Casing := Casing_Value;
2366 Casing_Defined := True;
2368 if Current_Verbosity = High then
2369 Write_Str (" Casing = ");
2370 Write_Str (Image (Casing));
2377 when Constraint_Error =>
2378 if Casing_Image'Length = 0 then
2381 "Casing cannot be an empty string",
2382 Casing_String.Location);
2385 Name_Len := Casing_Image'Length;
2386 Name_Buffer (1 .. Name_Len) := Casing_Image;
2387 Err_Vars.Error_Msg_Name_1 := Name_Find;
2390 "%% is not a correct Casing",
2391 Casing_String.Location);
2396 if not Sep_Suffix.Default then
2397 Get_Name_String (Sep_Suffix.Value);
2399 if Name_Len = 0 then
2402 "Separate_Suffix cannot be empty",
2403 Sep_Suffix.Location);
2406 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2407 Separate_Suffix := Name_Find;
2409 if Current_Verbosity = High then
2410 Write_Str (" Separate_Suffix = """);
2412 (Get_Name_String (Data.Naming.Separate_Suffix));
2419 -- For all unit based languages, if any, set the specified
2420 -- value of Dot_Replacement, Casing and/or Separate_Suffix.
2422 if Dot_Replacement /= No_File or else
2423 Casing_Defined or else
2424 Separate_Suffix /= No_File
2426 Lang_Id := Data.First_Language_Processing;
2428 while Lang_Id /= No_Language_Index loop
2429 if In_Tree.Languages_Data.Table
2430 (Lang_Id).Config.Kind = Unit_Based
2432 if Dot_Replacement /= No_File then
2433 In_Tree.Languages_Data.Table
2434 (Lang_Id).Config.Naming_Data.Dot_Replacement :=
2438 if Casing_Defined then
2439 In_Tree.Languages_Data.Table
2440 (Lang_Id).Config.Naming_Data.Casing := Casing;
2443 if Separate_Suffix /= No_File then
2444 In_Tree.Languages_Data.Table
2445 (Lang_Id).Config.Naming_Data.Separate_Suffix :=
2451 In_Tree.Languages_Data.Table (Lang_Id).Next;
2456 -- Next, get the spec and body suffixes
2459 Suffix : Variable_Value;
2461 Lang_Id : Language_Index := Data.First_Language_Processing;
2464 while Lang_Id /= No_Language_Index loop
2465 Lang := In_Tree.Languages_Data.Table (Lang_Id).Name;
2471 Attribute_Or_Array_Name => Name_Spec_Suffix,
2472 In_Package => Naming_Id,
2473 In_Tree => In_Tree);
2475 if Suffix = Nil_Variable_Value then
2478 Attribute_Or_Array_Name => Name_Specification_Suffix,
2479 In_Package => Naming_Id,
2480 In_Tree => In_Tree);
2483 if Suffix /= Nil_Variable_Value then
2484 In_Tree.Languages_Data.Table (Lang_Id).
2485 Config.Naming_Data.Spec_Suffix :=
2486 File_Name_Type (Suffix.Value);
2493 Attribute_Or_Array_Name => Name_Body_Suffix,
2494 In_Package => Naming_Id,
2495 In_Tree => In_Tree);
2497 if Suffix = Nil_Variable_Value then
2500 Attribute_Or_Array_Name => Name_Implementation_Suffix,
2501 In_Package => Naming_Id,
2502 In_Tree => In_Tree);
2505 if Suffix /= Nil_Variable_Value then
2506 In_Tree.Languages_Data.Table (Lang_Id).
2507 Config.Naming_Data.Body_Suffix :=
2508 File_Name_Type (Suffix.Value);
2511 Lang_Id := In_Tree.Languages_Data.Table (Lang_Id).Next;
2515 -- Get the exceptions for file based languages
2517 Get_Exceptions (Spec);
2518 Get_Exceptions (Impl);
2520 -- Get the exceptions for unit based languages
2522 Get_Unit_Exceptions (Spec);
2523 Get_Unit_Exceptions (Impl);
2527 end Check_Naming_Schemes;
2529 ------------------------------
2530 -- Check_Library_Attributes --
2531 ------------------------------
2533 procedure Check_Library_Attributes
2534 (Project : Project_Id;
2535 In_Tree : Project_Tree_Ref;
2536 Data : in out Project_Data)
2538 Attributes : constant Prj.Variable_Id := Data.Decl.Attributes;
2540 Lib_Dir : constant Prj.Variable_Value :=
2542 (Snames.Name_Library_Dir, Attributes, In_Tree);
2544 Lib_Name : constant Prj.Variable_Value :=
2546 (Snames.Name_Library_Name, Attributes, In_Tree);
2548 Lib_Version : constant Prj.Variable_Value :=
2550 (Snames.Name_Library_Version, Attributes, In_Tree);
2552 Lib_ALI_Dir : constant Prj.Variable_Value :=
2554 (Snames.Name_Library_Ali_Dir, Attributes, In_Tree);
2556 The_Lib_Kind : constant Prj.Variable_Value :=
2558 (Snames.Name_Library_Kind, Attributes, In_Tree);
2560 Imported_Project_List : Project_List := Empty_Project_List;
2562 Continuation : String_Access := No_Continuation_String'Access;
2564 Support_For_Libraries : Library_Support;
2566 procedure Check_Library (Proj : Project_Id; Extends : Boolean);
2567 -- Check if an imported or extended project if also a library project
2573 procedure Check_Library (Proj : Project_Id; Extends : Boolean) is
2574 Proj_Data : Project_Data;
2577 if Proj /= No_Project then
2578 Proj_Data := In_Tree.Projects.Table (Proj);
2580 if not Proj_Data.Library then
2581 -- The only not library projects that are OK are those that
2584 if Proj_Data.Source_Dirs /= Nil_String then
2586 Error_Msg_Name_1 := Data.Name;
2587 Error_Msg_Name_2 := Proj_Data.Name;
2593 "library project %% cannot extend project %% " &
2594 "that is not a library project",
2601 "library project %% cannot import project %% " &
2602 "that is not a library project",
2606 Continuation := Continuation_String'Access;
2609 elsif Data.Library_Kind /= Static and then
2610 Proj_Data.Library_Kind = Static
2612 Error_Msg_Name_1 := Data.Name;
2613 Error_Msg_Name_2 := Proj_Data.Name;
2619 "shared library project %% cannot extend static " &
2620 "library project %%",
2627 "shared library project %% cannot import static " &
2628 "library project %%",
2632 Continuation := Continuation_String'Access;
2638 -- Special case of extending project
2640 if Data.Extends /= No_Project then
2642 Extended_Data : constant Project_Data :=
2643 In_Tree.Projects.Table (Data.Extends);
2646 -- If the project extended is a library project, we inherit
2647 -- the library name, if it is not redefined; we check that
2648 -- the library directory is specified.
2650 if Extended_Data.Library then
2651 if Lib_Name.Default then
2652 Data.Library_Name := Extended_Data.Library_Name;
2655 if Lib_Dir.Default then
2656 if not Data.Virtual then
2659 "a project extending a library project must " &
2660 "specify an attribute Library_Dir",
2668 pragma Assert (Lib_Dir.Kind = Single);
2670 if Lib_Dir.Value = Empty_String then
2671 if Current_Verbosity = High then
2672 Write_Line ("No library directory");
2676 -- Find path name, check that it is a directory
2681 File_Name_Type (Lib_Dir.Value),
2682 Data.Display_Directory,
2684 Data.Display_Library_Dir,
2685 Create => "library",
2686 Location => Lib_Dir.Location);
2688 if Data.Library_Dir = No_Path then
2690 -- Get the absolute name of the library directory that
2691 -- does not exist, to report an error.
2694 Dir_Name : constant String := Get_Name_String (Lib_Dir.Value);
2697 if Is_Absolute_Path (Dir_Name) then
2698 Err_Vars.Error_Msg_File_1 := File_Name_Type (Lib_Dir.Value);
2701 Get_Name_String (Data.Display_Directory);
2703 if Name_Buffer (Name_Len) /= Directory_Separator then
2704 Name_Len := Name_Len + 1;
2705 Name_Buffer (Name_Len) := Directory_Separator;
2709 (Name_Len + 1 .. Name_Len + Dir_Name'Length) :=
2711 Name_Len := Name_Len + Dir_Name'Length;
2712 Err_Vars.Error_Msg_File_1 := Name_Find;
2719 "library directory { does not exist",
2723 -- The library directory cannot be the same as the Object directory
2725 elsif Data.Library_Dir = Data.Object_Directory then
2728 "library directory cannot be the same " &
2729 "as object directory",
2731 Data.Library_Dir := No_Path;
2732 Data.Display_Library_Dir := No_Path;
2736 OK : Boolean := True;
2737 Dirs_Id : String_List_Id;
2738 Dir_Elem : String_Element;
2741 -- The library directory cannot be the same as a source
2742 -- directory of the current project.
2744 Dirs_Id := Data.Source_Dirs;
2745 while Dirs_Id /= Nil_String loop
2746 Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id);
2747 Dirs_Id := Dir_Elem.Next;
2749 if Data.Library_Dir = Path_Name_Type (Dir_Elem.Value) then
2750 Err_Vars.Error_Msg_File_1 :=
2751 File_Name_Type (Dir_Elem.Value);
2754 "library directory cannot be the same " &
2755 "as source directory {",
2764 -- The library directory cannot be the same as a source
2765 -- directory of another project either.
2768 for Pid in 1 .. Project_Table.Last (In_Tree.Projects) loop
2769 if Pid /= Project then
2770 Dirs_Id := In_Tree.Projects.Table (Pid).Source_Dirs;
2772 Dir_Loop : while Dirs_Id /= Nil_String loop
2773 Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id);
2774 Dirs_Id := Dir_Elem.Next;
2776 if Data.Library_Dir =
2777 Path_Name_Type (Dir_Elem.Value)
2779 Err_Vars.Error_Msg_File_1 :=
2780 File_Name_Type (Dir_Elem.Value);
2781 Err_Vars.Error_Msg_Name_1 :=
2782 In_Tree.Projects.Table (Pid).Name;
2786 "library directory cannot be the same " &
2787 "as source directory { of project %%",
2794 end loop Project_Loop;
2798 Data.Library_Dir := No_Path;
2799 Data.Display_Library_Dir := No_Path;
2801 elsif Current_Verbosity = High then
2803 -- Display the Library directory in high verbosity
2805 Write_Str ("Library directory =""");
2806 Write_Str (Get_Name_String (Data.Display_Library_Dir));
2813 pragma Assert (Lib_Name.Kind = Single);
2815 if Lib_Name.Value = Empty_String then
2816 if Current_Verbosity = High
2817 and then Data.Library_Name = No_Name
2819 Write_Line ("No library name");
2823 -- There is no restriction on the syntax of library names
2825 Data.Library_Name := Lib_Name.Value;
2828 if Data.Library_Name /= No_Name
2829 and then Current_Verbosity = High
2831 Write_Str ("Library name = """);
2832 Write_Str (Get_Name_String (Data.Library_Name));
2837 Data.Library_Dir /= No_Path
2839 Data.Library_Name /= No_Name;
2841 if Data.Library then
2842 if Get_Mode = Multi_Language then
2843 Support_For_Libraries := In_Tree.Config.Lib_Support;
2846 Support_For_Libraries := MLib.Tgt.Support_For_Libraries;
2849 if Support_For_Libraries = Prj.None then
2852 "?libraries are not supported on this platform",
2854 Data.Library := False;
2857 if Lib_ALI_Dir.Value = Empty_String then
2858 if Current_Verbosity = High then
2859 Write_Line ("No library 'A'L'I directory specified");
2861 Data.Library_ALI_Dir := Data.Library_Dir;
2862 Data.Display_Library_ALI_Dir := Data.Display_Library_Dir;
2865 -- Find path name, check that it is a directory
2870 File_Name_Type (Lib_ALI_Dir.Value),
2871 Data.Display_Directory,
2872 Data.Library_ALI_Dir,
2873 Data.Display_Library_ALI_Dir,
2874 Create => "library ALI",
2875 Location => Lib_ALI_Dir.Location);
2877 if Data.Library_ALI_Dir = No_Path then
2879 -- Get the absolute name of the library ALI directory that
2880 -- does not exist, to report an error.
2883 Dir_Name : constant String :=
2884 Get_Name_String (Lib_ALI_Dir.Value);
2887 if Is_Absolute_Path (Dir_Name) then
2888 Err_Vars.Error_Msg_File_1 :=
2889 File_Name_Type (Lib_Dir.Value);
2892 Get_Name_String (Data.Display_Directory);
2894 if Name_Buffer (Name_Len) /= Directory_Separator then
2895 Name_Len := Name_Len + 1;
2896 Name_Buffer (Name_Len) := Directory_Separator;
2900 (Name_Len + 1 .. Name_Len + Dir_Name'Length) :=
2902 Name_Len := Name_Len + Dir_Name'Length;
2903 Err_Vars.Error_Msg_File_1 := Name_Find;
2910 "library 'A'L'I directory { does not exist",
2911 Lib_ALI_Dir.Location);
2915 if Data.Library_ALI_Dir /= Data.Library_Dir then
2917 -- The library ALI directory cannot be the same as the
2918 -- Object directory.
2920 if Data.Library_ALI_Dir = Data.Object_Directory then
2923 "library 'A'L'I directory cannot be the same " &
2924 "as object directory",
2925 Lib_ALI_Dir.Location);
2926 Data.Library_ALI_Dir := No_Path;
2927 Data.Display_Library_ALI_Dir := No_Path;
2931 OK : Boolean := True;
2932 Dirs_Id : String_List_Id;
2933 Dir_Elem : String_Element;
2936 -- The library ALI directory cannot be the same as
2937 -- a source directory of the current project.
2939 Dirs_Id := Data.Source_Dirs;
2940 while Dirs_Id /= Nil_String loop
2941 Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id);
2942 Dirs_Id := Dir_Elem.Next;
2944 if Data.Library_ALI_Dir =
2945 Path_Name_Type (Dir_Elem.Value)
2947 Err_Vars.Error_Msg_File_1 :=
2948 File_Name_Type (Dir_Elem.Value);
2951 "library 'A'L'I directory cannot be " &
2952 "the same as source directory {",
2953 Lib_ALI_Dir.Location);
2961 -- The library ALI directory cannot be the same as
2962 -- a source directory of another project either.
2966 Pid in 1 .. Project_Table.Last (In_Tree.Projects)
2968 if Pid /= Project then
2970 In_Tree.Projects.Table (Pid).Source_Dirs;
2973 while Dirs_Id /= Nil_String loop
2975 In_Tree.String_Elements.Table (Dirs_Id);
2976 Dirs_Id := Dir_Elem.Next;
2978 if Data.Library_ALI_Dir =
2979 Path_Name_Type (Dir_Elem.Value)
2981 Err_Vars.Error_Msg_File_1 :=
2982 File_Name_Type (Dir_Elem.Value);
2983 Err_Vars.Error_Msg_Name_1 :=
2984 In_Tree.Projects.Table (Pid).Name;
2988 "library 'A'L'I directory cannot " &
2989 "be the same as source directory " &
2991 Lib_ALI_Dir.Location);
2993 exit ALI_Project_Loop;
2995 end loop ALI_Dir_Loop;
2997 end loop ALI_Project_Loop;
3001 Data.Library_ALI_Dir := No_Path;
3002 Data.Display_Library_ALI_Dir := No_Path;
3004 elsif Current_Verbosity = High then
3006 -- Display the Library ALI directory in high
3009 Write_Str ("Library ALI directory =""");
3011 (Get_Name_String (Data.Display_Library_ALI_Dir));
3019 pragma Assert (Lib_Version.Kind = Single);
3021 if Lib_Version.Value = Empty_String then
3022 if Current_Verbosity = High then
3023 Write_Line ("No library version specified");
3027 Data.Lib_Internal_Name := Lib_Version.Value;
3030 pragma Assert (The_Lib_Kind.Kind = Single);
3032 if The_Lib_Kind.Value = Empty_String then
3033 if Current_Verbosity = High then
3034 Write_Line ("No library kind specified");
3038 Get_Name_String (The_Lib_Kind.Value);
3041 Kind_Name : constant String :=
3042 To_Lower (Name_Buffer (1 .. Name_Len));
3044 OK : Boolean := True;
3047 if Kind_Name = "static" then
3048 Data.Library_Kind := Static;
3050 elsif Kind_Name = "dynamic" then
3051 Data.Library_Kind := Dynamic;
3053 elsif Kind_Name = "relocatable" then
3054 Data.Library_Kind := Relocatable;
3059 "illegal value for Library_Kind",
3060 The_Lib_Kind.Location);
3064 if Current_Verbosity = High and then OK then
3065 Write_Str ("Library kind = ");
3066 Write_Line (Kind_Name);
3069 if Data.Library_Kind /= Static and then
3070 Support_For_Libraries = Prj.Static_Only
3074 "only static libraries are supported " &
3076 The_Lib_Kind.Location);
3077 Data.Library := False;
3082 if Data.Library then
3083 if Current_Verbosity = High then
3084 Write_Line ("This is a library project file");
3087 if Get_Mode = Multi_Language then
3088 Check_Library (Data.Extends, Extends => True);
3090 Imported_Project_List := Data.Imported_Projects;
3091 while Imported_Project_List /= Empty_Project_List loop
3093 (In_Tree.Project_Lists.Table
3094 (Imported_Project_List).Project,
3096 Imported_Project_List :=
3097 In_Tree.Project_Lists.Table
3098 (Imported_Project_List).Next;
3106 if Data.Extends /= No_Project then
3107 In_Tree.Projects.Table (Data.Extends).Library := False;
3109 end Check_Library_Attributes;
3111 --------------------------
3112 -- Check_Package_Naming --
3113 --------------------------
3115 procedure Check_Package_Naming
3116 (Project : Project_Id;
3117 In_Tree : Project_Tree_Ref;
3118 Data : in out Project_Data)
3120 Naming_Id : constant Package_Id :=
3121 Util.Value_Of (Name_Naming, Data.Decl.Packages, In_Tree);
3123 Naming : Package_Element;
3126 -- If there is a package Naming, we will put in Data.Naming
3127 -- what is in this package Naming.
3129 if Naming_Id /= No_Package then
3130 Naming := In_Tree.Packages.Table (Naming_Id);
3132 if Current_Verbosity = High then
3133 Write_Line ("Checking ""Naming"".");
3136 -- Check Spec_Suffix
3139 Spec_Suffixs : Array_Element_Id :=
3145 Suffix : Array_Element_Id;
3146 Element : Array_Element;
3147 Suffix2 : Array_Element_Id;
3150 -- If some suffixs have been specified, we make sure that
3151 -- for each language for which a default suffix has been
3152 -- specified, there is a suffix specified, either the one
3153 -- in the project file or if there were none, the default.
3155 if Spec_Suffixs /= No_Array_Element then
3156 Suffix := Data.Naming.Spec_Suffix;
3158 while Suffix /= No_Array_Element loop
3160 In_Tree.Array_Elements.Table (Suffix);
3161 Suffix2 := Spec_Suffixs;
3163 while Suffix2 /= No_Array_Element loop
3164 exit when In_Tree.Array_Elements.Table
3165 (Suffix2).Index = Element.Index;
3166 Suffix2 := In_Tree.Array_Elements.Table
3170 -- There is a registered default suffix, but no
3171 -- suffix specified in the project file.
3172 -- Add the default to the array.
3174 if Suffix2 = No_Array_Element then
3175 Array_Element_Table.Increment_Last
3176 (In_Tree.Array_Elements);
3177 In_Tree.Array_Elements.Table
3178 (Array_Element_Table.Last
3179 (In_Tree.Array_Elements)) :=
3180 (Index => Element.Index,
3181 Src_Index => Element.Src_Index,
3182 Index_Case_Sensitive => False,
3183 Value => Element.Value,
3184 Next => Spec_Suffixs);
3185 Spec_Suffixs := Array_Element_Table.Last
3186 (In_Tree.Array_Elements);
3189 Suffix := Element.Next;
3192 -- Put the resulting array as the specification suffixs
3194 Data.Naming.Spec_Suffix := Spec_Suffixs;
3199 Current : Array_Element_Id := Data.Naming.Spec_Suffix;
3200 Element : Array_Element;
3203 while Current /= No_Array_Element loop
3204 Element := In_Tree.Array_Elements.Table (Current);
3205 Get_Name_String (Element.Value.Value);
3207 if Name_Len = 0 then
3210 "Spec_Suffix cannot be empty",
3211 Element.Value.Location);
3214 In_Tree.Array_Elements.Table (Current) := Element;
3215 Current := Element.Next;
3219 -- Check Body_Suffix
3222 Impl_Suffixs : Array_Element_Id :=
3228 Suffix : Array_Element_Id;
3229 Element : Array_Element;
3230 Suffix2 : Array_Element_Id;
3233 -- If some suffixes have been specified, we make sure that
3234 -- for each language for which a default suffix has been
3235 -- specified, there is a suffix specified, either the one
3236 -- in the project file or if there were none, the default.
3238 if Impl_Suffixs /= No_Array_Element then
3239 Suffix := Data.Naming.Body_Suffix;
3241 while Suffix /= No_Array_Element loop
3243 In_Tree.Array_Elements.Table (Suffix);
3244 Suffix2 := Impl_Suffixs;
3246 while Suffix2 /= No_Array_Element loop
3247 exit when In_Tree.Array_Elements.Table
3248 (Suffix2).Index = Element.Index;
3249 Suffix2 := In_Tree.Array_Elements.Table
3253 -- There is a registered default suffix, but no suffix was
3254 -- specified in the project file. Add the default to the
3257 if Suffix2 = No_Array_Element then
3258 Array_Element_Table.Increment_Last
3259 (In_Tree.Array_Elements);
3260 In_Tree.Array_Elements.Table
3261 (Array_Element_Table.Last
3262 (In_Tree.Array_Elements)) :=
3263 (Index => Element.Index,
3264 Src_Index => Element.Src_Index,
3265 Index_Case_Sensitive => False,
3266 Value => Element.Value,
3267 Next => Impl_Suffixs);
3268 Impl_Suffixs := Array_Element_Table.Last
3269 (In_Tree.Array_Elements);
3272 Suffix := Element.Next;
3275 -- Put the resulting array as the implementation suffixs
3277 Data.Naming.Body_Suffix := Impl_Suffixs;
3282 Current : Array_Element_Id := Data.Naming.Body_Suffix;
3283 Element : Array_Element;
3286 while Current /= No_Array_Element loop
3287 Element := In_Tree.Array_Elements.Table (Current);
3288 Get_Name_String (Element.Value.Value);
3290 if Name_Len = 0 then
3293 "Body_Suffix cannot be empty",
3294 Element.Value.Location);
3297 In_Tree.Array_Elements.Table (Current) := Element;
3298 Current := Element.Next;
3302 -- Get the exceptions, if any
3304 Data.Naming.Specification_Exceptions :=
3306 (Name_Specification_Exceptions,
3307 In_Arrays => Naming.Decl.Arrays,
3308 In_Tree => In_Tree);
3310 Data.Naming.Implementation_Exceptions :=
3312 (Name_Implementation_Exceptions,
3313 In_Arrays => Naming.Decl.Arrays,
3314 In_Tree => In_Tree);
3316 end Check_Package_Naming;
3318 ---------------------------------
3319 -- Check_Programming_Languages --
3320 ---------------------------------
3322 procedure Check_Programming_Languages
3323 (In_Tree : Project_Tree_Ref;
3324 Project : Project_Id;
3325 Data : in out Project_Data)
3327 Languages : Variable_Value := Nil_Variable_Value;
3328 Lang : Language_Index;
3332 Prj.Util.Value_Of (Name_Languages, Data.Decl.Attributes, In_Tree);
3333 Data.Ada_Sources_Present := Data.Source_Dirs /= Nil_String;
3334 Data.Other_Sources_Present := Data.Source_Dirs /= Nil_String;
3336 if Data.Source_Dirs /= Nil_String then
3338 -- Check if languages are specified in this project
3340 if Languages.Default then
3342 -- Attribute Languages is not specified. So, it defaults to
3343 -- a project of the default language only.
3345 Name_List_Table.Increment_Last (In_Tree.Name_Lists);
3346 Data.Languages := Name_List_Table.Last (In_Tree.Name_Lists);
3348 -- In Ada_Only mode, the default language is Ada
3350 if Get_Mode = Ada_Only then
3351 In_Tree.Name_Lists.Table (Data.Languages) :=
3352 (Name => Name_Ada, Next => No_Name_List);
3354 -- Attribute Languages is not specified. So, it defaults to
3355 -- a project of language Ada only.
3357 Data.Langs (Ada_Language_Index) := True;
3359 -- No sources of languages other than Ada
3361 Data.Other_Sources_Present := False;
3363 elsif In_Tree.Default_Language = No_Name then
3367 "no languages defined for this project",
3371 In_Tree.Name_Lists.Table (Data.Languages) :=
3372 (Name => In_Tree.Default_Language, Next => No_Name_List);
3373 Language_Data_Table.Increment_Last (In_Tree.Languages_Data);
3374 Data.First_Language_Processing :=
3375 Language_Data_Table.Last (In_Tree.Languages_Data);
3376 In_Tree.Languages_Data.Table
3377 (Data.First_Language_Processing) := No_Language_Data;
3378 In_Tree.Languages_Data.Table
3379 (Data.First_Language_Processing).Name :=
3380 In_Tree.Default_Language;
3381 Get_Name_String (In_Tree.Default_Language);
3382 Name_Buffer (1) := GNAT.Case_Util.To_Upper (Name_Buffer (1));
3383 In_Tree.Languages_Data.Table
3384 (Data.First_Language_Processing).Display_Name := Name_Find;
3386 Lang := In_Tree.First_Language;
3388 while Lang /= No_Language_Index loop
3389 if In_Tree.Languages_Data.Table (Lang).Name =
3390 In_Tree.Default_Language
3392 In_Tree.Languages_Data.Table
3393 (Data.First_Language_Processing).Config :=
3394 In_Tree.Languages_Data.Table (Lang).Config;
3396 if In_Tree.Languages_Data.Table (Lang).Config.Kind =
3399 Data.Unit_Based_Language_Name :=
3400 In_Tree.Default_Language;
3401 Data.Unit_Based_Language_Index :=
3402 Data.First_Language_Processing;
3408 Lang := In_Tree.Languages_Data.Table (Lang).Next;
3414 Current : String_List_Id := Languages.Values;
3415 Element : String_Element;
3416 Lang_Name : Name_Id;
3417 Display_Lang_Name : Name_Id;
3418 Index : Language_Index;
3419 Lang_Data : Language_Data;
3420 NL_Id : Name_List_Index := No_Name_List;
3421 Config : Language_Config;
3424 if Get_Mode = Ada_Only then
3425 -- Assume that there is no language specified yet
3427 Data.Other_Sources_Present := False;
3428 Data.Ada_Sources_Present := False;
3431 -- If there are no languages declared, there are no sources
3433 if Current = Nil_String then
3434 Data.Source_Dirs := Nil_String;
3437 -- Look through all the languages specified in attribute
3440 while Current /= Nil_String loop
3442 In_Tree.String_Elements.Table (Current);
3443 Display_Lang_Name := Element.Value;
3444 Get_Name_String (Element.Value);
3445 To_Lower (Name_Buffer (1 .. Name_Len));
3446 Lang_Name := Name_Find;
3448 Name_List_Table.Increment_Last (In_Tree.Name_Lists);
3450 if NL_Id = No_Name_List then
3452 Name_List_Table.Last (In_Tree.Name_Lists);
3455 In_Tree.Name_Lists.Table (NL_Id).Next :=
3456 Name_List_Table.Last (In_Tree.Name_Lists);
3459 NL_Id := Name_List_Table.Last (In_Tree.Name_Lists);
3460 In_Tree.Name_Lists.Table (NL_Id) :=
3461 (Lang_Name, No_Name_List);
3463 if Get_Mode = Ada_Only then
3464 Index := Language_Indexes.Get (Lang_Name);
3466 if Index = No_Language_Index then
3467 Add_Language_Name (Lang_Name);
3468 Index := Last_Language_Index;
3471 Set (Index, True, Data, In_Tree);
3472 Set (Language_Processing =>
3473 Default_Language_Processing_Data,
3474 For_Language => Index,
3476 In_Tree => In_Tree);
3478 if Index = Ada_Language_Index then
3479 Data.Ada_Sources_Present := True;
3482 Data.Other_Sources_Present := True;
3486 Index := Data.First_Language_Processing;
3488 while Index /= No_Language_Index loop
3491 In_Tree.Languages_Data.Table (Index).Name;
3492 Index := In_Tree.Languages_Data.Table (Index).Next;
3495 if Index = No_Language_Index then
3496 Language_Data_Table.Increment_Last
3497 (In_Tree.Languages_Data);
3499 Language_Data_Table.Last (In_Tree.Languages_Data);
3500 Lang_Data.Name := Lang_Name;
3501 Lang_Data.Display_Name := Element.Value;
3502 Lang_Data.Next := Data.First_Language_Processing;
3503 In_Tree.Languages_Data.Table (Index) := Lang_Data;
3504 Data.First_Language_Processing := Index;
3506 Index := In_Tree.First_Language;
3508 while Index /= No_Language_Index loop
3511 In_Tree.Languages_Data.Table (Index).Name;
3513 In_Tree.Languages_Data.Table (Index).Next;
3516 if Index = No_Language_Index then
3520 Get_Name_String (Display_Lang_Name) &
3521 """ not found in configuration",
3522 Languages.Location);
3526 In_Tree.Languages_Data.Table (Index).Config;
3528 -- Duplicate name lists
3531 (Config.Compiler_Min_Options, In_Tree);
3533 (Config.Compilation_PIC_Option, In_Tree);
3535 (Config.Mapping_File_Switches, In_Tree);
3537 (Config.Config_File_Switches, In_Tree);
3539 (Config.Dependency_Option, In_Tree);
3541 (Config.Compute_Dependency, In_Tree);
3543 (Config.Include_Option, In_Tree);
3545 (Config.Binder_Min_Options, In_Tree);
3547 In_Tree.Languages_Data.Table
3548 (Data.First_Language_Processing).Config :=
3551 if Config.Kind = Unit_Based then
3553 Data.Unit_Based_Language_Name = No_Name
3555 Data.Unit_Based_Language_Name := Lang_Name;
3556 Data.Unit_Based_Language_Index :=
3557 Language_Data_Table.Last
3558 (In_Tree.Languages_Data);
3563 "not allowed to have several " &
3564 "unit-based languages in the same " &
3566 Languages.Location);
3573 Current := Element.Next;
3579 end Check_Programming_Languages;
3585 function Check_Project
3587 Root_Project : Project_Id;
3588 In_Tree : Project_Tree_Ref;
3589 Extending : Boolean) return Boolean
3592 if P = Root_Project then
3595 elsif Extending then
3597 Data : Project_Data := In_Tree.Projects.Table (Root_Project);
3600 while Data.Extends /= No_Project loop
3601 if P = Data.Extends then
3605 Data := In_Tree.Projects.Table (Data.Extends);
3613 -------------------------------
3614 -- Check_Stand_Alone_Library --
3615 -------------------------------
3617 procedure Check_Stand_Alone_Library
3618 (Project : Project_Id;
3619 In_Tree : Project_Tree_Ref;
3620 Data : in out Project_Data;
3621 Extending : Boolean)
3623 Lib_Interfaces : constant Prj.Variable_Value :=
3625 (Snames.Name_Library_Interface,
3626 Data.Decl.Attributes,
3629 Lib_Auto_Init : constant Prj.Variable_Value :=
3631 (Snames.Name_Library_Auto_Init,
3632 Data.Decl.Attributes,
3635 Lib_Src_Dir : constant Prj.Variable_Value :=
3637 (Snames.Name_Library_Src_Dir,
3638 Data.Decl.Attributes,
3641 Lib_Symbol_File : constant Prj.Variable_Value :=
3643 (Snames.Name_Library_Symbol_File,
3644 Data.Decl.Attributes,
3647 Lib_Symbol_Policy : constant Prj.Variable_Value :=
3649 (Snames.Name_Library_Symbol_Policy,
3650 Data.Decl.Attributes,
3653 Lib_Ref_Symbol_File : constant Prj.Variable_Value :=
3655 (Snames.Name_Library_Reference_Symbol_File,
3656 Data.Decl.Attributes,
3659 Auto_Init_Supported : Boolean;
3661 OK : Boolean := True;
3664 Next_Proj : Project_Id;
3667 if Get_Mode = Multi_Language then
3668 Auto_Init_Supported := In_Tree.Config.Auto_Init_Supported;
3671 Auto_Init_Supported :=
3672 MLib.Tgt.Standalone_Library_Auto_Init_Is_Supported;
3675 pragma Assert (Lib_Interfaces.Kind = List);
3677 -- It is a stand-alone library project file if attribute
3678 -- Library_Interface is defined.
3680 if not Lib_Interfaces.Default then
3681 SAL_Library : declare
3682 Interfaces : String_List_Id := Lib_Interfaces.Values;
3683 Interface_ALIs : String_List_Id := Nil_String;
3685 The_Unit_Id : Unit_Index;
3686 The_Unit_Data : Unit_Data;
3688 procedure Add_ALI_For (Source : File_Name_Type);
3689 -- Add an ALI file name to the list of Interface ALIs
3695 procedure Add_ALI_For (Source : File_Name_Type) is
3697 Get_Name_String (Source);
3700 ALI : constant String :=
3701 ALI_File_Name (Name_Buffer (1 .. Name_Len));
3702 ALI_Name_Id : Name_Id;
3704 Name_Len := ALI'Length;
3705 Name_Buffer (1 .. Name_Len) := ALI;
3706 ALI_Name_Id := Name_Find;
3708 String_Element_Table.Increment_Last
3709 (In_Tree.String_Elements);
3710 In_Tree.String_Elements.Table
3711 (String_Element_Table.Last
3712 (In_Tree.String_Elements)) :=
3713 (Value => ALI_Name_Id,
3715 Display_Value => ALI_Name_Id,
3717 In_Tree.String_Elements.Table
3718 (Interfaces).Location,
3720 Next => Interface_ALIs);
3721 Interface_ALIs := String_Element_Table.Last
3722 (In_Tree.String_Elements);
3726 -- Start of processing for SAL_Library
3729 Data.Standalone_Library := True;
3731 -- Library_Interface cannot be an empty list
3733 if Interfaces = Nil_String then
3736 "Library_Interface cannot be an empty list",
3737 Lib_Interfaces.Location);
3740 -- Process each unit name specified in the attribute
3741 -- Library_Interface.
3743 while Interfaces /= Nil_String loop
3745 (In_Tree.String_Elements.Table (Interfaces).Value);
3746 To_Lower (Name_Buffer (1 .. Name_Len));
3748 if Name_Len = 0 then
3751 "an interface cannot be an empty string",
3752 In_Tree.String_Elements.Table (Interfaces).Location);
3756 Error_Msg_Name_1 := Unit;
3758 if Get_Mode = Ada_Only then
3760 Units_Htable.Get (In_Tree.Units_HT, Unit);
3762 if The_Unit_Id = No_Unit_Index then
3766 In_Tree.String_Elements.Table
3767 (Interfaces).Location);
3770 -- Check that the unit is part of the project
3773 In_Tree.Units.Table (The_Unit_Id);
3775 if The_Unit_Data.File_Names (Body_Part).Name /= No_File
3776 and then The_Unit_Data.File_Names (Body_Part).Path /=
3780 (The_Unit_Data.File_Names (Body_Part).Project,
3781 Project, In_Tree, Extending)
3783 -- There is a body for this unit.
3784 -- If there is no spec, we need to check
3785 -- that it is not a subunit.
3787 if The_Unit_Data.File_Names
3788 (Specification).Name = No_File
3791 Src_Ind : Source_File_Index;
3794 Src_Ind := Sinput.P.Load_Project_File
3796 (The_Unit_Data.File_Names
3799 if Sinput.P.Source_File_Is_Subunit
3804 "%% is a subunit; " &
3805 "it cannot be an interface",
3807 String_Elements.Table
3808 (Interfaces).Location);
3813 -- The unit is not a subunit, so we add
3814 -- to the Interface ALIs the ALI file
3815 -- corresponding to the body.
3818 (The_Unit_Data.File_Names (Body_Part).Name);
3823 "%% is not an unit of this project",
3824 In_Tree.String_Elements.Table
3825 (Interfaces).Location);
3828 elsif The_Unit_Data.File_Names
3829 (Specification).Name /= No_File
3830 and then The_Unit_Data.File_Names
3831 (Specification).Path /= Slash
3832 and then Check_Project
3833 (The_Unit_Data.File_Names
3834 (Specification).Project,
3835 Project, In_Tree, Extending)
3838 -- The unit is part of the project, it has
3839 -- a spec, but no body. We add to the Interface
3840 -- ALIs the ALI file corresponding to the spec.
3843 (The_Unit_Data.File_Names (Specification).Name);
3848 "%% is not an unit of this project",
3849 In_Tree.String_Elements.Table
3850 (Interfaces).Location);
3855 -- Multi_Language mode
3857 Next_Proj := Data.Extends;
3858 Source := Data.First_Source;
3861 while Source /= No_Source and then
3862 In_Tree.Sources.Table (Source).Unit /= Unit
3865 In_Tree.Sources.Table (Source).Next_In_Project;
3868 exit when Source /= No_Source or else
3869 Next_Proj = No_Project;
3872 In_Tree.Projects.Table (Next_Proj).First_Source;
3874 In_Tree.Projects.Table (Next_Proj).Extends;
3877 if Source /= No_Source then
3878 if In_Tree.Sources.Table (Source).Kind = Sep then
3879 Source := No_Source;
3881 elsif In_Tree.Sources.Table (Source).Kind = Spec
3883 In_Tree.Sources.Table (Source).Other_Part /=
3886 Source := In_Tree.Sources.Table (Source).Other_Part;
3890 if Source /= No_Source then
3891 if In_Tree.Sources.Table (Source).Project /= Project
3895 In_Tree.Sources.Table (Source).Project,
3898 Source := No_Source;
3902 if Source = No_Source then
3905 "%% is not an unit of this project",
3906 In_Tree.String_Elements.Table
3907 (Interfaces).Location);
3910 if In_Tree.Sources.Table (Source).Kind = Spec and then
3911 In_Tree.Sources.Table (Source).Other_Part /=
3915 In_Tree.Sources.Table (Source).Other_Part;
3918 String_Element_Table.Increment_Last
3919 (In_Tree.String_Elements);
3920 In_Tree.String_Elements.Table
3921 (String_Element_Table.Last
3922 (In_Tree.String_Elements)) :=
3924 Name_Id (In_Tree.Sources.Table (Source).Dep_Name),
3927 Name_Id (In_Tree.Sources.Table (Source).Dep_Name),
3929 In_Tree.String_Elements.Table
3930 (Interfaces).Location,
3932 Next => Interface_ALIs);
3933 Interface_ALIs := String_Element_Table.Last
3934 (In_Tree.String_Elements);
3942 In_Tree.String_Elements.Table (Interfaces).Next;
3945 -- Put the list of Interface ALIs in the project data
3947 Data.Lib_Interface_ALIs := Interface_ALIs;
3949 -- Check value of attribute Library_Auto_Init and set
3950 -- Lib_Auto_Init accordingly.
3952 if Lib_Auto_Init.Default then
3954 -- If no attribute Library_Auto_Init is declared, then
3955 -- set auto init only if it is supported.
3957 Data.Lib_Auto_Init := Auto_Init_Supported;
3960 Get_Name_String (Lib_Auto_Init.Value);
3961 To_Lower (Name_Buffer (1 .. Name_Len));
3963 if Name_Buffer (1 .. Name_Len) = "false" then
3964 Data.Lib_Auto_Init := False;
3966 elsif Name_Buffer (1 .. Name_Len) = "true" then
3967 if Auto_Init_Supported then
3968 Data.Lib_Auto_Init := True;
3971 -- Library_Auto_Init cannot be "true" if auto init
3976 "library auto init not supported " &
3978 Lib_Auto_Init.Location);
3984 "invalid value for attribute Library_Auto_Init",
3985 Lib_Auto_Init.Location);
3990 -- If attribute Library_Src_Dir is defined and not the
3991 -- empty string, check if the directory exist and is not
3992 -- the object directory or one of the source directories.
3993 -- This is the directory where copies of the interface
3994 -- sources will be copied. Note that this directory may be
3995 -- the library directory.
3997 if Lib_Src_Dir.Value /= Empty_String then
3999 Dir_Id : constant File_Name_Type :=
4000 File_Name_Type (Lib_Src_Dir.Value);
4007 Data.Display_Directory,
4008 Data.Library_Src_Dir,
4009 Data.Display_Library_Src_Dir,
4010 Create => "library source copy",
4011 Location => Lib_Src_Dir.Location);
4013 -- If directory does not exist, report an error
4015 if Data.Library_Src_Dir = No_Path then
4017 -- Get the absolute name of the library directory
4018 -- that does not exist, to report an error.
4021 Dir_Name : constant String :=
4022 Get_Name_String (Dir_Id);
4025 if Is_Absolute_Path (Dir_Name) then
4026 Err_Vars.Error_Msg_File_1 := Dir_Id;
4029 Get_Name_String (Data.Directory);
4031 if Name_Buffer (Name_Len) /=
4034 Name_Len := Name_Len + 1;
4035 Name_Buffer (Name_Len) :=
4036 Directory_Separator;
4041 Name_Len + Dir_Name'Length) :=
4043 Name_Len := Name_Len + Dir_Name'Length;
4044 Err_Vars.Error_Msg_Name_1 := Name_Find;
4051 "Directory { does not exist",
4052 Lib_Src_Dir.Location);
4055 -- Report an error if it is the same as the object
4058 elsif Data.Library_Src_Dir = Data.Object_Directory then
4061 "directory to copy interfaces cannot be " &
4062 "the object directory",
4063 Lib_Src_Dir.Location);
4064 Data.Library_Src_Dir := No_Path;
4068 Src_Dirs : String_List_Id;
4069 Src_Dir : String_Element;
4072 -- Interface copy directory cannot be one of the source
4073 -- directory of the current project.
4075 Src_Dirs := Data.Source_Dirs;
4076 while Src_Dirs /= Nil_String loop
4077 Src_Dir := In_Tree.String_Elements.Table
4080 -- Report error if it is one of the source directories
4082 if Data.Library_Src_Dir =
4083 Path_Name_Type (Src_Dir.Value)
4087 "directory to copy interfaces cannot " &
4088 "be one of the source directories",
4089 Lib_Src_Dir.Location);
4090 Data.Library_Src_Dir := No_Path;
4094 Src_Dirs := Src_Dir.Next;
4097 if Data.Library_Src_Dir /= No_Path then
4099 -- It cannot be a source directory of any other
4102 Project_Loop : for Pid in 1 ..
4103 Project_Table.Last (In_Tree.Projects)
4106 In_Tree.Projects.Table (Pid).Source_Dirs;
4107 Dir_Loop : while Src_Dirs /= Nil_String loop
4109 In_Tree.String_Elements.Table (Src_Dirs);
4111 -- Report error if it is one of the source
4114 if Data.Library_Src_Dir =
4115 Path_Name_Type (Src_Dir.Value)
4118 File_Name_Type (Src_Dir.Value);
4120 In_Tree.Projects.Table (Pid).Name;
4123 "directory to copy interfaces cannot " &
4124 "be the same as source directory { of " &
4126 Lib_Src_Dir.Location);
4127 Data.Library_Src_Dir := No_Path;
4131 Src_Dirs := Src_Dir.Next;
4133 end loop Project_Loop;
4137 -- In high verbosity, if there is a valid Library_Src_Dir,
4138 -- display its path name.
4140 if Data.Library_Src_Dir /= No_Path
4141 and then Current_Verbosity = High
4143 Write_Str ("Directory to copy interfaces =""");
4144 Write_Str (Get_Name_String (Data.Library_Src_Dir));
4151 -- Check the symbol related attributes
4153 -- First, the symbol policy
4155 if not Lib_Symbol_Policy.Default then
4157 Value : constant String :=
4159 (Get_Name_String (Lib_Symbol_Policy.Value));
4162 -- Symbol policy must hove one of a limited number of values
4164 if Value = "autonomous" or else Value = "default" then
4165 Data.Symbol_Data.Symbol_Policy := Autonomous;
4167 elsif Value = "compliant" then
4168 Data.Symbol_Data.Symbol_Policy := Compliant;
4170 elsif Value = "controlled" then
4171 Data.Symbol_Data.Symbol_Policy := Controlled;
4173 elsif Value = "restricted" then
4174 Data.Symbol_Data.Symbol_Policy := Restricted;
4176 elsif Value = "direct" then
4177 Data.Symbol_Data.Symbol_Policy := Direct;
4182 "illegal value for Library_Symbol_Policy",
4183 Lib_Symbol_Policy.Location);
4188 -- If attribute Library_Symbol_File is not specified, symbol policy
4189 -- cannot be Restricted.
4191 if Lib_Symbol_File.Default then
4192 if Data.Symbol_Data.Symbol_Policy = Restricted then
4195 "Library_Symbol_File needs to be defined when " &
4196 "symbol policy is Restricted",
4197 Lib_Symbol_Policy.Location);
4201 -- Library_Symbol_File is defined.
4203 Data.Symbol_Data.Symbol_File :=
4204 Path_Name_Type (Lib_Symbol_File.Value);
4206 Get_Name_String (Lib_Symbol_File.Value);
4208 if Name_Len = 0 then
4211 "symbol file name cannot be an empty string",
4212 Lib_Symbol_File.Location);
4215 OK := not Is_Absolute_Path (Name_Buffer (1 .. Name_Len));
4218 for J in 1 .. Name_Len loop
4219 if Name_Buffer (J) = '/'
4220 or else Name_Buffer (J) = Directory_Separator
4229 Error_Msg_File_1 := File_Name_Type (Lib_Symbol_File.Value);
4232 "symbol file name { is illegal. " &
4233 "Name canot include directory info.",
4234 Lib_Symbol_File.Location);
4239 -- If attribute Library_Reference_Symbol_File is not defined,
4240 -- symbol policy cannot be Compilant or Controlled.
4242 if Lib_Ref_Symbol_File.Default then
4243 if Data.Symbol_Data.Symbol_Policy = Compliant
4244 or else Data.Symbol_Data.Symbol_Policy = Controlled
4248 "a reference symbol file need to be defined",
4249 Lib_Symbol_Policy.Location);
4253 -- Library_Reference_Symbol_File is defined, check file exists
4255 Data.Symbol_Data.Reference :=
4256 Path_Name_Type (Lib_Ref_Symbol_File.Value);
4258 Get_Name_String (Lib_Ref_Symbol_File.Value);
4260 if Name_Len = 0 then
4263 "reference symbol file name cannot be an empty string",
4264 Lib_Symbol_File.Location);
4267 if not Is_Absolute_Path (Name_Buffer (1 .. Name_Len)) then
4269 Add_Str_To_Name_Buffer (Get_Name_String (Data.Directory));
4270 Add_Char_To_Name_Buffer (Directory_Separator);
4271 Add_Str_To_Name_Buffer
4272 (Get_Name_String (Lib_Ref_Symbol_File.Value));
4273 Data.Symbol_Data.Reference := Name_Find;
4276 if not Is_Regular_File
4277 (Get_Name_String (Data.Symbol_Data.Reference))
4280 File_Name_Type (Lib_Ref_Symbol_File.Value);
4282 -- For controlled and direct symbol policies, it is an error
4283 -- if the reference symbol file does not exist. For other
4284 -- symbol policies, this is just a warning
4287 Data.Symbol_Data.Symbol_Policy /= Controlled
4288 and then Data.Symbol_Data.Symbol_Policy /= Direct;
4292 "<library reference symbol file { does not exist",
4293 Lib_Ref_Symbol_File.Location);
4295 -- In addition in the non-controlled case, if symbol policy
4296 -- is Compliant, it is changed to Autonomous, because there
4297 -- is no reference to check against, and we don't want to
4298 -- fail in this case.
4300 if Data.Symbol_Data.Symbol_Policy /= Controlled then
4301 if Data.Symbol_Data.Symbol_Policy = Compliant then
4302 Data.Symbol_Data.Symbol_Policy := Autonomous;
4307 -- If both the reference symbol file and the symbol file are
4308 -- defined, then check that they are not the same file.
4310 if Data.Symbol_Data.Symbol_File /= No_Path then
4311 Get_Name_String (Data.Symbol_Data.Symbol_File);
4313 if Name_Len > 0 then
4315 Symb_Path : constant String :=
4318 (Data.Object_Directory) &
4319 Directory_Separator &
4320 Name_Buffer (1 .. Name_Len));
4321 Ref_Path : constant String :=
4324 (Data.Symbol_Data.Reference));
4326 if Symb_Path = Ref_Path then
4329 "library reference symbol file and library" &
4330 " symbol file cannot be the same file",
4331 Lib_Ref_Symbol_File.Location);
4339 end Check_Stand_Alone_Library;
4341 ----------------------------
4342 -- Compute_Directory_Last --
4343 ----------------------------
4345 function Compute_Directory_Last (Dir : String) return Natural is
4348 and then (Dir (Dir'Last - 1) = Directory_Separator
4349 or else Dir (Dir'Last - 1) = '/')
4351 return Dir'Last - 1;
4355 end Compute_Directory_Last;
4362 (Project : Project_Id;
4363 In_Tree : Project_Tree_Ref;
4365 Flag_Location : Source_Ptr)
4367 Real_Location : Source_Ptr := Flag_Location;
4368 Error_Buffer : String (1 .. 5_000);
4369 Error_Last : Natural := 0;
4370 Name_Number : Natural := 0;
4371 File_Number : Natural := 0;
4372 First : Positive := Msg'First;
4375 procedure Add (C : Character);
4376 -- Add a character to the buffer
4378 procedure Add (S : String);
4379 -- Add a string to the buffer
4382 -- Add a name to the buffer
4385 -- Add a file name to the buffer
4391 procedure Add (C : Character) is
4393 Error_Last := Error_Last + 1;
4394 Error_Buffer (Error_Last) := C;
4397 procedure Add (S : String) is
4399 Error_Buffer (Error_Last + 1 .. Error_Last + S'Length) := S;
4400 Error_Last := Error_Last + S'Length;
4407 procedure Add_File is
4408 File : File_Name_Type;
4411 File_Number := File_Number + 1;
4415 File := Err_Vars.Error_Msg_File_1;
4417 File := Err_Vars.Error_Msg_File_2;
4419 File := Err_Vars.Error_Msg_File_3;
4424 Get_Name_String (File);
4425 Add (Name_Buffer (1 .. Name_Len));
4433 procedure Add_Name is
4437 Name_Number := Name_Number + 1;
4441 Name := Err_Vars.Error_Msg_Name_1;
4443 Name := Err_Vars.Error_Msg_Name_2;
4445 Name := Err_Vars.Error_Msg_Name_3;
4450 Get_Name_String (Name);
4451 Add (Name_Buffer (1 .. Name_Len));
4455 -- Start of processing for Error_Msg
4458 -- If location of error is unknown, use the location of the project
4460 if Real_Location = No_Location then
4461 Real_Location := In_Tree.Projects.Table (Project).Location;
4464 if Error_Report = null then
4465 Prj.Err.Error_Msg (Msg, Real_Location);
4469 -- Ignore continuation character
4471 if Msg (First) = '\' then
4474 -- Warning character is always the first one in this package
4475 -- this is an undocumented kludge!!!
4477 elsif Msg (First) = '?' then
4481 elsif Msg (First) = '<' then
4484 if Err_Vars.Error_Msg_Warn then
4490 while Index <= Msg'Last loop
4491 if Msg (Index) = '{' then
4494 elsif Msg (Index) = '%' then
4495 if Index < Msg'Last and then Msg (Index + 1) = '%' then
4507 Error_Report (Error_Buffer (1 .. Error_Last), Project, In_Tree);
4510 ----------------------
4511 -- Find_Ada_Sources --
4512 ----------------------
4514 procedure Find_Ada_Sources
4515 (Project : Project_Id;
4516 In_Tree : Project_Tree_Ref;
4517 Data : in out Project_Data;
4518 Follow_Links : Boolean := False)
4520 Source_Dir : String_List_Id := Data.Source_Dirs;
4521 Element : String_Element;
4523 Current_Source : String_List_Id := Nil_String;
4524 Source_Recorded : Boolean := False;
4527 if Current_Verbosity = High then
4528 Write_Line ("Looking for sources:");
4531 -- For each subdirectory
4533 while Source_Dir /= Nil_String loop
4535 Source_Recorded := False;
4536 Element := In_Tree.String_Elements.Table (Source_Dir);
4537 if Element.Value /= No_Name then
4538 Get_Name_String (Element.Display_Value);
4541 Source_Directory : constant String :=
4542 Name_Buffer (1 .. Name_Len) & Directory_Separator;
4543 Dir_Last : constant Natural :=
4544 Compute_Directory_Last (Source_Directory);
4547 if Current_Verbosity = High then
4548 Write_Str ("Source_Dir = ");
4549 Write_Line (Source_Directory);
4552 -- We look to every entry in the source directory
4554 Open (Dir, Source_Directory
4555 (Source_Directory'First .. Dir_Last));
4558 Read (Dir, Name_Buffer, Name_Len);
4560 if Current_Verbosity = High then
4561 Write_Str (" Checking ");
4562 Write_Line (Name_Buffer (1 .. Name_Len));
4565 exit when Name_Len = 0;
4568 File_Name : constant File_Name_Type := Name_Find;
4569 Path : constant String :=
4571 (Name => Name_Buffer (1 .. Name_Len),
4572 Directory => Source_Directory
4573 (Source_Directory'First .. Dir_Last),
4574 Resolve_Links => Follow_Links,
4575 Case_Sensitive => True);
4576 Path_Name : Path_Name_Type;
4579 Name_Len := Path'Length;
4580 Name_Buffer (1 .. Name_Len) := Path;
4581 Path_Name := Name_Find;
4583 -- We attempt to register it as a source. However,
4584 -- there is no error if the file does not contain
4585 -- a valid source. But there is an error if we have
4586 -- a duplicate unit name.
4589 (File_Name => File_Name,
4590 Path_Name => Path_Name,
4594 Location => No_Location,
4595 Current_Source => Current_Source,
4596 Source_Recorded => Source_Recorded,
4597 Follow_Links => Follow_Links);
4606 when Directory_Error =>
4610 if Source_Recorded then
4611 In_Tree.String_Elements.Table (Source_Dir).Flag :=
4615 Source_Dir := Element.Next;
4618 if Current_Verbosity = High then
4619 Write_Line ("end Looking for sources.");
4622 -- If we have looked for sources and found none, then
4623 -- it is an error, except if it is an extending project.
4624 -- If a non extending project is not supposed to contain
4625 -- any source, then we never call Find_Ada_Sources.
4627 if Current_Source = Nil_String and then
4628 Data.Extends = No_Project
4630 Report_No_Sources (Project, "Ada", In_Tree, Data.Location);
4632 end Find_Ada_Sources;
4638 procedure Find_Sources
4639 (Project : Project_Id;
4640 In_Tree : Project_Tree_Ref;
4641 Data : in out Project_Data;
4642 For_Language : Language_Index;
4643 Follow_Links : Boolean := False)
4645 Source_Dir : String_List_Id := Data.Source_Dirs;
4646 Element : String_Element;
4648 Current_Source : String_List_Id := Nil_String;
4649 Source_Recorded : Boolean := False;
4652 if Current_Verbosity = High then
4653 Write_Line ("Looking for sources:");
4656 -- For each subdirectory
4658 while Source_Dir /= Nil_String loop
4660 Source_Recorded := False;
4661 Element := In_Tree.String_Elements.Table (Source_Dir);
4663 if Element.Value /= No_Name then
4664 Get_Name_String (Element.Display_Value);
4667 Source_Directory : constant String :=
4668 Name_Buffer (1 .. Name_Len) &
4669 Directory_Separator;
4671 Dir_Last : constant Natural :=
4672 Compute_Directory_Last (Source_Directory);
4675 if Current_Verbosity = High then
4676 Write_Str ("Source_Dir = ");
4677 Write_Line (Source_Directory);
4680 -- We look to every entry in the source directory
4682 Open (Dir, Source_Directory
4683 (Source_Directory'First .. Dir_Last));
4686 Read (Dir, Name_Buffer, Name_Len);
4688 if Current_Verbosity = High then
4689 Write_Str (" Checking ");
4690 Write_Line (Name_Buffer (1 .. Name_Len));
4693 exit when Name_Len = 0;
4696 File_Name : constant File_Name_Type := Name_Find;
4697 Path : constant String :=
4699 (Name => Name_Buffer (1 .. Name_Len),
4700 Directory => Source_Directory
4701 (Source_Directory'First .. Dir_Last),
4702 Resolve_Links => Follow_Links,
4703 Case_Sensitive => True);
4704 Path_Name : Path_Name_Type;
4707 Name_Len := Path'Length;
4708 Name_Buffer (1 .. Name_Len) := Path;
4709 Path_Name := Name_Find;
4711 if For_Language = Ada_Language_Index then
4713 -- We attempt to register it as a source. However,
4714 -- there is no error if the file does not contain
4715 -- a valid source. But there is an error if we have
4716 -- a duplicate unit name.
4719 (File_Name => File_Name,
4720 Path_Name => Path_Name,
4724 Location => No_Location,
4725 Current_Source => Current_Source,
4726 Source_Recorded => Source_Recorded,
4727 Follow_Links => Follow_Links);
4731 (File_Name => File_Name,
4732 Path_Name => Path_Name,
4736 Location => No_Location,
4737 Language => For_Language,
4739 Body_Suffix_Of (For_Language, Data, In_Tree),
4740 Naming_Exception => False);
4750 when Directory_Error =>
4754 if Source_Recorded then
4755 In_Tree.String_Elements.Table (Source_Dir).Flag :=
4759 Source_Dir := Element.Next;
4762 if Current_Verbosity = High then
4763 Write_Line ("end Looking for sources.");
4766 if For_Language = Ada_Language_Index then
4768 -- If we have looked for sources and found none, then
4769 -- it is an error, except if it is an extending project.
4770 -- If a non extending project is not supposed to contain
4771 -- any source, then we never call Find_Sources.
4773 if Current_Source /= Nil_String then
4774 Data.Ada_Sources_Present := True;
4776 elsif Data.Extends = No_Project then
4777 Report_No_Sources (Project, "Ada", In_Tree, Data.Location);
4782 --------------------------------
4783 -- Free_Ada_Naming_Exceptions --
4784 --------------------------------
4786 procedure Free_Ada_Naming_Exceptions is
4788 Ada_Naming_Exception_Table.Set_Last (0);
4789 Ada_Naming_Exceptions.Reset;
4790 Reverse_Ada_Naming_Exceptions.Reset;
4791 end Free_Ada_Naming_Exceptions;
4793 ---------------------
4794 -- Get_Directories --
4795 ---------------------
4797 procedure Get_Directories
4798 (Project : Project_Id;
4799 In_Tree : Project_Tree_Ref;
4800 Data : in out Project_Data)
4802 Object_Dir : constant Variable_Value :=
4804 (Name_Object_Dir, Data.Decl.Attributes, In_Tree);
4806 Exec_Dir : constant Variable_Value :=
4808 (Name_Exec_Dir, Data.Decl.Attributes, In_Tree);
4810 Source_Dirs : constant Variable_Value :=
4812 (Name_Source_Dirs, Data.Decl.Attributes, In_Tree);
4814 Excluded_Source_Dirs : constant Variable_Value :=
4816 (Name_Excluded_Source_Dirs,
4817 Data.Decl.Attributes,
4820 Source_Files : constant Variable_Value :=
4822 (Name_Source_Files, Data.Decl.Attributes, In_Tree);
4824 Last_Source_Dir : String_List_Id := Nil_String;
4826 procedure Find_Source_Dirs
4827 (From : File_Name_Type;
4828 Location : Source_Ptr;
4829 Removed : Boolean := False);
4830 -- Find one or several source directories, and add (or remove, if
4831 -- Removed is True) them to the list of source directories of the
4834 ----------------------
4835 -- Find_Source_Dirs --
4836 ----------------------
4838 procedure Find_Source_Dirs
4839 (From : File_Name_Type;
4840 Location : Source_Ptr;
4841 Removed : Boolean := False)
4843 Directory : constant String := Get_Name_String (From);
4844 Element : String_Element;
4846 procedure Recursive_Find_Dirs (Path : Name_Id);
4847 -- Find all the subdirectories (recursively) of Path and add them
4848 -- to the list of source directories of the project.
4850 -------------------------
4851 -- Recursive_Find_Dirs --
4852 -------------------------
4854 procedure Recursive_Find_Dirs (Path : Name_Id) is
4856 Name : String (1 .. 250);
4858 List : String_List_Id := Data.Source_Dirs;
4859 Prev : String_List_Id := Nil_String;
4860 Element : String_Element;
4861 Found : Boolean := False;
4863 Non_Canonical_Path : Name_Id := No_Name;
4864 Canonical_Path : Name_Id := No_Name;
4866 The_Path : constant String :=
4867 Normalize_Pathname (Get_Name_String (Path)) &
4868 Directory_Separator;
4870 The_Path_Last : constant Natural :=
4871 Compute_Directory_Last (The_Path);
4874 Name_Len := The_Path_Last - The_Path'First + 1;
4875 Name_Buffer (1 .. Name_Len) :=
4876 The_Path (The_Path'First .. The_Path_Last);
4877 Non_Canonical_Path := Name_Find;
4878 Get_Name_String (Non_Canonical_Path);
4879 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
4880 Canonical_Path := Name_Find;
4882 -- To avoid processing the same directory several times, check
4883 -- if the directory is already in Recursive_Dirs. If it is,
4884 -- then there is nothing to do, just return. If it is not, put
4885 -- it there and continue recursive processing.
4888 if Recursive_Dirs.Get (Canonical_Path) then
4891 Recursive_Dirs.Set (Canonical_Path, True);
4895 -- Check if directory is already in list
4897 while List /= Nil_String loop
4898 Element := In_Tree.String_Elements.Table (List);
4900 if Element.Value /= No_Name then
4901 Found := Element.Value = Canonical_Path;
4906 List := Element.Next;
4909 -- If directory is not already in list, put it there
4911 if (not Removed) and (not Found) then
4912 if Current_Verbosity = High then
4914 Write_Line (The_Path (The_Path'First .. The_Path_Last));
4917 String_Element_Table.Increment_Last
4918 (In_Tree.String_Elements);
4920 (Value => Canonical_Path,
4921 Display_Value => Non_Canonical_Path,
4922 Location => No_Location,
4927 -- Case of first source directory
4929 if Last_Source_Dir = Nil_String then
4930 Data.Source_Dirs := String_Element_Table.Last
4931 (In_Tree.String_Elements);
4933 -- Here we already have source directories
4936 -- Link the previous last to the new one
4938 In_Tree.String_Elements.Table
4939 (Last_Source_Dir).Next :=
4940 String_Element_Table.Last
4941 (In_Tree.String_Elements);
4944 -- And register this source directory as the new last
4946 Last_Source_Dir := String_Element_Table.Last
4947 (In_Tree.String_Elements);
4948 In_Tree.String_Elements.Table (Last_Source_Dir) :=
4951 elsif Removed and Found then
4952 if Prev = Nil_String then
4954 In_Tree.String_Elements.Table (List).Next;
4956 In_Tree.String_Elements.Table (Prev).Next :=
4957 In_Tree.String_Elements.Table (List).Next;
4961 -- Now look for subdirectories. We do that even when this
4962 -- directory is already in the list, because some of its
4963 -- subdirectories may not be in the list yet.
4965 Open (Dir, The_Path (The_Path'First .. The_Path_Last));
4968 Read (Dir, Name, Last);
4971 if Name (1 .. Last) /= "."
4972 and then Name (1 .. Last) /= ".."
4974 -- Avoid . and .. directories
4976 if Current_Verbosity = High then
4977 Write_Str (" Checking ");
4978 Write_Line (Name (1 .. Last));
4982 Path_Name : constant String :=
4984 (Name => Name (1 .. Last),
4987 (The_Path'First .. The_Path_Last),
4988 Resolve_Links => False,
4989 Case_Sensitive => True);
4992 if Is_Directory (Path_Name) then
4994 -- We have found a new subdirectory, call self
4996 Name_Len := Path_Name'Length;
4997 Name_Buffer (1 .. Name_Len) := Path_Name;
4998 Recursive_Find_Dirs (Name_Find);
5007 when Directory_Error =>
5009 end Recursive_Find_Dirs;
5011 -- Start of processing for Find_Source_Dirs
5014 if Current_Verbosity = High and then not Removed then
5015 Write_Str ("Find_Source_Dirs (""");
5016 Write_Str (Directory);
5020 -- First, check if we are looking for a directory tree, indicated
5021 -- by "/**" at the end.
5023 if Directory'Length >= 3
5024 and then Directory (Directory'Last - 1 .. Directory'Last) = "**"
5025 and then (Directory (Directory'Last - 2) = '/'
5027 Directory (Directory'Last - 2) = Directory_Separator)
5030 Data.Known_Order_Of_Source_Dirs := False;
5033 Name_Len := Directory'Length - 3;
5035 if Name_Len = 0 then
5037 -- Case of "/**": all directories in file system
5040 Name_Buffer (1) := Directory (Directory'First);
5043 Name_Buffer (1 .. Name_Len) :=
5044 Directory (Directory'First .. Directory'Last - 3);
5047 if Current_Verbosity = High then
5048 Write_Str ("Looking for all subdirectories of """);
5049 Write_Str (Name_Buffer (1 .. Name_Len));
5054 Base_Dir : constant File_Name_Type := Name_Find;
5055 Root_Dir : constant String :=
5057 (Name => Get_Name_String (Base_Dir),
5059 Get_Name_String (Data.Display_Directory),
5060 Resolve_Links => False,
5061 Case_Sensitive => True);
5064 if Root_Dir'Length = 0 then
5065 Err_Vars.Error_Msg_File_1 := Base_Dir;
5067 if Location = No_Location then
5070 "{ is not a valid directory.",
5075 "{ is not a valid directory.",
5080 -- We have an existing directory, we register it and all of
5081 -- its subdirectories.
5083 if Current_Verbosity = High then
5084 Write_Line ("Looking for source directories:");
5087 Name_Len := Root_Dir'Length;
5088 Name_Buffer (1 .. Name_Len) := Root_Dir;
5089 Recursive_Find_Dirs (Name_Find);
5091 if Current_Verbosity = High then
5092 Write_Line ("End of looking for source directories.");
5097 -- We have a single directory
5101 Path_Name : Path_Name_Type;
5102 Display_Path_Name : Path_Name_Type;
5103 List : String_List_Id;
5104 Prev : String_List_Id;
5111 Data.Display_Directory,
5115 if Path_Name = No_Path then
5116 Err_Vars.Error_Msg_File_1 := From;
5118 if Location = No_Location then
5121 "{ is not a valid directory",
5126 "{ is not a valid directory",
5132 Path : constant String :=
5133 Get_Name_String (Path_Name) &
5134 Directory_Separator;
5135 Last_Path : constant Natural :=
5136 Compute_Directory_Last (Path);
5138 Display_Path : constant String :=
5140 (Display_Path_Name) &
5141 Directory_Separator;
5142 Last_Display_Path : constant Natural :=
5143 Compute_Directory_Last
5145 Display_Path_Id : Name_Id;
5149 Add_Str_To_Name_Buffer (Path (Path'First .. Last_Path));
5150 Path_Id := Name_Find;
5152 Add_Str_To_Name_Buffer
5154 (Display_Path'First .. Last_Display_Path));
5155 Display_Path_Id := Name_Find;
5159 -- As it is an existing directory, we add it to the
5160 -- list of directories.
5162 String_Element_Table.Increment_Last
5163 (In_Tree.String_Elements);
5167 Display_Value => Display_Path_Id,
5168 Location => No_Location,
5170 Next => Nil_String);
5172 if Last_Source_Dir = Nil_String then
5174 -- This is the first source directory
5176 Data.Source_Dirs := String_Element_Table.Last
5177 (In_Tree.String_Elements);
5180 -- We already have source directories, link the
5181 -- previous last to the new one.
5183 In_Tree.String_Elements.Table
5184 (Last_Source_Dir).Next :=
5185 String_Element_Table.Last
5186 (In_Tree.String_Elements);
5189 -- And register this source directory as the new last
5191 Last_Source_Dir := String_Element_Table.Last
5192 (In_Tree.String_Elements);
5193 In_Tree.String_Elements.Table
5194 (Last_Source_Dir) := Element;
5197 -- Remove source dir, if present
5199 List := Data.Source_Dirs;
5202 -- Look for source dir in current list
5204 while List /= Nil_String loop
5205 Element := In_Tree.String_Elements.Table (List);
5206 exit when Element.Value = Path_Id;
5208 List := Element.Next;
5211 if List /= Nil_String then
5212 -- Source dir was found, remove it from the list
5214 if Prev = Nil_String then
5216 In_Tree.String_Elements.Table (List).Next;
5219 In_Tree.String_Elements.Table (Prev).Next :=
5220 In_Tree.String_Elements.Table (List).Next;
5228 end Find_Source_Dirs;
5230 -- Start of processing for Get_Directories
5233 if Current_Verbosity = High then
5234 Write_Line ("Starting to look for directories");
5237 -- Check the object directory
5239 pragma Assert (Object_Dir.Kind = Single,
5240 "Object_Dir is not a single string");
5242 -- We set the object directory to its default
5244 Data.Object_Directory := Data.Directory;
5245 Data.Display_Object_Dir := Data.Display_Directory;
5247 if Object_Dir.Value /= Empty_String then
5248 Get_Name_String (Object_Dir.Value);
5250 if Name_Len = 0 then
5253 "Object_Dir cannot be empty",
5254 Object_Dir.Location);
5257 -- We check that the specified object directory does exist
5262 File_Name_Type (Object_Dir.Value),
5263 Data.Display_Directory,
5264 Data.Object_Directory,
5265 Data.Display_Object_Dir,
5267 Location => Object_Dir.Location);
5269 if Data.Object_Directory = No_Path then
5271 -- The object directory does not exist, report an error if the
5272 -- project is not externally built.
5274 if not Data.Externally_Built then
5275 Err_Vars.Error_Msg_File_1 :=
5276 File_Name_Type (Object_Dir.Value);
5279 "the object directory { cannot be found",
5283 -- Do not keep a nil Object_Directory. Set it to the specified
5284 -- (relative or absolute) path. This is for the benefit of
5285 -- tools that recover from errors; for example, these tools
5286 -- could create the non existent directory.
5288 Data.Display_Object_Dir := Path_Name_Type (Object_Dir.Value);
5289 Get_Name_String (Object_Dir.Value);
5290 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
5291 Data.Object_Directory := Name_Find;
5296 if Current_Verbosity = High then
5297 if Data.Object_Directory = No_Path then
5298 Write_Line ("No object directory");
5300 Write_Str ("Object directory: """);
5301 Write_Str (Get_Name_String (Data.Display_Object_Dir));
5306 -- Check the exec directory
5308 pragma Assert (Exec_Dir.Kind = Single,
5309 "Exec_Dir is not a single string");
5311 -- We set the object directory to its default
5313 Data.Exec_Directory := Data.Object_Directory;
5314 Data.Display_Exec_Dir := Data.Display_Object_Dir;
5316 if Exec_Dir.Value /= Empty_String then
5317 Get_Name_String (Exec_Dir.Value);
5319 if Name_Len = 0 then
5322 "Exec_Dir cannot be empty",
5326 -- We check that the specified object directory does exist
5331 File_Name_Type (Exec_Dir.Value),
5332 Data.Display_Directory,
5333 Data.Exec_Directory,
5334 Data.Display_Exec_Dir,
5336 Location => Exec_Dir.Location);
5338 if Data.Exec_Directory = No_Path then
5339 Err_Vars.Error_Msg_File_1 := File_Name_Type (Exec_Dir.Value);
5342 "the exec directory { cannot be found",
5348 if Current_Verbosity = High then
5349 if Data.Exec_Directory = No_Path then
5350 Write_Line ("No exec directory");
5352 Write_Str ("Exec directory: """);
5353 Write_Str (Get_Name_String (Data.Display_Exec_Dir));
5358 -- Look for the source directories
5360 if Current_Verbosity = High then
5361 Write_Line ("Starting to look for source directories");
5364 pragma Assert (Source_Dirs.Kind = List, "Source_Dirs is not a list");
5366 if (not Source_Files.Default) and then
5367 Source_Files.Values = Nil_String
5369 Data.Source_Dirs := Nil_String;
5371 if Data.Extends = No_Project
5372 and then Data.Object_Directory = Data.Directory
5374 Data.Object_Directory := No_Path;
5377 elsif Source_Dirs.Default then
5379 -- No Source_Dirs specified: the single source directory is the one
5380 -- containing the project file
5382 String_Element_Table.Increment_Last
5383 (In_Tree.String_Elements);
5384 Data.Source_Dirs := String_Element_Table.Last
5385 (In_Tree.String_Elements);
5386 In_Tree.String_Elements.Table (Data.Source_Dirs) :=
5387 (Value => Name_Id (Data.Directory),
5388 Display_Value => Name_Id (Data.Display_Directory),
5389 Location => No_Location,
5394 if Current_Verbosity = High then
5395 Write_Line ("Single source directory:");
5397 Write_Str (Get_Name_String (Data.Display_Directory));
5401 elsif Source_Dirs.Values = Nil_String then
5403 -- If Source_Dirs is an empty string list, this means that this
5404 -- project contains no source. For projects that don't extend other
5405 -- projects, this also means that there is no need for an object
5406 -- directory, if not specified.
5408 if Data.Extends = No_Project
5409 and then Data.Object_Directory = Data.Directory
5411 Data.Object_Directory := No_Path;
5414 Data.Source_Dirs := Nil_String;
5418 Source_Dir : String_List_Id;
5419 Element : String_Element;
5422 -- Process the source directories for each element of the list
5424 Source_Dir := Source_Dirs.Values;
5425 while Source_Dir /= Nil_String loop
5427 In_Tree.String_Elements.Table (Source_Dir);
5429 (File_Name_Type (Element.Value), Element.Location);
5430 Source_Dir := Element.Next;
5435 if not Excluded_Source_Dirs.Default
5436 and then Excluded_Source_Dirs.Values /= Nil_String
5439 Source_Dir : String_List_Id;
5440 Element : String_Element;
5443 -- Process the source directories for each element of the list
5445 Source_Dir := Excluded_Source_Dirs.Values;
5446 while Source_Dir /= Nil_String loop
5448 In_Tree.String_Elements.Table (Source_Dir);
5450 (File_Name_Type (Element.Value),
5453 Source_Dir := Element.Next;
5458 if Current_Verbosity = High then
5459 Write_Line ("Putting source directories in canonical cases");
5463 Current : String_List_Id := Data.Source_Dirs;
5464 Element : String_Element;
5467 while Current /= Nil_String loop
5468 Element := In_Tree.String_Elements.Table (Current);
5469 if Element.Value /= No_Name then
5470 Get_Name_String (Element.Value);
5471 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
5472 Element.Value := Name_Find;
5473 In_Tree.String_Elements.Table (Current) := Element;
5476 Current := Element.Next;
5480 end Get_Directories;
5487 (Project : Project_Id;
5488 In_Tree : Project_Tree_Ref;
5489 Data : in out Project_Data)
5491 Mains : constant Variable_Value :=
5492 Prj.Util.Value_Of (Name_Main, Data.Decl.Attributes, In_Tree);
5495 Data.Mains := Mains.Values;
5497 -- If no Mains were specified, and if we are an extending project,
5498 -- inherit the Mains from the project we are extending.
5500 if Mains.Default then
5501 if Data.Extends /= No_Project then
5503 In_Tree.Projects.Table (Data.Extends).Mains;
5506 -- In a library project file, Main cannot be specified
5508 elsif Data.Library then
5511 "a library project file cannot have Main specified",
5516 ---------------------------
5517 -- Get_Sources_From_File --
5518 ---------------------------
5520 procedure Get_Sources_From_File
5522 Location : Source_Ptr;
5523 Project : Project_Id;
5524 In_Tree : Project_Tree_Ref)
5526 File : Prj.Util.Text_File;
5527 Line : String (1 .. 250);
5529 Source_Name : File_Name_Type;
5530 Name_Loc : Name_Location;
5533 if Get_Mode = Ada_Only then
5537 if Current_Verbosity = High then
5538 Write_Str ("Opening """);
5545 Prj.Util.Open (File, Path);
5547 if not Prj.Util.Is_Valid (File) then
5548 Error_Msg (Project, In_Tree, "file does not exist", Location);
5550 -- Read the lines one by one
5552 while not Prj.Util.End_Of_File (File) loop
5553 Prj.Util.Get_Line (File, Line, Last);
5555 -- A non empty, non comment line should contain a file name
5558 and then (Last = 1 or else Line (1 .. 2) /= "--")
5560 -- ??? we should check that there is no directory information
5563 Name_Buffer (1 .. Name_Len) := Line (1 .. Last);
5564 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
5565 Source_Name := Name_Find;
5566 Name_Loc := Source_Names.Get (Source_Name);
5568 if Name_Loc = No_Name_Location then
5570 (Name => Source_Name,
5571 Location => Location,
5572 Source => No_Source,
5577 Source_Names.Set (Source_Name, Name_Loc);
5581 Prj.Util.Close (File);
5584 end Get_Sources_From_File;
5591 (In_Tree : Project_Tree_Ref;
5592 Canonical_File_Name : File_Name_Type;
5593 Naming : Naming_Data;
5594 Exception_Id : out Ada_Naming_Exception_Id;
5595 Unit_Name : out Name_Id;
5596 Unit_Kind : out Spec_Or_Body;
5597 Needs_Pragma : out Boolean)
5599 Info_Id : Ada_Naming_Exception_Id :=
5600 Ada_Naming_Exceptions.Get (Canonical_File_Name);
5601 VMS_Name : File_Name_Type;
5604 if Info_Id = No_Ada_Naming_Exception then
5605 if Hostparm.OpenVMS then
5606 VMS_Name := Canonical_File_Name;
5607 Get_Name_String (VMS_Name);
5609 if Name_Buffer (Name_Len) = '.' then
5610 Name_Len := Name_Len - 1;
5611 VMS_Name := Name_Find;
5614 Info_Id := Ada_Naming_Exceptions.Get (VMS_Name);
5619 if Info_Id /= No_Ada_Naming_Exception then
5620 Exception_Id := Info_Id;
5621 Unit_Name := No_Name;
5622 Unit_Kind := Specification;
5623 Needs_Pragma := True;
5627 Needs_Pragma := False;
5628 Exception_Id := No_Ada_Naming_Exception;
5630 Get_Name_String (Canonical_File_Name);
5633 File : String := Name_Buffer (1 .. Name_Len);
5634 First : constant Positive := File'First;
5635 Last : Natural := File'Last;
5636 Standard_GNAT : Boolean;
5640 Spec_Suffix_Id_Of (In_Tree, "ada", Naming) = Default_Ada_Spec_Suffix
5642 Body_Suffix_Id_Of (In_Tree, "ada", Naming) = Default_Ada_Body_Suffix;
5644 -- Check if the end of the file name is Specification_Append
5646 Get_Name_String (Spec_Suffix_Id_Of (In_Tree, "ada", Naming));
5648 if File'Length > Name_Len
5649 and then File (Last - Name_Len + 1 .. Last) =
5650 Name_Buffer (1 .. Name_Len)
5654 Unit_Kind := Specification;
5655 Last := Last - Name_Len;
5657 if Current_Verbosity = High then
5658 Write_Str (" Specification: ");
5659 Write_Line (File (First .. Last));
5663 Get_Name_String (Body_Suffix_Id_Of (In_Tree, "ada", Naming));
5665 -- Check if the end of the file name is Body_Append
5667 if File'Length > Name_Len
5668 and then File (Last - Name_Len + 1 .. Last) =
5669 Name_Buffer (1 .. Name_Len)
5673 Unit_Kind := Body_Part;
5674 Last := Last - Name_Len;
5676 if Current_Verbosity = High then
5677 Write_Str (" Body: ");
5678 Write_Line (File (First .. Last));
5681 elsif Naming.Separate_Suffix /=
5682 Body_Suffix_Id_Of (In_Tree, "ada", Naming)
5684 Get_Name_String (Naming.Separate_Suffix);
5686 -- Check if the end of the file name is Separate_Append
5688 if File'Length > Name_Len
5689 and then File (Last - Name_Len + 1 .. Last) =
5690 Name_Buffer (1 .. Name_Len)
5692 -- We have a separate (a body)
5694 Unit_Kind := Body_Part;
5695 Last := Last - Name_Len;
5697 if Current_Verbosity = High then
5698 Write_Str (" Separate: ");
5699 Write_Line (File (First .. Last));
5713 -- This is not a source file
5715 Unit_Name := No_Name;
5716 Unit_Kind := Specification;
5718 if Current_Verbosity = High then
5719 Write_Line (" Not a valid file name.");
5725 Get_Name_String (Naming.Dot_Replacement);
5727 Standard_GNAT and then Name_Buffer (1 .. Name_Len) = "-";
5729 if Name_Buffer (1 .. Name_Len) /= "." then
5731 -- If Dot_Replacement is not a single dot, then there should not
5732 -- be any dot in the name.
5734 for Index in First .. Last loop
5735 if File (Index) = '.' then
5736 if Current_Verbosity = High then
5738 (" Not a valid file name (some dot not replaced).");
5741 Unit_Name := No_Name;
5747 -- Replace the substring Dot_Replacement with dots
5750 Index : Positive := First;
5753 while Index <= Last - Name_Len + 1 loop
5755 if File (Index .. Index + Name_Len - 1) =
5756 Name_Buffer (1 .. Name_Len)
5758 File (Index) := '.';
5760 if Name_Len > 1 and then Index < Last then
5761 File (Index + 1 .. Last - Name_Len + 1) :=
5762 File (Index + Name_Len .. Last);
5765 Last := Last - Name_Len + 1;
5773 -- Check if the casing is right
5776 Src : String := File (First .. Last);
5777 Src_Last : Positive := Last;
5780 case Naming.Casing is
5781 when All_Lower_Case =>
5784 Mapping => Lower_Case_Map);
5786 when All_Upper_Case =>
5789 Mapping => Upper_Case_Map);
5791 when Mixed_Case | Unknown =>
5795 if Src /= File (First .. Last) then
5796 if Current_Verbosity = High then
5797 Write_Line (" Not a valid file name (casing).");
5800 Unit_Name := No_Name;
5804 -- We put the name in lower case
5808 Mapping => Lower_Case_Map);
5810 -- In the standard GNAT naming scheme, check for special cases:
5811 -- children or separates of A, G, I or S, and run time sources.
5813 if Standard_GNAT and then Src'Length >= 3 then
5815 S1 : constant Character := Src (Src'First);
5816 S2 : constant Character := Src (Src'First + 1);
5817 S3 : constant Character := Src (Src'First + 2);
5825 -- Children or separates of packages A, G, I or S. These
5826 -- names are x__ ... or x~... (where x is a, g, i, or s).
5827 -- Both versions (x__... and x~...) are allowed in all
5828 -- platforms, because it is not possible to know the
5829 -- platform before processing of the project files.
5831 if S2 = '_' and then S3 = '_' then
5832 Src (Src'First + 1) := '.';
5833 Src_Last := Src_Last - 1;
5834 Src (Src'First + 2 .. Src_Last) :=
5835 Src (Src'First + 3 .. Src_Last + 1);
5838 Src (Src'First + 1) := '.';
5840 -- If it is potentially a run time source, disable
5841 -- filling of the mapping file to avoid warnings.
5844 Set_Mapping_File_Initial_State_To_Empty;
5850 if Current_Verbosity = High then
5852 Write_Line (Src (Src'First .. Src_Last));
5855 -- Now, we check if this name is a valid unit name
5858 (Name => Src (Src'First .. Src_Last), Unit => Unit_Name);
5868 function Hash (Unit : Unit_Info) return Header_Num is
5870 return Header_Num (Unit.Unit mod 2048);
5873 -----------------------
5874 -- Is_Illegal_Suffix --
5875 -----------------------
5877 function Is_Illegal_Suffix
5879 Dot_Replacement_Is_A_Single_Dot : Boolean) return Boolean
5882 if Suffix'Length = 0 or else Index (Suffix, ".") = 0 then
5886 -- If dot replacement is a single dot, and first character of suffix is
5889 if Dot_Replacement_Is_A_Single_Dot
5890 and then Suffix (Suffix'First) = '.'
5892 for Index in Suffix'First + 1 .. Suffix'Last loop
5894 -- If there is another dot
5896 if Suffix (Index) = '.' then
5898 -- It is illegal to have a letter following the initial dot
5900 return Is_Letter (Suffix (Suffix'First + 1));
5908 end Is_Illegal_Suffix;
5910 ----------------------
5911 -- Locate_Directory --
5912 ----------------------
5914 procedure Locate_Directory
5915 (Project : Project_Id;
5916 In_Tree : Project_Tree_Ref;
5917 Name : File_Name_Type;
5918 Parent : Path_Name_Type;
5919 Dir : out Path_Name_Type;
5920 Display : out Path_Name_Type;
5921 Create : String := "";
5922 Location : Source_Ptr := No_Location)
5924 The_Name : String := Get_Name_String (Name);
5926 The_Parent : constant String :=
5927 Get_Name_String (Parent) & Directory_Separator;
5929 The_Parent_Last : constant Natural :=
5930 Compute_Directory_Last (The_Parent);
5932 Full_Name : File_Name_Type;
5935 -- Convert '/' to directory separator (for Windows)
5937 for J in The_Name'Range loop
5938 if The_Name (J) = '/' then
5939 The_Name (J) := Directory_Separator;
5943 if Current_Verbosity = High then
5944 Write_Str ("Locate_Directory (""");
5945 Write_Str (The_Name);
5946 Write_Str (""", """);
5947 Write_Str (The_Parent);
5954 if Is_Absolute_Path (The_Name) then
5959 Add_Str_To_Name_Buffer
5960 (The_Parent (The_Parent'First .. The_Parent_Last));
5961 Add_Str_To_Name_Buffer (The_Name);
5962 Full_Name := Name_Find;
5966 Full_Path_Name : constant String := Get_Name_String (Full_Name);
5969 if Setup_Projects and then Create'Length > 0
5970 and then not Is_Directory (Full_Path_Name)
5973 Create_Path (Full_Path_Name);
5975 if not Quiet_Output then
5977 Write_Str (" directory """);
5978 Write_Str (Full_Path_Name);
5979 Write_Line (""" created");
5986 "could not create " & Create &
5987 " directory " & Full_Path_Name,
5992 if Is_Directory (Full_Path_Name) then
5994 Normed : constant String :=
5997 Resolve_Links => False,
5998 Case_Sensitive => True);
6000 Canonical_Path : constant String :=
6003 Resolve_Links => True,
6004 Case_Sensitive => False);
6007 Name_Len := Normed'Length;
6008 Name_Buffer (1 .. Name_Len) := Normed;
6009 Display := Name_Find;
6011 Name_Len := Canonical_Path'Length;
6012 Name_Buffer (1 .. Name_Len) := Canonical_Path;
6017 end Locate_Directory;
6019 ----------------------
6020 -- Look_For_Sources --
6021 ----------------------
6023 procedure Look_For_Sources
6024 (Project : Project_Id;
6025 In_Tree : Project_Tree_Ref;
6026 Data : in out Project_Data;
6027 Follow_Links : Boolean)
6029 procedure Get_Path_Names_And_Record_Sources (Follow_Links : Boolean);
6030 -- Find the path names of the source files in the Source_Names table
6031 -- in the source directories and record those that are Ada sources.
6033 procedure Get_Sources_From_File
6035 Location : Source_Ptr);
6036 -- Get the sources of a project from a text file
6038 procedure Search_Directories (For_All_Sources : Boolean);
6039 -- Search the source directories to find the sources.
6040 -- If For_All_Sources is True, check each regular file name against
6041 -- the naming schemes of the different languages. Otherwise consider
6042 -- only the file names in the hash table Source_Names.
6044 ---------------------------------------
6045 -- Get_Path_Names_And_Record_Sources --
6046 ---------------------------------------
6048 procedure Get_Path_Names_And_Record_Sources (Follow_Links : Boolean) is
6049 Source_Dir : String_List_Id := Data.Source_Dirs;
6050 Element : String_Element;
6051 Path : Path_Name_Type;
6054 Name : File_Name_Type;
6055 Canonical_Name : File_Name_Type;
6056 Name_Str : String (1 .. 1_024);
6057 Last : Natural := 0;
6059 Current_Source : String_List_Id := Nil_String;
6060 First_Error : Boolean := True;
6061 Source_Recorded : Boolean := False;
6064 -- We look in all source directories for the file names in the
6065 -- hash table Source_Names
6067 while Source_Dir /= Nil_String loop
6068 Source_Recorded := False;
6069 Element := In_Tree.String_Elements.Table (Source_Dir);
6072 Dir_Path : constant String :=
6073 Get_Name_String (Element.Display_Value);
6075 if Current_Verbosity = High then
6076 Write_Str ("checking directory """);
6077 Write_Str (Dir_Path);
6081 Open (Dir, Dir_Path);
6084 Read (Dir, Name_Str, Last);
6088 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
6091 Canonical_Case_File_Name (Name_Str (1 .. Last));
6092 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
6093 Canonical_Name := Name_Find;
6095 NL := Source_Names.Get (Canonical_Name);
6097 if NL /= No_Name_Location and then not NL.Found then
6099 Source_Names.Set (Canonical_Name, NL);
6100 Name_Len := Dir_Path'Length;
6101 Name_Buffer (1 .. Name_Len) := Dir_Path;
6103 if Name_Buffer (Name_Len) /= Directory_Separator then
6104 Add_Char_To_Name_Buffer (Directory_Separator);
6107 Add_Str_To_Name_Buffer (Name_Str (1 .. Last));
6110 if Current_Verbosity = High then
6111 Write_Str (" found ");
6112 Write_Line (Get_Name_String (Name));
6115 -- Register the source if it is an Ada compilation unit
6123 Location => NL.Location,
6124 Current_Source => Current_Source,
6125 Source_Recorded => Source_Recorded,
6126 Follow_Links => Follow_Links);
6133 if Source_Recorded then
6134 In_Tree.String_Elements.Table (Source_Dir).Flag :=
6138 Source_Dir := Element.Next;
6141 -- It is an error if a source file name in a source list or
6142 -- in a source list file is not found.
6144 NL := Source_Names.Get_First;
6145 while NL /= No_Name_Location loop
6146 if not NL.Found then
6147 Err_Vars.Error_Msg_File_1 := NL.Name;
6152 "source file { cannot be found",
6154 First_Error := False;
6159 "\source file { cannot be found",
6164 NL := Source_Names.Get_Next;
6166 end Get_Path_Names_And_Record_Sources;
6168 ---------------------------
6169 -- Get_Sources_From_File --
6170 ---------------------------
6172 procedure Get_Sources_From_File
6174 Location : Source_Ptr)
6177 -- Get the list of sources from the file and put them in hash table
6180 Get_Sources_From_File (Path, Location, Project, In_Tree);
6182 if Get_Mode = Ada_Only then
6183 -- Look in the source directories to find those sources
6185 Get_Path_Names_And_Record_Sources (Follow_Links);
6187 -- We should have found at least one source.
6188 -- If not, report an error.
6190 if Data.Ada_Sources = Nil_String then
6191 Report_No_Sources (Project, "Ada", In_Tree, Location);
6197 end Get_Sources_From_File;
6199 ------------------------
6200 -- Search_Directories --
6201 ------------------------
6203 procedure Search_Directories (For_All_Sources : Boolean) is
6204 Source_Dir : String_List_Id;
6205 Element : String_Element;
6207 Name : String (1 .. 1_000);
6210 File_Name : File_Name_Type;
6211 Display_File_Name : File_Name_Type;
6213 Source_To_Replace : Source_Id := No_Source;
6214 Src_Data : Source_Data;
6216 Name_Loc : Name_Location;
6217 Check_Name : Boolean;
6219 Language : Language_Index;
6220 Language_Name : Name_Id;
6221 Display_Language_Name : Name_Id;
6223 Kind : Source_Kind := Spec;
6224 Alternate_Languages : Alternate_Language_Id :=
6225 No_Alternate_Language;
6229 procedure Check_Naming_Schemes;
6230 -- Check if the file name File_Name conforms to one of the naming
6231 -- schemes of the project. If it does, set the global variables
6232 -- Language, Language_Name, Display_Language_Name, Unit and Kind
6233 -- appropriately. If it does not, set Language to No_Language_Index.
6235 --------------------------
6236 -- Check_Naming_Schemes --
6237 --------------------------
6239 procedure Check_Naming_Schemes is
6240 Filename : constant String := Get_Name_String (File_Name);
6241 Last : Positive := Filename'Last;
6242 Config : Language_Config;
6243 Lang : Name_List_Index;
6245 Header_File : Boolean := False;
6246 First_Language : Language_Index;
6251 Lang := Data.Languages;
6252 while Lang /= No_Name_List loop
6253 Language_Name := In_Tree.Name_Lists.Table (Lang).Name;
6255 Language := Data.First_Language_Processing;
6256 while Language /= No_Language_Index loop
6257 if In_Tree.Languages_Data.Table (Language).Name =
6260 Display_Language_Name :=
6261 In_Tree.Languages_Data.Table (Language).Display_Name;
6262 Config := In_Tree.Languages_Data.Table (Language).Config;
6264 if Config.Kind = File_Based then
6266 -- For file based languages, there is no Unit. Just
6267 -- check if the file name has the implementation or,
6268 -- if it is specified, the template suffix of the
6273 if not Header_File and then
6274 Config.Naming_Data.Body_Suffix /= No_File
6277 Impl_Suffix : constant String :=
6279 (Config.Naming_Data.Body_Suffix);
6282 if Filename'Length > Impl_Suffix'Length
6285 (Last - Impl_Suffix'Length + 1 .. Last) =
6290 if Current_Verbosity = High then
6291 Write_Str (" source of language ");
6294 (Display_Language_Name));
6302 if Config.Naming_Data.Spec_Suffix /= No_File then
6304 Spec_Suffix : constant String :=
6306 (Config.Naming_Data.Spec_Suffix);
6309 if Filename'Length > Spec_Suffix'Length
6312 (Last - Spec_Suffix'Length + 1 .. Last) =
6317 if Current_Verbosity = High then
6319 (" header file of language ");
6322 (Display_Language_Name));
6326 Alternate_Language_Table.Increment_Last
6327 (In_Tree.Alt_Langs);
6328 In_Tree.Alt_Langs.Table
6329 (Alternate_Language_Table.Last
6330 (In_Tree.Alt_Langs)) :=
6331 (Language => Language,
6332 Next => Alternate_Languages);
6333 Alternate_Languages :=
6334 Alternate_Language_Table.Last
6335 (In_Tree.Alt_Langs);
6337 Header_File := True;
6338 First_Language := Language;
6344 elsif not Header_File then
6346 -- Unit based language
6348 OK := Config.Naming_Data.Dot_Replacement /= No_File;
6354 case Config.Naming_Data.Casing is
6355 when All_Lower_Case =>
6356 for J in Filename'Range loop
6357 if Is_Letter (Filename (J)) then
6358 if not Is_Lower (Filename (J)) then
6365 when All_Upper_Case =>
6366 for J in Filename'Range loop
6367 if Is_Letter (Filename (J)) then
6368 if not Is_Upper (Filename (J)) then
6383 if Config.Naming_Data.Separate_Suffix /= No_File
6385 Config.Naming_Data.Separate_Suffix /=
6386 Config.Naming_Data.Body_Suffix
6389 Suffix : constant String :=
6391 (Config.Naming_Data.Separate_Suffix);
6393 if Filename'Length > Suffix'Length
6396 (Last - Suffix'Length + 1 .. Last) =
6400 Last := Last - Suffix'Length;
6407 Config.Naming_Data.Body_Suffix /= No_File
6410 Suffix : constant String :=
6412 (Config.Naming_Data.Body_Suffix);
6414 if Filename'Length > Suffix'Length
6417 (Last - Suffix'Length + 1 .. Last) =
6421 Last := Last - Suffix'Length;
6428 Config.Naming_Data.Spec_Suffix /= No_File
6431 Suffix : constant String :=
6433 (Config.Naming_Data.Spec_Suffix);
6435 if Filename'Length > Suffix'Length
6438 (Last - Suffix'Length + 1 .. Last) =
6442 Last := Last - Suffix'Length;
6451 -- Replace dot replacements with dots
6456 J : Positive := Filename'First;
6458 Dot_Replacement : constant String :=
6460 (Config.Naming_Data.
6463 Max : constant Positive :=
6464 Last - Dot_Replacement'Length + 1;
6468 Name_Len := Name_Len + 1;
6470 if J <= Max and then
6472 (J .. J + Dot_Replacement'Length - 1) =
6475 Name_Buffer (Name_Len) := '.';
6476 J := J + Dot_Replacement'Length;
6479 if Filename (J) = '.' then
6484 Name_Buffer (Name_Len) :=
6485 GNAT.Case_Util.To_Lower (Filename (J));
6496 -- The name buffer should contain the name of the
6497 -- the unit, if it is one.
6499 -- Check that this is a valid unit name
6501 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit);
6503 if Unit /= No_Name then
6505 if Current_Verbosity = High then
6507 Write_Str (" spec of ");
6510 Write_Str (" body of ");
6513 Write_Str (Get_Name_String (Unit));
6514 Write_Str (" (language ");
6516 (Get_Name_String (Display_Language_Name));
6526 Language := In_Tree.Languages_Data.Table (Language).Next;
6529 Lang := In_Tree.Name_Lists.Table (Lang).Next;
6533 Language := First_Language;
6536 Language := No_Language_Index;
6538 if Current_Verbosity = High then
6539 Write_Line (" not a source of any language");
6542 end Check_Naming_Schemes;
6544 -- Start of processing for Search_Directories
6547 if Current_Verbosity = High then
6548 Write_Line ("Looking for sources:");
6551 -- Loop through subdirectories
6553 Source_Dir := Data.Source_Dirs;
6554 while Source_Dir /= Nil_String loop
6556 Element := In_Tree.String_Elements.Table (Source_Dir);
6557 if Element.Value /= No_Name then
6558 Get_Name_String (Element.Display_Value);
6561 Source_Directory : constant String :=
6562 Name_Buffer (1 .. Name_Len) &
6563 Directory_Separator;
6564 Dir_Last : constant Natural :=
6565 Compute_Directory_Last
6569 if Current_Verbosity = High then
6570 Write_Str ("Source_Dir = ");
6571 Write_Line (Source_Directory);
6574 -- We look to every entry in the source directory
6576 Open (Dir, Source_Directory
6577 (Source_Directory'First .. Dir_Last));
6580 Read (Dir, Name, Last);
6585 (Source_Directory & Name (1 .. Last))
6587 if Current_Verbosity = High then
6588 Write_Str (" Checking ");
6589 Write_Line (Name (1 .. Last));
6592 Source_To_Replace := No_Source;
6595 Name_Buffer (1 .. Name_Len) := Name (1 .. Last);
6596 Display_File_Name := Name_Find;
6597 Canonical_Case_File_Name
6598 (Name_Buffer (1 .. Name_Len));
6599 File_Name := Name_Find;
6602 Display_Path : constant String :=
6608 (Source_Directory'First ..
6612 Case_Sensitive => True);
6613 Path : String := Display_Path;
6614 Path_Id : Path_Name_Type;
6615 Display_Path_Id : Path_Name_Type;
6618 Canonical_Case_File_Name (Path);
6619 Name_Len := Path'Length;
6620 Name_Buffer (1 .. Name_Len) := Path;
6621 Path_Id := Name_Find;
6623 Name_Len := Display_Path'Length;
6624 Name_Buffer (1 .. Name_Len) := Display_Path;
6625 Display_Path_Id := Name_Find;
6627 Name_Loc := Source_Names.Get (File_Name);
6628 Check_Name := False;
6630 if Name_Loc = No_Name_Location then
6631 Check_Name := For_All_Sources;
6634 if Name_Loc.Found then
6636 -- Check if it is OK to have the same file
6637 -- name in several source directories.
6640 not Data.Known_Order_Of_Source_Dirs
6642 Error_Msg_File_1 := File_Name;
6645 "{ is found in several " &
6646 "source directories",
6651 Name_Loc.Found := True;
6653 if Name_Loc.Source = No_Source then
6657 In_Tree.Sources.Table
6658 (Name_Loc.Source).Path := Path_Id;
6660 Source_Paths_Htable.Set
6661 (In_Tree.Source_Paths_HT,
6665 In_Tree.Sources.Table
6666 (Name_Loc.Source).Display_Path :=
6669 -- Check if this is a subunit
6671 if In_Tree.Sources.Table
6672 (Name_Loc.Source).Unit /= No_Name
6674 In_Tree.Sources.Table
6675 (Name_Loc.Source).Kind = Impl
6678 Src_Ind : Source_File_Index;
6682 Sinput.P.Load_Project_File
6683 (Get_Name_String (Path_Id));
6685 if Sinput.P.Source_File_Is_Subunit
6688 In_Tree.Sources.Table
6689 (Name_Loc.Source).Kind :=
6699 Alternate_Languages := No_Alternate_Language;
6700 Check_Naming_Schemes;
6702 if Language = No_Language_Index then
6703 if Name_Loc.Found then
6705 -- A file name in a list must be
6706 -- a source of a language.
6708 Error_Msg_File_1 := File_Name;
6711 "language unknown for {",
6716 -- Check if the same file name or unit
6717 -- is used in the project tree.
6719 Source := In_Tree.First_Source;
6722 while Source /= No_Source loop
6724 In_Tree.Sources.Table (Source);
6726 if (Unit /= No_Name and then
6727 Src_Data.Unit = Unit and then
6728 Src_Data.Kind = Kind)
6730 (Unit = No_Name and then
6731 Src_Data.File = File_Name)
6733 -- Duplication of file/unit in the
6734 -- same project is only allowed if
6735 -- the order of source directories
6738 if Project = Src_Data.Project then
6740 Data.Known_Order_Of_Source_Dirs
6744 elsif Unit /= No_Name then
6745 Error_Msg_Name_1 := Unit;
6748 "duplicate unit %%",
6753 Error_Msg_File_1 := File_Name;
6756 "duplicate source file " &
6762 -- Do not allow the same unit name
6763 -- in different projects, except if
6764 -- one is extending the other.
6766 -- For a file based language,
6767 -- the same file name replaces
6768 -- a file in a project being
6769 -- extended, but it is allowed
6770 -- to have the same file name in
6771 -- unrelated projects.
6778 Source_To_Replace := Source;
6780 elsif Unit /= No_Name then
6781 Error_Msg_Name_1 := Unit;
6784 "unit %% cannot belong to " &
6791 Source := Src_Data.Next_In_Sources;
6795 Source_Data_Table.Increment_Last
6797 Source := Source_Data_Table.Last
6803 Data.Project := Project;
6804 Data.Language_Name := Language_Name;
6805 Data.Language := Language;
6806 Data.Alternate_Languages :=
6807 Alternate_Languages;
6810 Data.File := File_Name;
6812 Object_Name (File_Name);
6814 In_Tree.Languages_Data.Table
6815 (Language).Config.Dependency_Kind;
6818 (File_Name, Data.Dependency);
6820 Switches_Name (File_Name);
6821 Data.Display_File :=
6823 Data.Path := Path_Id;
6824 Data.Display_Path :=
6826 In_Tree.Sources.Table (Source) :=
6830 Add_Source (Source, Data, In_Tree);
6832 Source_Paths_Htable.Set
6833 (In_Tree.Source_Paths_HT,
6837 if Source_To_Replace /= No_Source then
6857 when Directory_Error =>
6860 Source_Dir := Element.Next;
6863 if Current_Verbosity = High then
6864 Write_Line ("end Looking for sources.");
6866 end Search_Directories;
6868 -- Start of processing for Look_For_Sources
6871 if Get_Mode = Ada_Only and then
6872 Is_A_Language (In_Tree, Data, "ada")
6875 Sources : constant Variable_Value :=
6878 Data.Decl.Attributes,
6881 Source_List_File : constant Variable_Value :=
6883 (Name_Source_List_File,
6884 Data.Decl.Attributes,
6887 Excluded_Sources : Variable_Value :=
6889 (Name_Excluded_Source_Files,
6890 Data.Decl.Attributes,
6895 (Sources.Kind = List,
6896 "Source_Files is not a list");
6899 (Source_List_File.Kind = Single,
6900 "Source_List_File is not a single string");
6902 if not Sources.Default then
6903 if not Source_List_File.Default then
6906 "?both variables source_files and " &
6907 "source_list_file are present",
6908 Source_List_File.Location);
6911 -- Sources is a list of file names
6914 Current : String_List_Id := Sources.Values;
6915 Element : String_Element;
6916 Location : Source_Ptr;
6917 Name : File_Name_Type;
6922 Data.Ada_Sources_Present := Current /= Nil_String;
6924 if Current = Nil_String then
6925 Data.Source_Dirs := Nil_String;
6927 -- This project contains no source. For projects that
6928 -- don't extend other projects, this also means that
6929 -- there is no need for an object directory, if not
6932 if Data.Extends = No_Project
6933 and then Data.Object_Directory = Data.Directory
6935 Data.Object_Directory := No_Path;
6939 while Current /= Nil_String loop
6941 In_Tree.String_Elements.Table (Current);
6942 Get_Name_String (Element.Value);
6943 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
6946 -- If the element has no location, then use the
6947 -- location of Sources to report possible errors.
6949 if Element.Location = No_Location then
6950 Location := Sources.Location;
6952 Location := Element.Location;
6959 Location => Location,
6960 Source => No_Source,
6964 Current := Element.Next;
6967 Get_Path_Names_And_Record_Sources (Follow_Links);
6971 -- No source_files specified
6973 -- We check Source_List_File has been specified
6975 elsif not Source_List_File.Default then
6977 -- Source_List_File is the name of the file
6978 -- that contains the source file names
6981 Source_File_Path_Name : constant String :=
6984 (Source_List_File.Value),
6988 if Source_File_Path_Name'Length = 0 then
6989 Err_Vars.Error_Msg_File_1 :=
6990 File_Name_Type (Source_List_File.Value);
6993 "file with sources { does not exist",
6994 Source_List_File.Location);
6997 Get_Sources_From_File
6998 (Source_File_Path_Name,
6999 Source_List_File.Location);
7004 -- Neither Source_Files nor Source_List_File has been
7005 -- specified. Find all the files that satisfy the naming
7006 -- scheme in all the source directories.
7009 (Project, In_Tree, Data, Follow_Links);
7012 -- If Excluded_ource_Files is not declared, check
7013 -- Locally_Removed_Files.
7015 if Excluded_Sources.Default then
7018 (Name_Locally_Removed_Files,
7019 Data.Decl.Attributes,
7023 -- If there are sources that are locally removed, mark them as
7024 -- such in the Units table.
7026 if not Excluded_Sources.Default then
7029 Current : String_List_Id := Excluded_Sources.Values;
7030 Element : String_Element;
7031 Location : Source_Ptr;
7034 Name : File_Name_Type;
7035 Extended : Project_Id;
7038 while Current /= Nil_String loop
7039 Element := In_Tree.String_Elements.Table (Current);
7040 Get_Name_String (Element.Value);
7041 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7044 -- If the element has no location, then use the location
7045 -- of Excluded_Sources to report possible errors.
7047 if Element.Location = No_Location then
7048 Location := Excluded_Sources.Location;
7050 Location := Element.Location;
7055 for Index in Unit_Table.First ..
7056 Unit_Table.Last (In_Tree.Units)
7058 Unit := In_Tree.Units.Table (Index);
7060 if Unit.File_Names (Specification).Name = Name then
7063 -- Check that this is from the current project or
7064 -- that the current project extends.
7066 Extended := Unit.File_Names
7067 (Specification).Project;
7069 if Extended = Project or else
7070 Project_Extends (Project, Extended, In_Tree)
7073 (Specification).Path := Slash;
7075 (Specification).Needs_Pragma := False;
7076 In_Tree.Units.Table (Index) := Unit;
7077 Add_Forbidden_File_Name
7078 (Unit.File_Names (Specification).Name);
7084 "cannot remove a source from " &
7090 Unit.File_Names (Body_Part).Name = Name
7094 -- Check that this is from the current project or
7095 -- that the current project extends.
7097 Extended := Unit.File_Names
7098 (Body_Part).Project;
7100 if Extended = Project or else
7101 Project_Extends (Project, Extended, In_Tree)
7103 Unit.File_Names (Body_Part).Path := Slash;
7104 Unit.File_Names (Body_Part).Needs_Pragma
7106 In_Tree.Units.Table (Index) := Unit;
7107 Add_Forbidden_File_Name
7108 (Unit.File_Names (Body_Part).Name);
7116 Err_Vars.Error_Msg_File_1 := Name;
7118 (Project, In_Tree, "unknown file {", Location);
7121 Current := Element.Next;
7128 if Get_Mode = Ada_Only and then Data.Other_Sources_Present then
7130 -- Set Source_Present to False. It will be set back to True
7131 -- whenever a source is found.
7133 Data.Other_Sources_Present := False;
7134 for Lang in Ada_Language_Index + 1 .. Last_Language_Index loop
7136 -- For each language (other than Ada) in the project file
7138 if Is_Present (Lang, Data, In_Tree) then
7140 -- Reset the indication that there are sources of this
7141 -- language. It will be set back to True whenever we find
7142 -- a source of the language.
7144 Set (Lang, False, Data, In_Tree);
7146 -- First, get the source suffix for the language
7148 Set (Suffix => Suffix_For (Lang, Data.Naming, In_Tree),
7149 For_Language => Lang,
7151 In_Tree => In_Tree);
7153 -- Then, deal with the naming exceptions, if any
7158 Naming_Exceptions : constant Variable_Value :=
7160 (Index => Language_Names.Table (Lang),
7162 In_Array => Data.Naming.Implementation_Exceptions,
7163 In_Tree => In_Tree);
7164 Element_Id : String_List_Id;
7165 Element : String_Element;
7166 File_Id : File_Name_Type;
7167 Source_Found : Boolean := False;
7170 -- If there are naming exceptions, look through them one
7173 if Naming_Exceptions /= Nil_Variable_Value then
7174 Element_Id := Naming_Exceptions.Values;
7176 while Element_Id /= Nil_String loop
7177 Element := In_Tree.String_Elements.Table
7179 Get_Name_String (Element.Value);
7180 Canonical_Case_File_Name
7181 (Name_Buffer (1 .. Name_Len));
7182 File_Id := Name_Find;
7184 -- Put each naming exception in the Source_Names
7185 -- hash table, but if there are repetition, don't
7186 -- bother after the first instance.
7189 Source_Names.Get (File_Id) = No_Name_Location
7191 Source_Found := True;
7195 Location => Element.Location,
7196 Source => No_Source,
7201 Element_Id := Element.Next;
7204 -- If there is at least one naming exception, record
7205 -- those that are found in the source directories.
7207 if Source_Found then
7208 Record_Other_Sources
7209 (Project => Project,
7213 Naming_Exceptions => True);
7219 -- Now, check if a list of sources is declared either through
7220 -- a string list (attribute Source_Files) or a text file
7221 -- (attribute Source_List_File). If a source list is declared,
7222 -- we will consider only those naming exceptions that are
7226 Sources : constant Variable_Value :=
7229 Data.Decl.Attributes,
7232 Source_List_File : constant Variable_Value :=
7234 (Name_Source_List_File,
7235 Data.Decl.Attributes,
7240 (Sources.Kind = List,
7241 "Source_Files is not a list");
7244 (Source_List_File.Kind = Single,
7245 "Source_List_File is not a single string");
7247 if not Sources.Default then
7248 if not Source_List_File.Default then
7251 "?both variables source_files and " &
7252 "source_list_file are present",
7253 Source_List_File.Location);
7256 -- Sources is a list of file names
7259 Current : String_List_Id := Sources.Values;
7260 Element : String_Element;
7261 Location : Source_Ptr;
7262 Name : File_Name_Type;
7267 -- Put all the sources in the Source_Names hash table
7269 while Current /= Nil_String loop
7271 In_Tree.String_Elements.Table
7273 Get_Name_String (Element.Value);
7274 Canonical_Case_File_Name
7275 (Name_Buffer (1 .. Name_Len));
7278 -- If the element has no location, then use the
7279 -- location of Sources to report possible errors.
7281 if Element.Location = No_Location then
7282 Location := Sources.Location;
7284 Location := Element.Location;
7291 Location => Location,
7292 Source => No_Source,
7296 Current := Element.Next;
7299 -- And look for their directories
7301 Record_Other_Sources
7302 (Project => Project,
7306 Naming_Exceptions => False);
7309 -- No source_files specified
7311 -- We check if Source_List_File has been specified
7313 elsif not Source_List_File.Default then
7315 -- Source_List_File is the name of the file
7316 -- that contains the source file names
7319 Source_File_Path_Name : constant String :=
7321 (File_Name_Type (Source_List_File.Value),
7325 if Source_File_Path_Name'Length = 0 then
7326 Err_Vars.Error_Msg_File_1 :=
7327 File_Name_Type (Source_List_File.Value);
7331 "file with sources { does not exist",
7332 Source_List_File.Location);
7335 -- Read the file, putting each source in the
7336 -- Source_Names hash table.
7338 Get_Sources_From_File
7339 (Source_File_Path_Name,
7340 Source_List_File.Location,
7343 -- And look for their directories
7345 Record_Other_Sources
7346 (Project => Project,
7350 Naming_Exceptions => False);
7354 -- Neither Source_Files nor Source_List_File was specified
7357 -- Find all the files that satisfy the naming scheme in
7358 -- all the source directories. All the naming exceptions
7359 -- that effectively exist are also part of the source
7360 -- of this language.
7362 Find_Sources (Project, In_Tree, Data, Lang);
7369 if Get_Mode = Multi_Language and then
7370 Data.First_Language_Processing /= No_Language_Index
7372 -- First, put all the naming exceptions, if any, in the Source_Names
7379 Src_Data : Source_Data;
7380 Name_Loc : Name_Location;
7383 Source := Data.First_Source;
7385 while Source /= No_Source loop
7386 Src_Data := In_Tree.Sources.Table (Source);
7387 Name_Loc := (Name => Src_Data.File,
7388 Location => No_Location,
7390 Except => Src_Data.Unit /= No_Name,
7393 if Current_Verbosity = High then
7394 Write_Str ("Putting source #");
7395 Write_Str (Source'Img);
7396 Write_Str (", file ");
7397 Write_Str (Get_Name_String (Src_Data.File));
7398 Write_Line (" in Source_Names");
7402 (K => Src_Data.File,
7405 Source := Src_Data.Next_In_Project;
7409 -- Now check attributes Sources and Source_List_File
7412 Sources : constant Variable_Value :=
7415 Data.Decl.Attributes,
7418 Source_List_File : constant Variable_Value :=
7420 (Name_Source_List_File,
7421 Data.Decl.Attributes,
7424 Excluded_Sources : Variable_Value :=
7426 (Name_Excluded_Source_Files,
7427 Data.Decl.Attributes,
7429 Name_Loc : Name_Location;
7432 -- If Excluded_ource_Files is not declared, check
7433 -- Locally_Removed_Files.
7435 if Excluded_Sources.Default then
7438 (Name_Locally_Removed_Files,
7439 Data.Decl.Attributes,
7443 if not Sources.Default then
7444 if not Source_List_File.Default then
7447 "?both variables source_files and " &
7448 "source_list_file are present",
7449 Source_List_File.Location);
7452 -- Sources is a list of file names
7455 Current : String_List_Id := Sources.Values;
7456 Element : String_Element;
7457 Location : Source_Ptr;
7458 Name : File_Name_Type;
7461 if Current = Nil_String then
7462 Data.First_Language_Processing := No_Language_Index;
7464 -- This project contains no source. For projects that
7465 -- don't extend other projects, this also means that
7466 -- there is no need for an object directory, if not
7469 if Data.Extends = No_Project
7470 and then Data.Object_Directory = Data.Directory
7472 Data.Object_Directory := No_Path;
7476 while Current /= Nil_String loop
7478 In_Tree.String_Elements.Table (Current);
7479 Get_Name_String (Element.Value);
7480 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7483 -- If the element has no location, then use the
7484 -- location of Sources to report possible errors.
7486 if Element.Location = No_Location then
7487 Location := Sources.Location;
7489 Location := Element.Location;
7492 Name_Loc := Source_Names.Get (Name);
7494 if Name_Loc = No_Name_Location then
7497 Location => Location,
7498 Source => No_Source,
7501 Source_Names.Set (Name, Name_Loc);
7504 Current := Element.Next;
7508 elsif not Source_List_File.Default then
7510 -- Source_List_File is the name of the file
7511 -- that contains the source file names
7514 Source_File_Path_Name : constant String :=
7517 (Source_List_File.Value),
7521 if Source_File_Path_Name'Length = 0 then
7522 Err_Vars.Error_Msg_File_1 :=
7523 File_Name_Type (Source_List_File.Value);
7526 "file with sources { does not exist",
7527 Source_List_File.Location);
7530 Get_Sources_From_File
7531 (Source_File_Path_Name,
7532 Source_List_File.Location);
7539 Sources.Default and then Source_List_File.Default);
7541 -- If there are locally removed sources, mark them as such
7543 if not Excluded_Sources.Default then
7545 Current : String_List_Id;
7546 Element : String_Element;
7547 Location : Source_Ptr;
7549 Name : File_Name_Type;
7551 Src_Data : Source_Data;
7554 Current := Excluded_Sources.Values;
7555 while Current /= Nil_String loop
7557 In_Tree.String_Elements.Table (Current);
7558 Get_Name_String (Element.Value);
7559 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7562 -- If the element has no location, then use the location
7563 -- of Excluded_Sources to report possible errors.
7565 if Element.Location = No_Location then
7566 Location := Excluded_Sources.Location;
7568 Location := Element.Location;
7573 Source := In_Tree.First_Source;
7575 while Source /= No_Source loop
7576 Src_Data := In_Tree.Sources.Table (Source);
7578 if Src_Data.File = Name then
7580 -- Check that this is from this project or a
7581 -- project that the current project extends.
7583 if Src_Data.Project = Project or else
7585 (Project, Src_Data.Project, In_Tree)
7587 Src_Data.Locally_Removed := True;
7588 In_Tree.Sources.Table (Source) := Src_Data;
7589 Add_Forbidden_File_Name (Name);
7595 Source := Src_Data.Next_In_Sources;
7599 Err_Vars.Error_Msg_File_1 := Name;
7601 (Project, In_Tree, "unknown file {", Location);
7604 Current := Element.Next;
7610 end Look_For_Sources;
7616 function Path_Name_Of
7617 (File_Name : File_Name_Type;
7618 Directory : Path_Name_Type)
7621 Result : String_Access;
7623 The_Directory : constant String := Get_Name_String (Directory);
7626 Get_Name_String (File_Name);
7627 Result := Locate_Regular_File
7628 (File_Name => Name_Buffer (1 .. Name_Len),
7629 Path => The_Directory);
7631 if Result = null then
7634 Canonical_Case_File_Name (Result.all);
7639 -------------------------------
7640 -- Prepare_Ada_Naming_Exceptions --
7641 -------------------------------
7643 procedure Prepare_Ada_Naming_Exceptions
7644 (List : Array_Element_Id;
7645 In_Tree : Project_Tree_Ref;
7646 Kind : Spec_Or_Body)
7648 Current : Array_Element_Id;
7649 Element : Array_Element;
7653 -- Traverse the list
7656 while Current /= No_Array_Element loop
7657 Element := In_Tree.Array_Elements.Table (Current);
7659 if Element.Index /= No_Name then
7662 Unit => Element.Index,
7663 Next => No_Ada_Naming_Exception);
7664 Reverse_Ada_Naming_Exceptions.Set
7665 (Unit, (Element.Value.Value, Element.Value.Index));
7667 Ada_Naming_Exceptions.Get (File_Name_Type (Element.Value.Value));
7668 Ada_Naming_Exception_Table.Increment_Last;
7669 Ada_Naming_Exception_Table.Table
7670 (Ada_Naming_Exception_Table.Last) := Unit;
7671 Ada_Naming_Exceptions.Set
7672 (File_Name_Type (Element.Value.Value),
7673 Ada_Naming_Exception_Table.Last);
7676 Current := Element.Next;
7678 end Prepare_Ada_Naming_Exceptions;
7680 ---------------------
7681 -- Project_Extends --
7682 ---------------------
7684 function Project_Extends
7685 (Extending : Project_Id;
7686 Extended : Project_Id;
7687 In_Tree : Project_Tree_Ref) return Boolean
7689 Current : Project_Id := Extending;
7692 if Current = No_Project then
7695 elsif Current = Extended then
7699 Current := In_Tree.Projects.Table (Current).Extends;
7701 end Project_Extends;
7703 -----------------------
7704 -- Record_Ada_Source --
7705 -----------------------
7707 procedure Record_Ada_Source
7708 (File_Name : File_Name_Type;
7709 Path_Name : Path_Name_Type;
7710 Project : Project_Id;
7711 In_Tree : Project_Tree_Ref;
7712 Data : in out Project_Data;
7713 Location : Source_Ptr;
7714 Current_Source : in out String_List_Id;
7715 Source_Recorded : in out Boolean;
7716 Follow_Links : Boolean)
7718 Canonical_File_Name : File_Name_Type;
7719 Canonical_Path_Name : Path_Name_Type;
7721 Exception_Id : Ada_Naming_Exception_Id;
7722 Unit_Name : Name_Id;
7723 Unit_Kind : Spec_Or_Body;
7724 Unit_Ind : Int := 0;
7726 Name_Index : Name_And_Index;
7727 Needs_Pragma : Boolean;
7729 The_Location : Source_Ptr := Location;
7730 Previous_Source : constant String_List_Id := Current_Source;
7731 Except_Name : Name_And_Index := No_Name_And_Index;
7733 Unit_Prj : Unit_Project;
7735 File_Name_Recorded : Boolean := False;
7738 Get_Name_String (File_Name);
7739 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7740 Canonical_File_Name := Name_Find;
7743 Canonical_Path : constant String :=
7745 (Get_Name_String (Path_Name),
7746 Resolve_Links => Follow_Links,
7747 Case_Sensitive => False);
7750 Add_Str_To_Name_Buffer (Canonical_Path);
7751 Canonical_Path_Name := Name_Find;
7754 -- Find out the unit name, the unit kind and if it needs
7755 -- a specific SFN pragma.
7758 (In_Tree => In_Tree,
7759 Canonical_File_Name => Canonical_File_Name,
7760 Naming => Data.Naming,
7761 Exception_Id => Exception_Id,
7762 Unit_Name => Unit_Name,
7763 Unit_Kind => Unit_Kind,
7764 Needs_Pragma => Needs_Pragma);
7766 if Exception_Id = No_Ada_Naming_Exception and then
7769 if Current_Verbosity = High then
7771 Write_Str (Get_Name_String (Canonical_File_Name));
7772 Write_Line (""" is not a valid source file name (ignored).");
7776 -- Check to see if the source has been hidden by an exception,
7777 -- but only if it is not an exception.
7779 if not Needs_Pragma then
7781 Reverse_Ada_Naming_Exceptions.Get
7782 ((Unit_Kind, Unit_Name, No_Ada_Naming_Exception));
7784 if Except_Name /= No_Name_And_Index then
7785 if Current_Verbosity = High then
7787 Write_Str (Get_Name_String (Canonical_File_Name));
7788 Write_Str (""" contains a unit that is found in """);
7789 Write_Str (Get_Name_String (Except_Name.Name));
7790 Write_Line (""" (ignored).");
7793 -- The file is not included in the source of the project since
7794 -- it is hidden by the exception. So, nothing else to do.
7801 if Exception_Id /= No_Ada_Naming_Exception then
7802 Info := Ada_Naming_Exception_Table.Table (Exception_Id);
7803 Exception_Id := Info.Next;
7804 Info.Next := No_Ada_Naming_Exception;
7805 Name_Index := Reverse_Ada_Naming_Exceptions.Get (Info);
7807 Unit_Name := Info.Unit;
7808 Unit_Ind := Name_Index.Index;
7809 Unit_Kind := Info.Kind;
7812 -- Put the file name in the list of sources of the project
7814 String_Element_Table.Increment_Last
7815 (In_Tree.String_Elements);
7816 In_Tree.String_Elements.Table
7817 (String_Element_Table.Last
7818 (In_Tree.String_Elements)) :=
7819 (Value => Name_Id (Canonical_File_Name),
7820 Display_Value => Name_Id (File_Name),
7821 Location => No_Location,
7826 if Current_Source = Nil_String then
7827 Data.Ada_Sources := String_Element_Table.Last
7828 (In_Tree.String_Elements);
7829 Data.Sources := Data.Ada_Sources;
7831 In_Tree.String_Elements.Table
7832 (Current_Source).Next :=
7833 String_Element_Table.Last
7834 (In_Tree.String_Elements);
7837 Current_Source := String_Element_Table.Last
7838 (In_Tree.String_Elements);
7840 -- Put the unit in unit list
7843 The_Unit : Unit_Index :=
7844 Units_Htable.Get (In_Tree.Units_HT, Unit_Name);
7846 The_Unit_Data : Unit_Data;
7849 if Current_Verbosity = High then
7850 Write_Str ("Putting ");
7851 Write_Str (Get_Name_String (Unit_Name));
7852 Write_Line (" in the unit list.");
7855 -- The unit is already in the list, but may be it is
7856 -- only the other unit kind (spec or body), or what is
7857 -- in the unit list is a unit of a project we are extending.
7859 if The_Unit /= No_Unit_Index then
7860 The_Unit_Data := In_Tree.Units.Table (The_Unit);
7862 if (The_Unit_Data.File_Names (Unit_Kind).Name =
7865 The_Unit_Data.File_Names (Unit_Kind).Path = Slash)
7866 or else The_Unit_Data.File_Names (Unit_Kind).Name = No_File
7867 or else Project_Extends
7869 The_Unit_Data.File_Names (Unit_Kind).Project,
7872 if The_Unit_Data.File_Names (Unit_Kind).Path = Slash then
7873 Remove_Forbidden_File_Name
7874 (The_Unit_Data.File_Names (Unit_Kind).Name);
7877 -- Record the file name in the hash table Files_Htable
7879 Unit_Prj := (Unit => The_Unit, Project => Project);
7882 Canonical_File_Name,
7885 The_Unit_Data.File_Names (Unit_Kind) :=
7886 (Name => Canonical_File_Name,
7888 Display_Name => File_Name,
7889 Path => Canonical_Path_Name,
7890 Display_Path => Path_Name,
7892 Needs_Pragma => Needs_Pragma);
7893 In_Tree.Units.Table (The_Unit) :=
7895 Source_Recorded := True;
7897 elsif The_Unit_Data.File_Names (Unit_Kind).Project = Project
7898 and then (Data.Known_Order_Of_Source_Dirs or else
7899 The_Unit_Data.File_Names (Unit_Kind).Path =
7900 Canonical_Path_Name)
7902 if Previous_Source = Nil_String then
7903 Data.Ada_Sources := Nil_String;
7904 Data.Sources := Nil_String;
7906 In_Tree.String_Elements.Table
7907 (Previous_Source).Next := Nil_String;
7908 String_Element_Table.Decrement_Last
7909 (In_Tree.String_Elements);
7912 Current_Source := Previous_Source;
7915 -- It is an error to have two units with the same name
7916 -- and the same kind (spec or body).
7918 if The_Location = No_Location then
7920 In_Tree.Projects.Table
7924 Err_Vars.Error_Msg_Name_1 := Unit_Name;
7926 (Project, In_Tree, "duplicate source %%", The_Location);
7928 Err_Vars.Error_Msg_Name_1 :=
7929 In_Tree.Projects.Table
7930 (The_Unit_Data.File_Names (Unit_Kind).Project).Name;
7931 Err_Vars.Error_Msg_File_1 :=
7933 (The_Unit_Data.File_Names (Unit_Kind).Path);
7936 "\ project file %%, {", The_Location);
7938 Err_Vars.Error_Msg_Name_1 :=
7939 In_Tree.Projects.Table (Project).Name;
7940 Err_Vars.Error_Msg_File_1 :=
7941 File_Name_Type (Canonical_Path_Name);
7944 "\ project file %%, {", The_Location);
7947 -- It is a new unit, create a new record
7950 -- First, check if there is no other unit with this file
7951 -- name in another project. If it is, report an error.
7952 -- Of course, we do that only for the first unit in the
7955 Unit_Prj := Files_Htable.Get
7956 (In_Tree.Files_HT, Canonical_File_Name);
7958 if not File_Name_Recorded and then
7959 Unit_Prj /= No_Unit_Project
7961 Error_Msg_File_1 := File_Name;
7963 In_Tree.Projects.Table
7964 (Unit_Prj.Project).Name;
7967 "{ is already a source of project %%",
7971 Unit_Table.Increment_Last (In_Tree.Units);
7972 The_Unit := Unit_Table.Last (In_Tree.Units);
7974 (In_Tree.Units_HT, Unit_Name, The_Unit);
7975 Unit_Prj := (Unit => The_Unit, Project => Project);
7978 Canonical_File_Name,
7980 The_Unit_Data.Name := Unit_Name;
7981 The_Unit_Data.File_Names (Unit_Kind) :=
7982 (Name => Canonical_File_Name,
7984 Display_Name => File_Name,
7985 Path => Canonical_Path_Name,
7986 Display_Path => Path_Name,
7988 Needs_Pragma => Needs_Pragma);
7989 In_Tree.Units.Table (The_Unit) :=
7991 Source_Recorded := True;
7996 exit when Exception_Id = No_Ada_Naming_Exception;
7997 File_Name_Recorded := True;
8000 end Record_Ada_Source;
8002 --------------------------
8003 -- Record_Other_Sources --
8004 --------------------------
8006 procedure Record_Other_Sources
8007 (Project : Project_Id;
8008 In_Tree : Project_Tree_Ref;
8009 Data : in out Project_Data;
8010 Language : Language_Index;
8011 Naming_Exceptions : Boolean)
8013 Source_Dir : String_List_Id;
8014 Element : String_Element;
8015 Path : Path_Name_Type;
8017 Canonical_Name : File_Name_Type;
8018 Name_Str : String (1 .. 1_024);
8019 Last : Natural := 0;
8021 First_Error : Boolean := True;
8022 Suffix : constant String :=
8023 Body_Suffix_Of (Language, Data, In_Tree);
8026 Source_Dir := Data.Source_Dirs;
8027 while Source_Dir /= Nil_String loop
8028 Element := In_Tree.String_Elements.Table (Source_Dir);
8031 Dir_Path : constant String :=
8032 Get_Name_String (Element.Display_Value);
8034 if Current_Verbosity = High then
8035 Write_Str ("checking directory """);
8036 Write_Str (Dir_Path);
8037 Write_Str (""" for ");
8039 if Naming_Exceptions then
8040 Write_Str ("naming exceptions");
8043 Write_Str ("sources");
8046 Write_Str (" of Language ");
8047 Display_Language_Name (Language);
8050 Open (Dir, Dir_Path);
8053 Read (Dir, Name_Str, Last);
8057 (Dir_Path & Directory_Separator & Name_Str (1 .. Last))
8060 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
8061 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
8062 Canonical_Name := Name_Find;
8063 NL := Source_Names.Get (Canonical_Name);
8065 if NL /= No_Name_Location then
8067 if not Data.Known_Order_Of_Source_Dirs then
8068 Error_Msg_File_1 := Canonical_Name;
8071 "{ is found in several source directories",
8077 Source_Names.Set (Canonical_Name, NL);
8078 Name_Len := Dir_Path'Length;
8079 Name_Buffer (1 .. Name_Len) := Dir_Path;
8080 Add_Char_To_Name_Buffer (Directory_Separator);
8081 Add_Str_To_Name_Buffer (Name_Str (1 .. Last));
8085 (File_Name => Canonical_Name,
8090 Location => NL.Location,
8091 Language => Language,
8093 Naming_Exception => Naming_Exceptions);
8102 Source_Dir := Element.Next;
8105 if not Naming_Exceptions then
8106 NL := Source_Names.Get_First;
8108 -- It is an error if a source file name in a source list or
8109 -- in a source list file is not found.
8111 while NL /= No_Name_Location loop
8112 if not NL.Found then
8113 Err_Vars.Error_Msg_File_1 := NL.Name;
8118 "source file { cannot be found",
8120 First_Error := False;
8125 "\source file { cannot be found",
8130 NL := Source_Names.Get_Next;
8133 -- Any naming exception of this language that is not in a list
8134 -- of sources must be removed.
8137 Source_Id : Other_Source_Id := Data.First_Other_Source;
8138 Prev_Id : Other_Source_Id := No_Other_Source;
8139 Source : Other_Source;
8142 while Source_Id /= No_Other_Source loop
8143 Source := In_Tree.Other_Sources.Table (Source_Id);
8145 if Source.Language = Language
8146 and then Source.Naming_Exception
8148 if Current_Verbosity = High then
8149 Write_Str ("Naming exception """);
8150 Write_Str (Get_Name_String (Source.File_Name));
8151 Write_Str (""" is not in the list of sources,");
8152 Write_Line (" so it is removed.");
8155 if Prev_Id = No_Other_Source then
8156 Data.First_Other_Source := Source.Next;
8159 In_Tree.Other_Sources.Table
8160 (Prev_Id).Next := Source.Next;
8163 Source_Id := Source.Next;
8165 if Source_Id = No_Other_Source then
8166 Data.Last_Other_Source := Prev_Id;
8170 Prev_Id := Source_Id;
8171 Source_Id := Source.Next;
8176 end Record_Other_Sources;
8182 procedure Remove_Source
8184 Replaced_By : Source_Id;
8185 Project : Project_Id;
8186 Data : in out Project_Data;
8187 In_Tree : Project_Tree_Ref)
8189 Src_Data : constant Source_Data := In_Tree.Sources.Table (Id);
8194 if Current_Verbosity = High then
8195 Write_Str ("Removing source #");
8196 Write_Line (Id'Img);
8199 In_Tree.Sources.Table (Id).Replaced_By := Replaced_By;
8201 -- Remove the source from the global source list
8203 Source := In_Tree.First_Source;
8206 In_Tree.First_Source := Src_Data.Next_In_Sources;
8209 while In_Tree.Sources.Table (Source).Next_In_Sources /= Id loop
8210 Source := In_Tree.Sources.Table (Source).Next_In_Sources;
8213 In_Tree.Sources.Table (Source).Next_In_Sources :=
8214 Src_Data.Next_In_Sources;
8217 -- Remove the source from the project list
8219 if Src_Data.Project = Project then
8220 Source := Data.First_Source;
8223 Data.First_Source := Src_Data.Next_In_Project;
8225 if Src_Data.Next_In_Project = No_Source then
8226 Data.Last_Source := No_Source;
8230 while In_Tree.Sources.Table (Source).Next_In_Project /= Id loop
8231 Source := In_Tree.Sources.Table (Source).Next_In_Project;
8234 In_Tree.Sources.Table (Source).Next_In_Project :=
8235 Src_Data.Next_In_Project;
8237 if Src_Data.Next_In_Project = No_Source then
8238 In_Tree.Projects.Table (Src_Data.Project).Last_Source := Source;
8243 Source := In_Tree.Projects.Table (Src_Data.Project).First_Source;
8246 In_Tree.Projects.Table (Src_Data.Project).First_Source :=
8247 Src_Data.Next_In_Project;
8249 if Src_Data.Next_In_Project = No_Source then
8250 In_Tree.Projects.Table (Src_Data.Project).Last_Source :=
8255 while In_Tree.Sources.Table (Source).Next_In_Project /= Id loop
8256 Source := In_Tree.Sources.Table (Source).Next_In_Project;
8259 In_Tree.Sources.Table (Source).Next_In_Project :=
8260 Src_Data.Next_In_Project;
8262 if Src_Data.Next_In_Project = No_Source then
8263 In_Tree.Projects.Table (Src_Data.Project).Last_Source := Source;
8268 -- Remove source from the language list
8270 Source := In_Tree.Languages_Data.Table (Src_Data.Language).First_Source;
8273 In_Tree.Languages_Data.Table (Src_Data.Language).First_Source :=
8274 Src_Data.Next_In_Lang;
8277 while In_Tree.Sources.Table (Source).Next_In_Lang /= Id loop
8278 Source := In_Tree.Sources.Table (Source).Next_In_Lang;
8281 In_Tree.Sources.Table (Source).Next_In_Lang :=
8282 Src_Data.Next_In_Lang;
8286 -----------------------
8287 -- Report_No_Sources --
8288 -----------------------
8290 procedure Report_No_Sources
8291 (Project : Project_Id;
8293 In_Tree : Project_Tree_Ref;
8294 Location : Source_Ptr)
8297 case When_No_Sources is
8301 when Warning | Error =>
8302 Error_Msg_Warn := When_No_Sources = Warning;
8305 "<there are no " & Lang_Name & " sources in this project",
8308 end Report_No_Sources;
8310 ----------------------
8311 -- Show_Source_Dirs --
8312 ----------------------
8314 procedure Show_Source_Dirs
8315 (Data : Project_Data;
8316 In_Tree : Project_Tree_Ref)
8318 Current : String_List_Id;
8319 Element : String_Element;
8322 Write_Line ("Source_Dirs:");
8324 Current := Data.Source_Dirs;
8325 while Current /= Nil_String loop
8326 Element := In_Tree.String_Elements.Table (Current);
8328 Write_Line (Get_Name_String (Element.Value));
8329 Current := Element.Next;
8332 Write_Line ("end Source_Dirs.");
8333 end Show_Source_Dirs;
8340 (Language : Language_Index;
8341 Naming : Naming_Data;
8342 In_Tree : Project_Tree_Ref) return File_Name_Type
8344 Suffix : constant Variable_Value :=
8346 (Index => Language_Names.Table (Language),
8348 In_Array => Naming.Body_Suffix,
8349 In_Tree => In_Tree);
8351 -- If no suffix for this language in package Naming, use the default
8353 if Suffix = Nil_Variable_Value then
8357 when Ada_Language_Index =>
8358 Add_Str_To_Name_Buffer (".adb");
8360 when C_Language_Index =>
8361 Add_Str_To_Name_Buffer (".c");
8363 when C_Plus_Plus_Language_Index =>
8364 Add_Str_To_Name_Buffer (".cpp");
8370 -- Otherwise use the one specified
8373 Get_Name_String (Suffix.Value);
8376 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
8380 -------------------------
8381 -- Warn_If_Not_Sources --
8382 -------------------------
8384 -- comments needed in this body ???
8386 procedure Warn_If_Not_Sources
8387 (Project : Project_Id;
8388 In_Tree : Project_Tree_Ref;
8389 Conventions : Array_Element_Id;
8391 Extending : Boolean)
8393 Conv : Array_Element_Id := Conventions;
8395 The_Unit_Id : Unit_Index;
8396 The_Unit_Data : Unit_Data;
8397 Location : Source_Ptr;
8400 while Conv /= No_Array_Element loop
8401 Unit := In_Tree.Array_Elements.Table (Conv).Index;
8402 Error_Msg_Name_1 := Unit;
8403 Get_Name_String (Unit);
8404 To_Lower (Name_Buffer (1 .. Name_Len));
8406 The_Unit_Id := Units_Htable.Get
8407 (In_Tree.Units_HT, Unit);
8408 Location := In_Tree.Array_Elements.Table
8409 (Conv).Value.Location;
8411 if The_Unit_Id = No_Unit_Index then
8418 The_Unit_Data := In_Tree.Units.Table (The_Unit_Id);
8420 In_Tree.Array_Elements.Table (Conv).Value.Value;
8423 if not Check_Project
8424 (The_Unit_Data.File_Names (Specification).Project,
8425 Project, In_Tree, Extending)
8429 "?source of spec of unit %% (%%)" &
8430 " cannot be found in this project",
8435 if not Check_Project
8436 (The_Unit_Data.File_Names (Body_Part).Project,
8437 Project, In_Tree, Extending)
8441 "?source of body of unit %% (%%)" &
8442 " cannot be found in this project",
8448 Conv := In_Tree.Array_Elements.Table (Conv).Next;
8450 end Warn_If_Not_Sources;