1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 2000-2008, 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 -- More documentation needed on what unit exceptions are about ???
102 type Unit_Exception is record
104 Spec : File_Name_Type;
105 Impl : File_Name_Type;
108 No_Unit_Exception : constant Unit_Exception :=
113 package Unit_Exceptions is new GNAT.HTable.Simple_HTable
114 (Header_Num => Header_Num,
115 Element => Unit_Exception,
116 No_Element => No_Unit_Exception,
120 -- Hash table to store the unit exceptions
122 package Recursive_Dirs is new GNAT.HTable.Simple_HTable
123 (Header_Num => Header_Num,
129 -- Hash table to store recursive source directories, to avoid looking
130 -- several times, and to avoid cycles that may be introduced by symbolic
133 type Ada_Naming_Exception_Id is new Nat;
134 No_Ada_Naming_Exception : constant Ada_Naming_Exception_Id := 0;
136 type Unit_Info is record
139 Next : Ada_Naming_Exception_Id := No_Ada_Naming_Exception;
143 -- Why is the following commented out ???
144 -- No_Unit : constant Unit_Info :=
145 -- (Specification, No_Name, No_Ada_Naming_Exception);
147 package Ada_Naming_Exception_Table is new Table.Table
148 (Table_Component_Type => Unit_Info,
149 Table_Index_Type => Ada_Naming_Exception_Id,
150 Table_Low_Bound => 1,
152 Table_Increment => 100,
153 Table_Name => "Prj.Nmsc.Ada_Naming_Exception_Table");
155 package Ada_Naming_Exceptions is new GNAT.HTable.Simple_HTable
156 (Header_Num => Header_Num,
157 Element => Ada_Naming_Exception_Id,
158 No_Element => No_Ada_Naming_Exception,
159 Key => File_Name_Type,
162 -- A hash table to store naming exceptions for Ada. For each file name
163 -- there is one or several unit in table Ada_Naming_Exception_Table.
165 type File_Found is record
166 File : File_Name_Type := No_File;
167 Found : Boolean := False;
168 Location : Source_Ptr := No_Location;
170 No_File_Found : constant File_Found := (No_File, False, No_Location);
171 -- Comments needed ???
173 package Excluded_Sources_Htable is new GNAT.HTable.Simple_HTable
174 (Header_Num => Header_Num,
175 Element => File_Found,
176 No_Element => No_File_Found,
177 Key => File_Name_Type,
180 -- A hash table to store the excluded files, if any. This is filled by
181 -- Find_Excluded_Sources below.
183 procedure Find_Excluded_Sources
184 (Project : Project_Id;
185 In_Tree : Project_Tree_Ref;
186 Data : Project_Data);
187 -- Find the list of files that should not be considered as source files
188 -- for this project. Sets the list in the Excluded_Sources_Htable.
190 function Hash (Unit : Unit_Info) return Header_Num;
192 type Name_And_Index is record
193 Name : Name_Id := No_Name;
196 No_Name_And_Index : constant Name_And_Index :=
197 (Name => No_Name, Index => 0);
199 package Reverse_Ada_Naming_Exceptions is new GNAT.HTable.Simple_HTable
200 (Header_Num => Header_Num,
201 Element => Name_And_Index,
202 No_Element => No_Name_And_Index,
206 -- A table to check if a unit with an exceptional name will hide a source
207 -- with a file name following the naming convention.
211 Data : in out Project_Data;
212 In_Tree : Project_Tree_Ref;
213 Project : Project_Id;
215 Lang_Id : Language_Index;
217 File_Name : File_Name_Type;
218 Display_File : File_Name_Type;
219 Lang_Kind : Language_Kind;
220 Naming_Exception : Boolean := False;
221 Path : Path_Name_Type := No_Path;
222 Display_Path : Path_Name_Type := No_Path;
223 Alternate_Languages : Alternate_Language_Id := No_Alternate_Language;
224 Other_Part : Source_Id := No_Source;
225 Unit : Name_Id := No_Name;
227 Source_To_Replace : Source_Id := No_Source);
228 -- Add a new source to the different lists: list of all sources in the
229 -- project tree, list of source of a project and list of sources of a
232 -- If Path is specified, the file is also added to Source_Paths_HT.
233 -- If Source_To_Replace is specified, it points to the source in the
234 -- extended project that the new file is overriding.
236 function ALI_File_Name (Source : String) return String;
237 -- Return the ALI file name corresponding to a source
239 procedure Check_Ada_Name (Name : String; Unit : out Name_Id);
240 -- Check that a name is a valid Ada unit name
242 procedure Check_Naming_Schemes
243 (Data : in out Project_Data;
244 Project : Project_Id;
245 In_Tree : Project_Tree_Ref);
246 -- Check the naming scheme part of Data
248 procedure Check_Ada_Naming_Scheme_Validity
249 (Project : Project_Id;
250 In_Tree : Project_Tree_Ref;
251 Naming : Naming_Data);
252 -- Check that the package Naming is correct
254 procedure Check_Configuration
255 (Project : Project_Id;
256 In_Tree : Project_Tree_Ref;
257 Data : in out Project_Data);
258 -- Check the configuration attributes for the project
260 procedure Check_For_Source
261 (File_Name : File_Name_Type;
262 Path_Name : Path_Name_Type;
263 Project : Project_Id;
264 In_Tree : Project_Tree_Ref;
265 Data : in out Project_Data;
266 Location : Source_Ptr;
267 Language : Language_Index;
269 Naming_Exception : Boolean);
270 -- Check if a file, with name File_Name and path Path_Name, in a source
271 -- directory is a source for language Language in project Project of
272 -- project tree In_Tree. ???
274 procedure Check_If_Externally_Built
275 (Project : Project_Id;
276 In_Tree : Project_Tree_Ref;
277 Data : in out Project_Data);
278 -- Check attribute Externally_Built of project Project in project tree
279 -- In_Tree and modify its data Data if it has the value "true".
281 procedure Check_Interfaces
282 (Project : Project_Id;
283 In_Tree : Project_Tree_Ref;
284 Data : in out Project_Data);
285 -- If a list of sources is specified in attribute Interfaces, set
286 -- In_Interfaces only for the sources specified in the list.
288 procedure Check_Library_Attributes
289 (Project : Project_Id;
290 In_Tree : Project_Tree_Ref;
291 Current_Dir : String;
292 Data : in out Project_Data);
293 -- Check the library attributes of project Project in project tree In_Tree
294 -- and modify its data Data accordingly.
295 -- Current_Dir should represent the current directory, and is passed for
296 -- efficiency to avoid system calls to recompute it.
298 procedure Check_Package_Naming
299 (Project : Project_Id;
300 In_Tree : Project_Tree_Ref;
301 Data : in out Project_Data);
302 -- Check package Naming of project Project in project tree In_Tree and
303 -- modify its data Data accordingly.
305 procedure Check_Programming_Languages
306 (In_Tree : Project_Tree_Ref;
307 Project : Project_Id;
308 Data : in out Project_Data);
309 -- Check attribute Languages for the project with data Data in project
310 -- tree In_Tree and set the components of Data for all the programming
311 -- languages indicated in attribute Languages, if any.
313 function Check_Project
315 Root_Project : Project_Id;
316 In_Tree : Project_Tree_Ref;
317 Extending : Boolean) return Boolean;
318 -- Returns True if P is Root_Project or, if Extending is True, a project
319 -- extended by Root_Project.
321 procedure Check_Stand_Alone_Library
322 (Project : Project_Id;
323 In_Tree : Project_Tree_Ref;
324 Data : in out Project_Data;
325 Current_Dir : String;
326 Extending : Boolean);
327 -- Check if project Project in project tree In_Tree is a Stand-Alone
328 -- Library project, and modify its data Data accordingly if it is one.
329 -- Current_Dir should represent the current directory, and is passed for
330 -- efficiency to avoid system calls to recompute it.
332 procedure Get_Path_Names_And_Record_Ada_Sources
333 (Project : Project_Id;
334 In_Tree : Project_Tree_Ref;
335 Data : in out Project_Data;
336 Current_Dir : String);
337 -- Find the path names of the source files in the Source_Names table
338 -- in the source directories and record those that are Ada sources.
340 function Compute_Directory_Last (Dir : String) return Natural;
341 -- Return the index of the last significant character in Dir. This is used
342 -- to avoid duplicate '/' (slash) characters at the end of directory names.
345 (Project : Project_Id;
346 In_Tree : Project_Tree_Ref;
348 Flag_Location : Source_Ptr);
349 -- Output an error message. If Error_Report is null, simply call
350 -- Prj.Err.Error_Msg. Otherwise, disregard Flag_Location and use
353 procedure Find_Ada_Sources
354 (Project : Project_Id;
355 In_Tree : Project_Tree_Ref;
356 Data : in out Project_Data;
357 Current_Dir : String);
358 -- Find all the Ada sources in all of the source directories of a project
359 -- Current_Dir should represent the current directory, and is passed for
360 -- efficiency to avoid system calls to recompute it.
362 procedure Find_Sources
363 (Project : Project_Id;
364 In_Tree : Project_Tree_Ref;
365 Data : in out Project_Data;
366 For_Language : Language_Index;
367 Current_Dir : String);
368 -- Find all the sources in all of the source directories of a project for
369 -- a specified language.
371 procedure Search_Directories
372 (Project : Project_Id;
373 In_Tree : Project_Tree_Ref;
374 Data : in out Project_Data;
375 For_All_Sources : Boolean);
376 -- Search the source directories to find the sources.
377 -- If For_All_Sources is True, check each regular file name against the
378 -- naming schemes of the different languages. Otherwise consider only the
379 -- file names in the hash table Source_Names.
382 (Project : Project_Id;
383 In_Tree : Project_Tree_Ref;
384 Data : in out Project_Data;
386 File_Name : File_Name_Type;
387 Display_File_Name : File_Name_Type;
388 Source_Directory : String;
389 For_All_Sources : Boolean);
390 -- Check if file File_Name is a valid source of the project. This is used
391 -- in multi-language mode only.
392 -- When the file matches one of the naming schemes, it is added to
393 -- various htables through Add_Source and to Source_Paths_Htable.
395 -- Name is the name of the candidate file. It hasn't been normalized yet
396 -- and is the direct result of readdir().
398 -- File_Name is the same as Name, but has been normalized.
399 -- Display_File_Name, however, has not been normalized.
401 -- Source_Directory is the directory in which the file
402 -- was found. It hasn't been normalized (nor has had links resolved).
403 -- It should not end with a directory separator, to avoid duplicates
406 -- If For_All_Sources is True, then all possible file names are analyzed
407 -- otherwise only those currently set in the Source_Names htable.
409 procedure Check_Naming_Schemes
410 (In_Tree : Project_Tree_Ref;
411 Data : in out Project_Data;
413 File_Name : File_Name_Type;
414 Alternate_Languages : out Alternate_Language_Id;
415 Language : out Language_Index;
416 Language_Name : out Name_Id;
417 Display_Language_Name : out Name_Id;
419 Lang_Kind : out Language_Kind;
420 Kind : out Source_Kind);
421 -- Check if the file name File_Name conforms to one of the naming
422 -- schemes of the project.
424 -- If the file does not match one of the naming schemes, set Language
425 -- to No_Language_Index.
427 -- Filename is the name of the file being investigated. It has been
428 -- normalized (case-folded). File_Name is the same value.
430 procedure Free_Ada_Naming_Exceptions;
431 -- Free the internal hash tables used for checking naming exceptions
433 procedure Get_Directories
434 (Project : Project_Id;
435 In_Tree : Project_Tree_Ref;
436 Current_Dir : String;
437 Data : in out Project_Data);
438 -- Get the object directory, the exec directory and the source directories
441 -- Current_Dir should represent the current directory, and is passed for
442 -- efficiency to avoid system calls to recompute it.
445 (Project : Project_Id;
446 In_Tree : Project_Tree_Ref;
447 Data : in out Project_Data);
448 -- Get the mains of a project from attribute Main, if it exists, and put
449 -- them in the project data.
451 procedure Get_Sources_From_File
453 Location : Source_Ptr;
454 Project : Project_Id;
455 In_Tree : Project_Tree_Ref);
456 -- Get the list of sources from a text file and put them in hash table
459 procedure Find_Explicit_Sources
460 (Lang : Language_Index;
461 Current_Dir : String;
462 Project : Project_Id;
463 In_Tree : Project_Tree_Ref;
464 Data : in out Project_Data);
465 -- Process the Source_Files and Source_List_File attributes, and store
466 -- the list of source files into the Source_Names htable.
468 -- Lang indicates which language is being processed when in Ada_Only mode
469 -- (all languages are processed anyway when in Multi_Language mode).
472 (In_Tree : Project_Tree_Ref;
473 Canonical_File_Name : File_Name_Type;
474 Naming : Naming_Data;
475 Exception_Id : out Ada_Naming_Exception_Id;
476 Unit_Name : out Name_Id;
477 Unit_Kind : out Spec_Or_Body;
478 Needs_Pragma : out Boolean);
479 -- Find out, from a file name, the unit name, the unit kind and if a
480 -- specific SFN pragma is needed. If the file name corresponds to no unit,
481 -- then Unit_Name will be No_Name. If the file is a multi-unit source or an
482 -- exception to the naming scheme, then Exception_Id is set to the unit or
483 -- units that the source contains.
485 function Is_Illegal_Suffix
487 Dot_Replacement_Is_A_Single_Dot : Boolean) return Boolean;
488 -- Returns True if the string Suffix cannot be used as a spec suffix, a
489 -- body suffix or a separate suffix.
491 procedure Locate_Directory
492 (Project : Project_Id;
493 In_Tree : Project_Tree_Ref;
494 Name : File_Name_Type;
495 Parent : Path_Name_Type;
496 Dir : out Path_Name_Type;
497 Display : out Path_Name_Type;
498 Create : String := "";
499 Current_Dir : String;
500 Location : Source_Ptr := No_Location);
501 -- Locate a directory. Name is the directory name. Parent is the root
502 -- directory, if Name a relative path name. Dir is set to the canonical
503 -- case path name of the directory, and Display is the directory path name
504 -- for display purposes. If the directory does not exist and Project_Setup
505 -- is True and Create is a non null string, an attempt is made to create
506 -- the directory. If the directory does not exist and Project_Setup is
507 -- false, then Dir and Display are set to No_Name.
509 -- Current_Dir should represent the current directory, and is passed for
510 -- efficiency to avoid system calls to recompute it.
512 procedure Look_For_Sources
513 (Project : Project_Id;
514 In_Tree : Project_Tree_Ref;
515 Data : in out Project_Data;
516 Current_Dir : String);
517 -- Find all the sources of project Project in project tree In_Tree and
518 -- update its Data accordingly.
520 -- Current_Dir should represent the current directory, and is passed for
521 -- efficiency to avoid system calls to recompute it.
523 function Path_Name_Of
524 (File_Name : File_Name_Type;
525 Directory : Path_Name_Type) return String;
526 -- Returns the path name of a (non project) file. Returns an empty string
527 -- if file cannot be found.
529 procedure Prepare_Ada_Naming_Exceptions
530 (List : Array_Element_Id;
531 In_Tree : Project_Tree_Ref;
532 Kind : Spec_Or_Body);
533 -- Prepare the internal hash tables used for checking naming exceptions
534 -- for Ada. Insert all elements of List in the tables.
536 function Project_Extends
537 (Extending : Project_Id;
538 Extended : Project_Id;
539 In_Tree : Project_Tree_Ref) return Boolean;
540 -- Returns True if Extending is extending Extended either directly or
543 procedure Record_Ada_Source
544 (File_Name : File_Name_Type;
545 Path_Name : Path_Name_Type;
546 Project : Project_Id;
547 In_Tree : Project_Tree_Ref;
548 Data : in out Project_Data;
549 Location : Source_Ptr;
550 Current_Source : in out String_List_Id;
551 Source_Recorded : in out Boolean;
552 Current_Dir : String);
553 -- Put a unit in the list of units of a project, if the file name
554 -- corresponds to a valid unit name.
556 -- Current_Dir should represent the current directory, and is passed for
557 -- efficiency to avoid system calls to recompute it.
559 procedure Record_Other_Sources
560 (Project : Project_Id;
561 In_Tree : Project_Tree_Ref;
562 Data : in out Project_Data;
563 Language : Language_Index;
564 Naming_Exceptions : Boolean);
565 -- Record the sources of a language in a project. When Naming_Exceptions is
566 -- True, mark the found sources as such, to later remove those that are not
567 -- named in a list of sources.
569 procedure Remove_Source
571 Replaced_By : Source_Id;
572 Project : Project_Id;
573 Data : in out Project_Data;
574 In_Tree : Project_Tree_Ref);
577 procedure Report_No_Sources
578 (Project : Project_Id;
580 In_Tree : Project_Tree_Ref;
581 Location : Source_Ptr;
582 Continuation : Boolean := False);
583 -- Report an error or a warning depending on the value of When_No_Sources
584 -- when there are no sources for language Lang_Name.
586 procedure Show_Source_Dirs
587 (Data : Project_Data; In_Tree : Project_Tree_Ref);
588 -- List all the source directories of a project
591 (Language : Language_Index;
592 Naming : Naming_Data;
593 In_Tree : Project_Tree_Ref) return File_Name_Type;
594 -- Get the suffix for the source of a language from a package naming. If
595 -- not specified, return the default for the language.
597 procedure Warn_If_Not_Sources
598 (Project : Project_Id;
599 In_Tree : Project_Tree_Ref;
600 Conventions : Array_Element_Id;
602 Extending : Boolean);
603 -- Check that individual naming conventions apply to immediate sources of
604 -- the project. If not, issue a warning.
612 Data : in out Project_Data;
613 In_Tree : Project_Tree_Ref;
614 Project : Project_Id;
616 Lang_Id : Language_Index;
618 File_Name : File_Name_Type;
619 Display_File : File_Name_Type;
620 Lang_Kind : Language_Kind;
621 Naming_Exception : Boolean := False;
622 Path : Path_Name_Type := No_Path;
623 Display_Path : Path_Name_Type := No_Path;
624 Alternate_Languages : Alternate_Language_Id := No_Alternate_Language;
625 Other_Part : Source_Id := No_Source;
626 Unit : Name_Id := No_Name;
628 Source_To_Replace : Source_Id := No_Source)
630 Source : constant Source_Id := Data.Last_Source;
631 Src_Data : Source_Data := No_Source_Data;
632 Config : constant Language_Config :=
633 In_Tree.Languages_Data.Table (Lang_Id).Config;
636 -- This is a new source so create an entry for it in the Sources table
638 Source_Data_Table.Increment_Last (In_Tree.Sources);
639 Id := Source_Data_Table.Last (In_Tree.Sources);
641 if Current_Verbosity = High then
642 Write_Str ("Adding source #");
644 Write_Str (", File : ");
645 Write_Str (Get_Name_String (File_Name));
647 if Lang_Kind = Unit_Based then
648 Write_Str (", Unit : ");
649 Write_Str (Get_Name_String (Unit));
655 Src_Data.Project := Project;
656 Src_Data.Language_Name := Lang;
657 Src_Data.Language := Lang_Id;
658 Src_Data.Lang_Kind := Lang_Kind;
659 Src_Data.Compiled := In_Tree.Languages_Data.Table
660 (Lang_Id).Config.Compiler_Driver /=
662 Src_Data.Kind := Kind;
663 Src_Data.Alternate_Languages := Alternate_Languages;
664 Src_Data.Other_Part := Other_Part;
666 Src_Data.Object_Exists := Config.Object_Generated;
667 Src_Data.Object_Linked := Config.Objects_Linked;
669 if Other_Part /= No_Source then
670 In_Tree.Sources.Table (Other_Part).Other_Part := Id;
673 Src_Data.Unit := Unit;
674 Src_Data.Index := Index;
675 Src_Data.File := File_Name;
676 Src_Data.Display_File := Display_File;
677 Src_Data.Dependency := In_Tree.Languages_Data.Table
678 (Lang_Id).Config.Dependency_Kind;
679 Src_Data.Naming_Exception := Naming_Exception;
681 if Src_Data.Compiled then
682 Src_Data.Object := Object_Name (File_Name);
684 Dependency_Name (File_Name, Src_Data.Dependency);
685 Src_Data.Switches := Switches_Name (File_Name);
688 if Path /= No_Path then
689 Src_Data.Path := Path;
690 Src_Data.Display_Path := Display_Path;
691 Source_Paths_Htable.Set (In_Tree.Source_Paths_HT, Path, Id);
694 -- Add the source to the global list
696 Src_Data.Next_In_Sources := In_Tree.First_Source;
697 In_Tree.First_Source := Id;
699 -- Add the source to the project list
701 if Source = No_Source then
702 Data.First_Source := Id;
704 In_Tree.Sources.Table (Source).Next_In_Project := Id;
707 Data.Last_Source := Id;
709 -- Add the source to the language list
711 Src_Data.Next_In_Lang :=
712 In_Tree.Languages_Data.Table (Lang_Id).First_Source;
713 In_Tree.Languages_Data.Table (Lang_Id).First_Source := Id;
715 In_Tree.Sources.Table (Id) := Src_Data;
717 if Source_To_Replace /= No_Source then
718 Remove_Source (Source_To_Replace, Id, Project, Data, In_Tree);
726 function ALI_File_Name (Source : String) return String is
728 -- If the source name has an extension, then replace it with
731 for Index in reverse Source'First + 1 .. Source'Last loop
732 if Source (Index) = '.' then
733 return Source (Source'First .. Index - 1) & ALI_Suffix;
737 -- If there is no dot, or if it is the first character, just add the
740 return Source & ALI_Suffix;
748 (Project : Project_Id;
749 In_Tree : Project_Tree_Ref;
750 Report_Error : Put_Line_Access;
751 When_No_Sources : Error_Warning;
752 Current_Dir : String)
754 Data : Project_Data := In_Tree.Projects.Table (Project);
755 Extending : Boolean := False;
758 Nmsc.When_No_Sources := When_No_Sources;
759 Error_Report := Report_Error;
761 Recursive_Dirs.Reset;
763 Check_If_Externally_Built (Project, In_Tree, Data);
765 -- Object, exec and source directories
767 Get_Directories (Project, In_Tree, Current_Dir, Data);
769 -- Get the programming languages
771 Check_Programming_Languages (In_Tree, Project, Data);
773 if Data.Qualifier = Dry and then Data.Source_Dirs /= Nil_String then
776 "an abstract project need to have no language, no sources or no " &
777 "source directories",
781 -- Check configuration in multi language mode
783 if Must_Check_Configuration then
784 Check_Configuration (Project, In_Tree, Data);
787 -- Library attributes
789 Check_Library_Attributes (Project, In_Tree, Current_Dir, Data);
791 if Current_Verbosity = High then
792 Show_Source_Dirs (Data, In_Tree);
795 Check_Package_Naming (Project, In_Tree, Data);
797 Extending := Data.Extends /= No_Project;
799 Check_Naming_Schemes (Data, Project, In_Tree);
801 if Get_Mode = Ada_Only then
802 Prepare_Ada_Naming_Exceptions
803 (Data.Naming.Bodies, In_Tree, Body_Part);
804 Prepare_Ada_Naming_Exceptions
805 (Data.Naming.Specs, In_Tree, Specification);
810 if Data.Source_Dirs /= Nil_String then
811 Look_For_Sources (Project, In_Tree, Data, Current_Dir);
813 if Get_Mode = Ada_Only then
815 -- Check that all individual naming conventions apply to sources
816 -- of this project file.
819 (Project, In_Tree, Data.Naming.Bodies,
821 Extending => Extending);
823 (Project, In_Tree, Data.Naming.Specs,
825 Extending => Extending);
827 elsif Get_Mode = Multi_Language and then
828 (not Data.Externally_Built) and then
832 Language : Language_Index;
834 Src_Data : Source_Data;
835 Alt_Lang : Alternate_Language_Id;
836 Alt_Lang_Data : Alternate_Language_Data;
837 Continuation : Boolean := False;
840 Language := Data.First_Language_Processing;
841 while Language /= No_Language_Index loop
842 Source := Data.First_Source;
843 Source_Loop : while Source /= No_Source loop
844 Src_Data := In_Tree.Sources.Table (Source);
846 exit Source_Loop when Src_Data.Language = Language;
848 Alt_Lang := Src_Data.Alternate_Languages;
851 while Alt_Lang /= No_Alternate_Language loop
853 In_Tree.Alt_Langs.Table (Alt_Lang);
855 when Alt_Lang_Data.Language = Language;
856 Alt_Lang := Alt_Lang_Data.Next;
857 end loop Alternate_Loop;
859 Source := Src_Data.Next_In_Project;
860 end loop Source_Loop;
862 if Source = No_Source then
866 (In_Tree.Languages_Data.Table
867 (Language).Display_Name),
871 Continuation := True;
874 Language := In_Tree.Languages_Data.Table (Language).Next;
880 if Get_Mode = Multi_Language then
882 -- If a list of sources is specified in attribute Interfaces, set
883 -- In_Interfaces only for the sources specified in the list.
885 Check_Interfaces (Project, In_Tree, Data);
888 -- If it is a library project file, check if it is a standalone library
891 Check_Stand_Alone_Library
892 (Project, In_Tree, Data, Current_Dir, Extending);
895 -- Put the list of Mains, if any, in the project data
897 Get_Mains (Project, In_Tree, Data);
899 -- Update the project data in the Projects table
901 In_Tree.Projects.Table (Project) := Data;
903 Free_Ada_Naming_Exceptions;
910 procedure Check_Ada_Name (Name : String; Unit : out Name_Id) is
911 The_Name : String := Name;
913 Need_Letter : Boolean := True;
914 Last_Underscore : Boolean := False;
915 OK : Boolean := The_Name'Length > 0;
918 function Is_Reserved (Name : Name_Id) return Boolean;
919 function Is_Reserved (S : String) return Boolean;
920 -- Check that the given name is not an Ada 95 reserved word. The reason
921 -- for the Ada 95 here is that we do not want to exclude the case of an
922 -- Ada 95 unit called Interface (for example). In Ada 2005, such a unit
923 -- name would be rejected anyway by the compiler. That means there is no
924 -- requirement that the project file parser reject this.
930 function Is_Reserved (S : String) return Boolean is
933 Add_Str_To_Name_Buffer (S);
934 return Is_Reserved (Name_Find);
941 function Is_Reserved (Name : Name_Id) return Boolean is
943 if Get_Name_Table_Byte (Name) /= 0
944 and then Name /= Name_Project
945 and then Name /= Name_Extends
946 and then Name /= Name_External
947 and then Name not in Ada_2005_Reserved_Words
951 if Current_Verbosity = High then
952 Write_Str (The_Name);
953 Write_Line (" is an Ada reserved word.");
963 -- Start of processing for Check_Ada_Name
968 Name_Len := The_Name'Length;
969 Name_Buffer (1 .. Name_Len) := The_Name;
971 -- Special cases of children of packages A, G, I and S on VMS
974 and then Name_Len > 3
975 and then Name_Buffer (2 .. 3) = "__"
977 ((Name_Buffer (1) = 'a') or else
978 (Name_Buffer (1) = 'g') or else
979 (Name_Buffer (1) = 'i') or else
980 (Name_Buffer (1) = 's'))
982 Name_Buffer (2) := '.';
983 Name_Buffer (3 .. Name_Len - 1) := Name_Buffer (4 .. Name_Len);
984 Name_Len := Name_Len - 1;
987 Real_Name := Name_Find;
989 if Is_Reserved (Real_Name) then
993 First := The_Name'First;
995 for Index in The_Name'Range loop
998 -- We need a letter (at the beginning, and following a dot),
999 -- but we don't have one.
1001 if Is_Letter (The_Name (Index)) then
1002 Need_Letter := False;
1007 if Current_Verbosity = High then
1008 Write_Int (Types.Int (Index));
1010 Write_Char (The_Name (Index));
1011 Write_Line ("' is not a letter.");
1017 elsif Last_Underscore
1018 and then (The_Name (Index) = '_' or else The_Name (Index) = '.')
1020 -- Two underscores are illegal, and a dot cannot follow
1025 if Current_Verbosity = High then
1026 Write_Int (Types.Int (Index));
1028 Write_Char (The_Name (Index));
1029 Write_Line ("' is illegal here.");
1034 elsif The_Name (Index) = '.' then
1036 -- First, check if the name before the dot is not a reserved word
1037 if Is_Reserved (The_Name (First .. Index - 1)) then
1043 -- We need a letter after a dot
1045 Need_Letter := True;
1047 elsif The_Name (Index) = '_' then
1048 Last_Underscore := True;
1051 -- We need an letter or a digit
1053 Last_Underscore := False;
1055 if not Is_Alphanumeric (The_Name (Index)) then
1058 if Current_Verbosity = High then
1059 Write_Int (Types.Int (Index));
1061 Write_Char (The_Name (Index));
1062 Write_Line ("' is not alphanumeric.");
1070 -- Cannot end with an underscore or a dot
1072 OK := OK and then not Need_Letter and then not Last_Underscore;
1075 if First /= Name'First and then
1076 Is_Reserved (The_Name (First .. The_Name'Last))
1084 -- Signal a problem with No_Name
1090 --------------------------------------
1091 -- Check_Ada_Naming_Scheme_Validity --
1092 --------------------------------------
1094 procedure Check_Ada_Naming_Scheme_Validity
1095 (Project : Project_Id;
1096 In_Tree : Project_Tree_Ref;
1097 Naming : Naming_Data)
1100 -- Only check if we are not using the Default naming scheme
1102 if Naming /= In_Tree.Private_Part.Default_Naming then
1104 Dot_Replacement : constant String :=
1106 (Naming.Dot_Replacement);
1108 Spec_Suffix : constant String :=
1109 Spec_Suffix_Of (In_Tree, "ada", Naming);
1111 Body_Suffix : constant String :=
1112 Body_Suffix_Of (In_Tree, "ada", Naming);
1114 Separate_Suffix : constant String :=
1116 (Naming.Separate_Suffix);
1119 -- Dot_Replacement cannot
1122 -- - start or end with an alphanumeric
1123 -- - be a single '_'
1124 -- - start with an '_' followed by an alphanumeric
1125 -- - contain a '.' except if it is "."
1127 if Dot_Replacement'Length = 0
1128 or else Is_Alphanumeric
1129 (Dot_Replacement (Dot_Replacement'First))
1130 or else Is_Alphanumeric
1131 (Dot_Replacement (Dot_Replacement'Last))
1132 or else (Dot_Replacement (Dot_Replacement'First) = '_'
1134 (Dot_Replacement'Length = 1
1137 (Dot_Replacement (Dot_Replacement'First + 1))))
1138 or else (Dot_Replacement'Length > 1
1140 Index (Source => Dot_Replacement,
1141 Pattern => ".") /= 0)
1145 '"' & Dot_Replacement &
1146 """ is illegal for Dot_Replacement.",
1147 Naming.Dot_Repl_Loc);
1153 if Is_Illegal_Suffix
1154 (Spec_Suffix, Dot_Replacement = ".")
1156 Err_Vars.Error_Msg_File_1 :=
1157 Spec_Suffix_Id_Of (In_Tree, Name_Ada, Naming);
1160 "{ is illegal for Spec_Suffix",
1161 Naming.Ada_Spec_Suffix_Loc);
1164 if Is_Illegal_Suffix
1165 (Body_Suffix, Dot_Replacement = ".")
1167 Err_Vars.Error_Msg_File_1 :=
1168 Body_Suffix_Id_Of (In_Tree, Name_Ada, Naming);
1171 "{ is illegal for Body_Suffix",
1172 Naming.Ada_Body_Suffix_Loc);
1175 if Body_Suffix /= Separate_Suffix then
1176 if Is_Illegal_Suffix
1177 (Separate_Suffix, Dot_Replacement = ".")
1179 Err_Vars.Error_Msg_File_1 := Naming.Separate_Suffix;
1182 "{ is illegal for Separate_Suffix",
1183 Naming.Sep_Suffix_Loc);
1187 -- Spec_Suffix cannot be equal to Body_Suffix Separate_Suffix,
1188 -- since that would cause a clear ambiguity. Note that we do
1189 -- allow a Spec_Suffix to have the same termination as one of
1190 -- these, which causes a potential ambiguity, but we resolve
1191 -- that my matching the longest possible suffix.
1193 if Spec_Suffix = Body_Suffix then
1198 """) cannot be the same as Spec_Suffix.",
1199 Naming.Ada_Body_Suffix_Loc);
1202 if Body_Suffix /= Separate_Suffix
1203 and then Spec_Suffix = Separate_Suffix
1207 "Separate_Suffix (""" &
1209 """) cannot be the same as Spec_Suffix.",
1210 Naming.Sep_Suffix_Loc);
1214 end Check_Ada_Naming_Scheme_Validity;
1216 -------------------------
1217 -- Check_Configuration --
1218 -------------------------
1220 procedure Check_Configuration
1221 (Project : Project_Id;
1222 In_Tree : Project_Tree_Ref;
1223 Data : in out Project_Data)
1225 Dot_Replacement : File_Name_Type := No_File;
1226 Casing : Casing_Type := All_Lower_Case;
1227 Separate_Suffix : File_Name_Type := No_File;
1229 Lang_Index : Language_Index := No_Language_Index;
1230 -- The index of the language data being checked
1232 Prev_Index : Language_Index := No_Language_Index;
1233 -- The index of the previous language
1235 Current_Language : Name_Id := No_Name;
1236 -- The name of the language
1238 Lang_Data : Language_Data;
1239 -- The data of the language being checked
1241 procedure Get_Language_Index_Of (Language : Name_Id);
1242 -- Get the language index of Language, if Language is one of the
1243 -- languages of the project.
1245 procedure Process_Project_Level_Simple_Attributes;
1246 -- Process the simple attributes at the project level
1248 procedure Process_Project_Level_Array_Attributes;
1249 -- Process the associate array attributes at the project level
1251 procedure Process_Packages;
1252 -- Read the packages of the project
1254 ---------------------------
1255 -- Get_Language_Index_Of --
1256 ---------------------------
1258 procedure Get_Language_Index_Of (Language : Name_Id) is
1259 Real_Language : Name_Id;
1262 Get_Name_String (Language);
1263 To_Lower (Name_Buffer (1 .. Name_Len));
1264 Real_Language := Name_Find;
1266 -- Nothing to do if the language is the same as the current language
1268 if Current_Language /= Real_Language then
1269 Lang_Index := Data.First_Language_Processing;
1270 while Lang_Index /= No_Language_Index loop
1271 exit when In_Tree.Languages_Data.Table (Lang_Index).Name =
1274 In_Tree.Languages_Data.Table (Lang_Index).Next;
1277 if Lang_Index = No_Language_Index then
1278 Current_Language := No_Name;
1280 Current_Language := Real_Language;
1283 end Get_Language_Index_Of;
1285 ----------------------
1286 -- Process_Packages --
1287 ----------------------
1289 procedure Process_Packages is
1290 Packages : Package_Id;
1291 Element : Package_Element;
1293 procedure Process_Binder (Arrays : Array_Id);
1294 -- Process the associate array attributes of package Binder
1296 procedure Process_Builder (Attributes : Variable_Id);
1297 -- Process the simple attributes of package Builder
1299 procedure Process_Compiler (Arrays : Array_Id);
1300 -- Process the associate array attributes of package Compiler
1302 procedure Process_Naming (Attributes : Variable_Id);
1303 -- Process the simple attributes of package Naming
1305 procedure Process_Naming (Arrays : Array_Id);
1306 -- Process the associate array attributes of package Naming
1308 procedure Process_Linker (Attributes : Variable_Id);
1309 -- Process the simple attributes of package Linker of a
1310 -- configuration project.
1312 --------------------
1313 -- Process_Binder --
1314 --------------------
1316 procedure Process_Binder (Arrays : Array_Id) is
1317 Current_Array_Id : Array_Id;
1318 Current_Array : Array_Data;
1319 Element_Id : Array_Element_Id;
1320 Element : Array_Element;
1323 -- Process the associative array attribute of package Binder
1325 Current_Array_Id := Arrays;
1326 while Current_Array_Id /= No_Array loop
1327 Current_Array := In_Tree.Arrays.Table (Current_Array_Id);
1329 Element_Id := Current_Array.Value;
1330 while Element_Id /= No_Array_Element loop
1331 Element := In_Tree.Array_Elements.Table (Element_Id);
1333 -- Get the name of the language
1335 Get_Language_Index_Of (Element.Index);
1337 if Lang_Index /= No_Language_Index then
1338 case Current_Array.Name is
1341 -- Attribute Driver (<language>)
1343 In_Tree.Languages_Data.Table
1344 (Lang_Index).Config.Binder_Driver :=
1345 File_Name_Type (Element.Value.Value);
1347 when Name_Required_Switches =>
1349 In_Tree.Languages_Data.Table
1350 (Lang_Index).Config.Binder_Required_Switches,
1351 From_List => Element.Value.Values,
1352 In_Tree => In_Tree);
1356 -- Attribute Prefix (<language>)
1358 In_Tree.Languages_Data.Table
1359 (Lang_Index).Config.Binder_Prefix :=
1360 Element.Value.Value;
1362 when Name_Objects_Path =>
1364 -- Attribute Objects_Path (<language>)
1366 In_Tree.Languages_Data.Table
1367 (Lang_Index).Config.Objects_Path :=
1368 Element.Value.Value;
1370 when Name_Objects_Path_File =>
1372 -- Attribute Objects_Path (<language>)
1374 In_Tree.Languages_Data.Table
1375 (Lang_Index).Config.Objects_Path_File :=
1376 Element.Value.Value;
1383 Element_Id := Element.Next;
1386 Current_Array_Id := Current_Array.Next;
1390 ---------------------
1391 -- Process_Builder --
1392 ---------------------
1394 procedure Process_Builder (Attributes : Variable_Id) is
1395 Attribute_Id : Variable_Id;
1396 Attribute : Variable;
1399 -- Process non associated array attribute from package Builder
1401 Attribute_Id := Attributes;
1402 while Attribute_Id /= No_Variable loop
1404 In_Tree.Variable_Elements.Table (Attribute_Id);
1406 if not Attribute.Value.Default then
1407 if Attribute.Name = Name_Executable_Suffix then
1409 -- Attribute Executable_Suffix: the suffix of the
1412 Data.Config.Executable_Suffix :=
1413 Attribute.Value.Value;
1417 Attribute_Id := Attribute.Next;
1419 end Process_Builder;
1421 ----------------------
1422 -- Process_Compiler --
1423 ----------------------
1425 procedure Process_Compiler (Arrays : Array_Id) is
1426 Current_Array_Id : Array_Id;
1427 Current_Array : Array_Data;
1428 Element_Id : Array_Element_Id;
1429 Element : Array_Element;
1430 List : String_List_Id;
1433 -- Process the associative array attribute of package Compiler
1435 Current_Array_Id := Arrays;
1436 while Current_Array_Id /= No_Array loop
1437 Current_Array := In_Tree.Arrays.Table (Current_Array_Id);
1439 Element_Id := Current_Array.Value;
1440 while Element_Id /= No_Array_Element loop
1441 Element := In_Tree.Array_Elements.Table (Element_Id);
1443 -- Get the name of the language
1445 Get_Language_Index_Of (Element.Index);
1447 if Lang_Index /= No_Language_Index then
1448 case Current_Array.Name is
1449 when Name_Dependency_Switches =>
1451 -- Attribute Dependency_Switches (<language>)
1453 if In_Tree.Languages_Data.Table
1454 (Lang_Index).Config.Dependency_Kind = None
1456 In_Tree.Languages_Data.Table
1457 (Lang_Index).Config.Dependency_Kind :=
1461 List := Element.Value.Values;
1463 if List /= Nil_String then
1465 In_Tree.Languages_Data.Table
1466 (Lang_Index).Config.Dependency_Option,
1468 In_Tree => In_Tree);
1471 when Name_Dependency_Driver =>
1473 -- Attribute Dependency_Driver (<language>)
1475 if In_Tree.Languages_Data.Table
1476 (Lang_Index).Config.Dependency_Kind = None
1478 In_Tree.Languages_Data.Table
1479 (Lang_Index).Config.Dependency_Kind :=
1483 List := Element.Value.Values;
1485 if List /= Nil_String then
1487 In_Tree.Languages_Data.Table
1488 (Lang_Index).Config.Compute_Dependency,
1490 In_Tree => In_Tree);
1493 when Name_Include_Switches =>
1495 -- Attribute Include_Switches (<language>)
1497 List := Element.Value.Values;
1499 if List = Nil_String then
1503 "include option cannot be null",
1504 Element.Value.Location);
1508 In_Tree.Languages_Data.Table
1509 (Lang_Index).Config.Include_Option,
1511 In_Tree => In_Tree);
1513 when Name_Include_Path =>
1515 -- Attribute Include_Path (<language>)
1517 In_Tree.Languages_Data.Table
1518 (Lang_Index).Config.Include_Path :=
1519 Element.Value.Value;
1521 when Name_Include_Path_File =>
1523 -- Attribute Include_Path_File (<language>)
1525 In_Tree.Languages_Data.Table
1526 (Lang_Index).Config.Include_Path_File :=
1527 Element.Value.Value;
1531 -- Attribute Driver (<language>)
1533 Get_Name_String (Element.Value.Value);
1535 In_Tree.Languages_Data.Table
1536 (Lang_Index).Config.Compiler_Driver :=
1537 File_Name_Type (Element.Value.Value);
1539 when Name_Required_Switches =>
1541 In_Tree.Languages_Data.Table
1542 (Lang_Index).Config.
1543 Compiler_Required_Switches,
1544 From_List => Element.Value.Values,
1545 In_Tree => In_Tree);
1547 when Name_Pic_Option =>
1549 -- Attribute Compiler_Pic_Option (<language>)
1551 List := Element.Value.Values;
1553 if List = Nil_String then
1557 "compiler PIC option cannot be null",
1558 Element.Value.Location);
1562 In_Tree.Languages_Data.Table
1563 (Lang_Index).Config.Compilation_PIC_Option,
1565 In_Tree => In_Tree);
1567 when Name_Mapping_File_Switches =>
1569 -- Attribute Mapping_File_Switches (<language>)
1571 List := Element.Value.Values;
1573 if List = Nil_String then
1577 "mapping file switches cannot be null",
1578 Element.Value.Location);
1582 In_Tree.Languages_Data.Table
1583 (Lang_Index).Config.Mapping_File_Switches,
1585 In_Tree => In_Tree);
1587 when Name_Mapping_Spec_Suffix =>
1589 -- Attribute Mapping_Spec_Suffix (<language>)
1591 In_Tree.Languages_Data.Table
1592 (Lang_Index).Config.Mapping_Spec_Suffix :=
1593 File_Name_Type (Element.Value.Value);
1595 when Name_Mapping_Body_Suffix =>
1597 -- Attribute Mapping_Body_Suffix (<language>)
1599 In_Tree.Languages_Data.Table
1600 (Lang_Index).Config.Mapping_Body_Suffix :=
1601 File_Name_Type (Element.Value.Value);
1603 when Name_Config_File_Switches =>
1605 -- Attribute Config_File_Switches (<language>)
1607 List := Element.Value.Values;
1609 if List = Nil_String then
1613 "config file switches cannot be null",
1614 Element.Value.Location);
1618 In_Tree.Languages_Data.Table
1619 (Lang_Index).Config.Config_File_Switches,
1621 In_Tree => In_Tree);
1623 when Name_Objects_Path =>
1625 -- Attribute Objects_Path (<language>)
1627 In_Tree.Languages_Data.Table
1628 (Lang_Index).Config.Objects_Path :=
1629 Element.Value.Value;
1631 when Name_Objects_Path_File =>
1633 -- Attribute Objects_Path_File (<language>)
1635 In_Tree.Languages_Data.Table
1636 (Lang_Index).Config.Objects_Path_File :=
1637 Element.Value.Value;
1639 when Name_Config_Body_File_Name =>
1641 -- Attribute Config_Body_File_Name (<language>)
1643 In_Tree.Languages_Data.Table
1644 (Lang_Index).Config.Config_Body :=
1645 Element.Value.Value;
1647 when Name_Config_Body_File_Name_Pattern =>
1649 -- Attribute Config_Body_File_Name_Pattern
1652 In_Tree.Languages_Data.Table
1653 (Lang_Index).Config.Config_Body_Pattern :=
1654 Element.Value.Value;
1656 when Name_Config_Spec_File_Name =>
1658 -- Attribute Config_Spec_File_Name (<language>)
1660 In_Tree.Languages_Data.Table
1661 (Lang_Index).Config.Config_Spec :=
1662 Element.Value.Value;
1664 when Name_Config_Spec_File_Name_Pattern =>
1666 -- Attribute Config_Spec_File_Name_Pattern
1669 In_Tree.Languages_Data.Table
1670 (Lang_Index).Config.Config_Spec_Pattern :=
1671 Element.Value.Value;
1673 when Name_Config_File_Unique =>
1675 -- Attribute Config_File_Unique (<language>)
1678 In_Tree.Languages_Data.Table
1679 (Lang_Index).Config.Config_File_Unique :=
1681 (Get_Name_String (Element.Value.Value));
1683 when Constraint_Error =>
1687 "illegal value for Config_File_Unique",
1688 Element.Value.Location);
1696 Element_Id := Element.Next;
1699 Current_Array_Id := Current_Array.Next;
1701 end Process_Compiler;
1703 --------------------
1704 -- Process_Naming --
1705 --------------------
1707 procedure Process_Naming (Attributes : Variable_Id) is
1708 Attribute_Id : Variable_Id;
1709 Attribute : Variable;
1712 -- Process non associated array attribute from package Naming
1714 Attribute_Id := Attributes;
1715 while Attribute_Id /= No_Variable loop
1717 In_Tree.Variable_Elements.Table (Attribute_Id);
1719 if not Attribute.Value.Default then
1720 if Attribute.Name = Name_Separate_Suffix then
1722 -- Attribute Separate_Suffix
1724 Separate_Suffix := File_Name_Type (Attribute.Value.Value);
1726 elsif Attribute.Name = Name_Casing then
1732 Value (Get_Name_String (Attribute.Value.Value));
1735 when Constraint_Error =>
1739 "invalid value for Casing",
1740 Attribute.Value.Location);
1743 elsif Attribute.Name = Name_Dot_Replacement then
1745 -- Attribute Dot_Replacement
1747 Dot_Replacement := File_Name_Type (Attribute.Value.Value);
1752 Attribute_Id := Attribute.Next;
1756 procedure Process_Naming (Arrays : Array_Id) is
1757 Current_Array_Id : Array_Id;
1758 Current_Array : Array_Data;
1759 Element_Id : Array_Element_Id;
1760 Element : Array_Element;
1762 -- Process the associative array attribute of package Naming
1764 Current_Array_Id := Arrays;
1765 while Current_Array_Id /= No_Array loop
1766 Current_Array := In_Tree.Arrays.Table (Current_Array_Id);
1768 Element_Id := Current_Array.Value;
1769 while Element_Id /= No_Array_Element loop
1770 Element := In_Tree.Array_Elements.Table (Element_Id);
1772 -- Get the name of the language
1774 Get_Language_Index_Of (Element.Index);
1776 if Lang_Index /= No_Language_Index then
1777 case Current_Array.Name is
1778 when Name_Specification_Suffix | Name_Spec_Suffix =>
1780 -- Attribute Spec_Suffix (<language>)
1782 In_Tree.Languages_Data.Table
1783 (Lang_Index).Config.Naming_Data.Spec_Suffix :=
1784 File_Name_Type (Element.Value.Value);
1786 when Name_Implementation_Suffix | Name_Body_Suffix =>
1788 -- Attribute Body_Suffix (<language>)
1790 In_Tree.Languages_Data.Table
1791 (Lang_Index).Config.Naming_Data.Body_Suffix :=
1792 File_Name_Type (Element.Value.Value);
1794 In_Tree.Languages_Data.Table
1795 (Lang_Index).Config.Naming_Data.Separate_Suffix :=
1796 File_Name_Type (Element.Value.Value);
1803 Element_Id := Element.Next;
1806 Current_Array_Id := Current_Array.Next;
1810 --------------------
1811 -- Process_Linker --
1812 --------------------
1814 procedure Process_Linker (Attributes : Variable_Id) is
1815 Attribute_Id : Variable_Id;
1816 Attribute : Variable;
1819 -- Process non associated array attribute from package Linker
1821 Attribute_Id := Attributes;
1822 while Attribute_Id /= No_Variable loop
1824 In_Tree.Variable_Elements.Table (Attribute_Id);
1826 if not Attribute.Value.Default then
1827 if Attribute.Name = Name_Driver then
1829 -- Attribute Linker'Driver: the default linker to use
1831 Data.Config.Linker :=
1832 Path_Name_Type (Attribute.Value.Value);
1835 Attribute.Name = Name_Required_Switches
1838 -- Attribute Required_Switches: the minimum
1839 -- options to use when invoking the linker
1842 Data.Config.Minimum_Linker_Options,
1843 From_List => Attribute.Value.Values,
1844 In_Tree => In_Tree);
1849 Attribute_Id := Attribute.Next;
1853 -- Start of processing for Process_Packages
1856 Packages := Data.Decl.Packages;
1857 while Packages /= No_Package loop
1858 Element := In_Tree.Packages.Table (Packages);
1860 case Element.Name is
1863 -- Process attributes of package Binder
1865 Process_Binder (Element.Decl.Arrays);
1867 when Name_Builder =>
1869 -- Process attributes of package Builder
1871 Process_Builder (Element.Decl.Attributes);
1873 when Name_Compiler =>
1875 -- Process attributes of package Compiler
1877 Process_Compiler (Element.Decl.Arrays);
1881 -- Process attributes of package Linker
1883 Process_Linker (Element.Decl.Attributes);
1887 -- Process attributes of package Naming
1889 Process_Naming (Element.Decl.Attributes);
1890 Process_Naming (Element.Decl.Arrays);
1896 Packages := Element.Next;
1898 end Process_Packages;
1900 ---------------------------------------------
1901 -- Process_Project_Level_Simple_Attributes --
1902 ---------------------------------------------
1904 procedure Process_Project_Level_Simple_Attributes is
1905 Attribute_Id : Variable_Id;
1906 Attribute : Variable;
1907 List : String_List_Id;
1910 -- Process non associated array attribute at project level
1912 Attribute_Id := Data.Decl.Attributes;
1913 while Attribute_Id /= No_Variable loop
1915 In_Tree.Variable_Elements.Table (Attribute_Id);
1917 if not Attribute.Value.Default then
1918 if Attribute.Name = Name_Library_Builder then
1920 -- Attribute Library_Builder: the application to invoke
1921 -- to build libraries.
1923 Data.Config.Library_Builder :=
1924 Path_Name_Type (Attribute.Value.Value);
1926 elsif Attribute.Name = Name_Archive_Builder then
1928 -- Attribute Archive_Builder: the archive builder
1929 -- (usually "ar") and its minimum options (usually "cr").
1931 List := Attribute.Value.Values;
1933 if List = Nil_String then
1937 "archive builder cannot be null",
1938 Attribute.Value.Location);
1941 Put (Into_List => Data.Config.Archive_Builder,
1943 In_Tree => In_Tree);
1945 elsif Attribute.Name = Name_Archive_Builder_Append_Option then
1947 -- Attribute Archive_Builder: the archive builder
1948 -- (usually "ar") and its minimum options (usually "cr").
1950 List := Attribute.Value.Values;
1952 if List /= Nil_String then
1954 (Into_List => Data.Config.Archive_Builder_Append_Option,
1956 In_Tree => In_Tree);
1959 elsif Attribute.Name = Name_Archive_Indexer then
1961 -- Attribute Archive_Indexer: the optional archive
1962 -- indexer (usually "ranlib") with its minimum options
1965 List := Attribute.Value.Values;
1967 if List = Nil_String then
1971 "archive indexer cannot be null",
1972 Attribute.Value.Location);
1975 Put (Into_List => Data.Config.Archive_Indexer,
1977 In_Tree => In_Tree);
1979 elsif Attribute.Name = Name_Library_Partial_Linker then
1981 -- Attribute Library_Partial_Linker: the optional linker
1982 -- driver with its minimum options, to partially link
1985 List := Attribute.Value.Values;
1987 if List = Nil_String then
1991 "partial linker cannot be null",
1992 Attribute.Value.Location);
1995 Put (Into_List => Data.Config.Lib_Partial_Linker,
1997 In_Tree => In_Tree);
1999 elsif Attribute.Name = Name_Archive_Suffix then
2000 Data.Config.Archive_Suffix :=
2001 File_Name_Type (Attribute.Value.Value);
2003 elsif Attribute.Name = Name_Linker_Executable_Option then
2005 -- Attribute Linker_Executable_Option: optional options
2006 -- to specify an executable name. Defaults to "-o".
2008 List := Attribute.Value.Values;
2010 if List = Nil_String then
2014 "linker executable option cannot be null",
2015 Attribute.Value.Location);
2018 Put (Into_List => Data.Config.Linker_Executable_Option,
2020 In_Tree => In_Tree);
2022 elsif Attribute.Name = Name_Linker_Lib_Dir_Option then
2024 -- Attribute Linker_Lib_Dir_Option: optional options
2025 -- to specify a library search directory. Defaults to
2028 Get_Name_String (Attribute.Value.Value);
2030 if Name_Len = 0 then
2034 "linker library directory option cannot be empty",
2035 Attribute.Value.Location);
2038 Data.Config.Linker_Lib_Dir_Option := Attribute.Value.Value;
2040 elsif Attribute.Name = Name_Linker_Lib_Name_Option then
2042 -- Attribute Linker_Lib_Name_Option: optional options
2043 -- to specify the name of a library to be linked in.
2044 -- Defaults to "-l".
2046 Get_Name_String (Attribute.Value.Value);
2048 if Name_Len = 0 then
2052 "linker library name option cannot be empty",
2053 Attribute.Value.Location);
2056 Data.Config.Linker_Lib_Name_Option := Attribute.Value.Value;
2058 elsif Attribute.Name = Name_Run_Path_Option then
2060 -- Attribute Run_Path_Option: optional options to
2061 -- specify a path for libraries.
2063 List := Attribute.Value.Values;
2065 if List /= Nil_String then
2066 Put (Into_List => Data.Config.Run_Path_Option,
2068 In_Tree => In_Tree);
2071 elsif Attribute.Name = Name_Library_Support then
2073 pragma Unsuppress (All_Checks);
2075 Data.Config.Lib_Support :=
2076 Library_Support'Value (Get_Name_String
2077 (Attribute.Value.Value));
2079 when Constraint_Error =>
2083 "invalid value """ &
2084 Get_Name_String (Attribute.Value.Value) &
2085 """ for Library_Support",
2086 Attribute.Value.Location);
2089 elsif Attribute.Name = Name_Shared_Library_Prefix then
2090 Data.Config.Shared_Lib_Prefix :=
2091 File_Name_Type (Attribute.Value.Value);
2093 elsif Attribute.Name = Name_Shared_Library_Suffix then
2094 Data.Config.Shared_Lib_Suffix :=
2095 File_Name_Type (Attribute.Value.Value);
2097 elsif Attribute.Name = Name_Symbolic_Link_Supported then
2099 pragma Unsuppress (All_Checks);
2101 Data.Config.Symbolic_Link_Supported :=
2102 Boolean'Value (Get_Name_String
2103 (Attribute.Value.Value));
2105 when Constraint_Error =>
2110 & Get_Name_String (Attribute.Value.Value)
2111 & """ for Symbolic_Link_Supported",
2112 Attribute.Value.Location);
2116 Attribute.Name = Name_Library_Major_Minor_Id_Supported
2119 pragma Unsuppress (All_Checks);
2121 Data.Config.Lib_Maj_Min_Id_Supported :=
2122 Boolean'Value (Get_Name_String
2123 (Attribute.Value.Value));
2125 when Constraint_Error =>
2129 "invalid value """ &
2130 Get_Name_String (Attribute.Value.Value) &
2131 """ for Library_Major_Minor_Id_Supported",
2132 Attribute.Value.Location);
2135 elsif Attribute.Name = Name_Library_Auto_Init_Supported then
2137 pragma Unsuppress (All_Checks);
2139 Data.Config.Auto_Init_Supported :=
2140 Boolean'Value (Get_Name_String (Attribute.Value.Value));
2142 when Constraint_Error =>
2147 & Get_Name_String (Attribute.Value.Value)
2148 & """ for Library_Auto_Init_Supported",
2149 Attribute.Value.Location);
2152 elsif Attribute.Name = Name_Shared_Library_Minimum_Switches then
2153 List := Attribute.Value.Values;
2155 if List /= Nil_String then
2156 Put (Into_List => Data.Config.Shared_Lib_Min_Options,
2158 In_Tree => In_Tree);
2161 elsif Attribute.Name = Name_Library_Version_Switches then
2162 List := Attribute.Value.Values;
2164 if List /= Nil_String then
2165 Put (Into_List => Data.Config.Lib_Version_Options,
2167 In_Tree => In_Tree);
2172 Attribute_Id := Attribute.Next;
2174 end Process_Project_Level_Simple_Attributes;
2176 --------------------------------------------
2177 -- Process_Project_Level_Array_Attributes --
2178 --------------------------------------------
2180 procedure Process_Project_Level_Array_Attributes is
2181 Current_Array_Id : Array_Id;
2182 Current_Array : Array_Data;
2183 Element_Id : Array_Element_Id;
2184 Element : Array_Element;
2185 List : String_List_Id;
2188 -- Process the associative array attributes at project level
2190 Current_Array_Id := Data.Decl.Arrays;
2191 while Current_Array_Id /= No_Array loop
2192 Current_Array := In_Tree.Arrays.Table (Current_Array_Id);
2194 Element_Id := Current_Array.Value;
2195 while Element_Id /= No_Array_Element loop
2196 Element := In_Tree.Array_Elements.Table (Element_Id);
2198 -- Get the name of the language
2200 Get_Language_Index_Of (Element.Index);
2202 if Lang_Index /= No_Language_Index then
2203 case Current_Array.Name is
2204 when Name_Inherit_Source_Path =>
2205 List := Element.Value.Values;
2207 if List /= Nil_String then
2210 In_Tree.Languages_Data.Table (Lang_Index).
2211 Config.Include_Compatible_Languages,
2214 Lower_Case => True);
2217 when Name_Toolchain_Description =>
2219 -- Attribute Toolchain_Description (<language>)
2221 In_Tree.Languages_Data.Table
2222 (Lang_Index).Config.Toolchain_Description :=
2223 Element.Value.Value;
2225 when Name_Toolchain_Version =>
2227 -- Attribute Toolchain_Version (<language>)
2229 In_Tree.Languages_Data.Table
2230 (Lang_Index).Config.Toolchain_Version :=
2231 Element.Value.Value;
2233 when Name_Runtime_Library_Dir =>
2235 -- Attribute Runtime_Library_Dir (<language>)
2237 In_Tree.Languages_Data.Table
2238 (Lang_Index).Config.Runtime_Library_Dir :=
2239 Element.Value.Value;
2241 when Name_Object_Generated =>
2243 pragma Unsuppress (All_Checks);
2249 (Get_Name_String (Element.Value.Value));
2251 In_Tree.Languages_Data.Table
2252 (Lang_Index).Config.Object_Generated := Value;
2254 -- If no object is generated, no object may be
2258 In_Tree.Languages_Data.Table
2259 (Lang_Index).Config.Objects_Linked := False;
2263 when Constraint_Error =>
2268 & Get_Name_String (Element.Value.Value)
2269 & """ for Object_Generated",
2270 Element.Value.Location);
2273 when Name_Objects_Linked =>
2275 pragma Unsuppress (All_Checks);
2281 (Get_Name_String (Element.Value.Value));
2283 -- No change if Object_Generated is False, as this
2284 -- forces Objects_Linked to be False too.
2286 if In_Tree.Languages_Data.Table
2287 (Lang_Index).Config.Object_Generated
2289 In_Tree.Languages_Data.Table
2290 (Lang_Index).Config.Objects_Linked :=
2295 when Constraint_Error =>
2300 & Get_Name_String (Element.Value.Value)
2301 & """ for Objects_Linked",
2302 Element.Value.Location);
2309 Element_Id := Element.Next;
2312 Current_Array_Id := Current_Array.Next;
2314 end Process_Project_Level_Array_Attributes;
2317 Process_Project_Level_Simple_Attributes;
2318 Process_Project_Level_Array_Attributes;
2321 -- For unit based languages, set Casing, Dot_Replacement and
2322 -- Separate_Suffix in Naming_Data.
2324 Lang_Index := Data.First_Language_Processing;
2325 while Lang_Index /= No_Language_Index loop
2326 if In_Tree.Languages_Data.Table
2327 (Lang_Index).Name = Name_Ada
2329 In_Tree.Languages_Data.Table
2330 (Lang_Index).Config.Naming_Data.Casing := Casing;
2331 In_Tree.Languages_Data.Table
2332 (Lang_Index).Config.Naming_Data.Dot_Replacement :=
2335 if Separate_Suffix /= No_File then
2336 In_Tree.Languages_Data.Table
2337 (Lang_Index).Config.Naming_Data.Separate_Suffix :=
2344 Lang_Index := In_Tree.Languages_Data.Table (Lang_Index).Next;
2347 -- Give empty names to various prefixes/suffixes, if they have not
2348 -- been specified in the configuration.
2350 if Data.Config.Archive_Suffix = No_File then
2351 Data.Config.Archive_Suffix := Empty_File;
2354 if Data.Config.Shared_Lib_Prefix = No_File then
2355 Data.Config.Shared_Lib_Prefix := Empty_File;
2358 if Data.Config.Shared_Lib_Suffix = No_File then
2359 Data.Config.Shared_Lib_Suffix := Empty_File;
2362 Lang_Index := Data.First_Language_Processing;
2363 while Lang_Index /= No_Language_Index loop
2364 Lang_Data := In_Tree.Languages_Data.Table (Lang_Index);
2366 Current_Language := Lang_Data.Display_Name;
2368 -- For all languages, Compiler_Driver needs to be specified
2370 if Lang_Data.Config.Compiler_Driver = No_File then
2371 Error_Msg_Name_1 := Current_Language;
2375 "?no compiler specified for language %%" &
2376 ", ignoring all its sources",
2379 if Lang_Index = Data.First_Language_Processing then
2380 Data.First_Language_Processing :=
2383 In_Tree.Languages_Data.Table (Prev_Index).Next :=
2387 elsif Lang_Data.Name = Name_Ada then
2388 Prev_Index := Lang_Index;
2390 -- For unit based languages, Dot_Replacement, Spec_Suffix and
2391 -- Body_Suffix need to be specified.
2393 if Lang_Data.Config.Naming_Data.Dot_Replacement = No_File then
2397 "Dot_Replacement not specified for Ada",
2401 if Lang_Data.Config.Naming_Data.Spec_Suffix = No_File then
2405 "Spec_Suffix not specified for Ada",
2409 if Lang_Data.Config.Naming_Data.Body_Suffix = No_File then
2413 "Body_Suffix not specified for Ada",
2418 Prev_Index := Lang_Index;
2420 -- For file based languages, either Spec_Suffix or Body_Suffix
2421 -- need to be specified.
2423 if Lang_Data.Config.Naming_Data.Spec_Suffix = No_File and then
2424 Lang_Data.Config.Naming_Data.Body_Suffix = No_File
2426 Error_Msg_Name_1 := Current_Language;
2430 "no suffixes specified for %%",
2435 Lang_Index := Lang_Data.Next;
2437 end Check_Configuration;
2439 ----------------------
2440 -- Check_For_Source --
2441 ----------------------
2443 procedure Check_For_Source
2444 (File_Name : File_Name_Type;
2445 Path_Name : Path_Name_Type;
2446 Project : Project_Id;
2447 In_Tree : Project_Tree_Ref;
2448 Data : in out Project_Data;
2449 Location : Source_Ptr;
2450 Language : Language_Index;
2452 Naming_Exception : Boolean)
2454 Name : String := Get_Name_String (File_Name);
2455 Real_Location : Source_Ptr := Location;
2458 Canonical_Case_File_Name (Name);
2460 -- A file is a source of a language if Naming_Exception is True (case
2461 -- of naming exceptions) or if its file name ends with the suffix.
2465 (Name'Length > Suffix'Length
2467 Name (Name'Last - Suffix'Length + 1 .. Name'Last) = Suffix)
2469 if Real_Location = No_Location then
2470 Real_Location := Data.Location;
2474 Path_Id : Path_Name_Type;
2475 C_Path_Id : Path_Name_Type;
2476 -- The path name id (in canonical case)
2478 File_Id : File_Name_Type;
2479 -- The file name id (in canonical case)
2481 Obj_Id : File_Name_Type;
2482 -- The object file name
2484 Obj_Path_Id : Path_Name_Type;
2485 -- The object path name
2487 Dep_Id : File_Name_Type;
2488 -- The dependency file name
2490 Dep_Path_Id : Path_Name_Type;
2491 -- The dependency path name
2493 Dot_Pos : Natural := 0;
2494 -- Position of the last dot in Name
2496 Source : Other_Source;
2497 Source_Id : Other_Source_Id := Data.First_Other_Source;
2500 -- Get the file name id
2502 if Osint.File_Names_Case_Sensitive then
2503 File_Id := File_Name;
2505 Name_Len := Name'Length;
2506 Name_Buffer (1 .. Name_Len) := Name;
2507 File_Id := Name_Find;
2510 -- Get the path name id
2512 Path_Id := Path_Name;
2514 if Osint.File_Names_Case_Sensitive then
2515 C_Path_Id := Path_Name;
2518 C_Path : String := Get_Name_String (Path_Name);
2520 Canonical_Case_File_Name (C_Path);
2521 Name_Len := C_Path'Length;
2522 Name_Buffer (1 .. Name_Len) := C_Path;
2523 C_Path_Id := Name_Find;
2527 -- Find the position of the last dot
2529 for J in reverse Name'Range loop
2530 if Name (J) = '.' then
2536 if Dot_Pos <= Name'First then
2537 Dot_Pos := Name'Last + 1;
2540 -- Compute the object file name
2542 Get_Name_String (File_Id);
2543 Name_Len := Dot_Pos - Name'First;
2545 for J in Object_Suffix'Range loop
2546 Name_Len := Name_Len + 1;
2547 Name_Buffer (Name_Len) := Object_Suffix (J);
2550 Obj_Id := Name_Find;
2552 -- Compute the object path name
2554 Get_Name_String (Data.Display_Object_Dir);
2556 if Name_Buffer (Name_Len) /= Directory_Separator
2557 and then Name_Buffer (Name_Len) /= '/'
2559 Name_Len := Name_Len + 1;
2560 Name_Buffer (Name_Len) := Directory_Separator;
2563 Add_Str_To_Name_Buffer (Get_Name_String (Obj_Id));
2564 Obj_Path_Id := Name_Find;
2566 -- Compute the dependency file name
2568 Get_Name_String (File_Id);
2569 Name_Len := Dot_Pos - Name'First + 1;
2570 Name_Buffer (Name_Len) := '.';
2571 Name_Len := Name_Len + 1;
2572 Name_Buffer (Name_Len) := 'd';
2573 Dep_Id := Name_Find;
2575 -- Compute the dependency path name
2577 Get_Name_String (Data.Display_Object_Dir);
2579 if Name_Buffer (Name_Len) /= Directory_Separator
2580 and then Name_Buffer (Name_Len) /= '/'
2582 Name_Len := Name_Len + 1;
2583 Name_Buffer (Name_Len) := Directory_Separator;
2586 Add_Str_To_Name_Buffer (Get_Name_String (Dep_Id));
2587 Dep_Path_Id := Name_Find;
2589 -- Check if source is already in the list of source for this
2590 -- project: it may have already been specified as a naming
2591 -- exception for the same language or an other language, or
2592 -- they may be two identical file names in different source
2595 while Source_Id /= No_Other_Source loop
2596 Source := In_Tree.Other_Sources.Table (Source_Id);
2598 if Source.File_Name = File_Id then
2599 -- Two sources of different languages cannot have the same
2602 if Source.Language /= Language then
2603 Error_Msg_File_1 := File_Name;
2606 "{ cannot be a source of several languages",
2610 -- No problem if a file has already been specified as
2611 -- a naming exception of this language.
2613 elsif Source.Path_Name = C_Path_Id then
2615 -- Reset the naming exception flag, if this is not a
2616 -- naming exception.
2618 if not Naming_Exception then
2619 In_Tree.Other_Sources.Table
2620 (Source_Id).Naming_Exception := False;
2625 -- There are several files with the same names, but the
2626 -- order of the source directories is known (no /**):
2627 -- only the first one encountered is kept, the other ones
2630 elsif Data.Known_Order_Of_Source_Dirs then
2633 -- But it is an error if the order of the source directories
2637 Error_Msg_File_1 := File_Name;
2640 "{ is found in several source directories",
2645 -- Two sources with different file names cannot have the same
2646 -- object file name.
2648 elsif Source.Object_Name = Obj_Id then
2649 Error_Msg_File_1 := File_Id;
2650 Error_Msg_File_2 := Source.File_Name;
2651 Error_Msg_File_3 := Obj_Id;
2654 "{ and { have the same object file {",
2659 Source_Id := Source.Next;
2662 if Current_Verbosity = High then
2663 Write_Str (" found ");
2664 Display_Language_Name (Language);
2665 Write_Str (" source """);
2666 Write_Str (Get_Name_String (File_Name));
2668 Write_Str (" object path = ");
2669 Write_Line (Get_Name_String (Obj_Path_Id));
2672 -- Create the Other_Source record
2675 (Language => Language,
2676 File_Name => File_Id,
2677 Path_Name => Path_Id,
2678 Source_TS => File_Stamp (Path_Id),
2679 Object_Name => Obj_Id,
2680 Object_Path => Obj_Path_Id,
2681 Object_TS => File_Stamp (Obj_Path_Id),
2683 Dep_Path => Dep_Path_Id,
2684 Dep_TS => File_Stamp (Dep_Path_Id),
2685 Naming_Exception => Naming_Exception,
2686 Next => No_Other_Source);
2688 -- And add it to the Other_Sources table
2690 Other_Source_Table.Increment_Last (In_Tree.Other_Sources);
2691 In_Tree.Other_Sources.Table
2692 (Other_Source_Table.Last (In_Tree.Other_Sources)) := Source;
2694 -- There are sources of languages other than Ada in this project
2696 Data.Other_Sources_Present := True;
2698 -- And there are sources of this language in this project
2700 Set (Language, True, Data, In_Tree);
2702 -- Add this source to the list of sources of languages other than
2703 -- Ada of the project.
2705 if Data.First_Other_Source = No_Other_Source then
2706 Data.First_Other_Source :=
2707 Other_Source_Table.Last (In_Tree.Other_Sources);
2710 In_Tree.Other_Sources.Table (Data.Last_Other_Source).Next :=
2711 Other_Source_Table.Last (In_Tree.Other_Sources);
2714 Data.Last_Other_Source :=
2715 Other_Source_Table.Last (In_Tree.Other_Sources);
2718 end Check_For_Source;
2720 -------------------------------
2721 -- Check_If_Externally_Built --
2722 -------------------------------
2724 procedure Check_If_Externally_Built
2725 (Project : Project_Id;
2726 In_Tree : Project_Tree_Ref;
2727 Data : in out Project_Data)
2729 Externally_Built : constant Variable_Value :=
2731 (Name_Externally_Built,
2732 Data.Decl.Attributes, In_Tree);
2735 if not Externally_Built.Default then
2736 Get_Name_String (Externally_Built.Value);
2737 To_Lower (Name_Buffer (1 .. Name_Len));
2739 if Name_Buffer (1 .. Name_Len) = "true" then
2740 Data.Externally_Built := True;
2742 elsif Name_Buffer (1 .. Name_Len) /= "false" then
2743 Error_Msg (Project, In_Tree,
2744 "Externally_Built may only be true or false",
2745 Externally_Built.Location);
2749 -- A virtual project extending an externally built project is itself
2750 -- externally built.
2752 if Data.Virtual and then Data.Extends /= No_Project then
2753 Data.Externally_Built :=
2754 In_Tree.Projects.Table (Data.Extends).Externally_Built;
2757 if Current_Verbosity = High then
2758 Write_Str ("Project is ");
2760 if not Data.Externally_Built then
2764 Write_Line ("externally built.");
2766 end Check_If_Externally_Built;
2768 ----------------------
2769 -- Check_Interfaces --
2770 ----------------------
2772 procedure Check_Interfaces
2773 (Project : Project_Id;
2774 In_Tree : Project_Tree_Ref;
2775 Data : in out Project_Data)
2777 Interfaces : constant Prj.Variable_Value :=
2779 (Snames.Name_Interfaces,
2780 Data.Decl.Attributes,
2783 List : String_List_Id;
2784 Element : String_Element;
2785 Name : File_Name_Type;
2788 Src_Data : Source_Data;
2790 Project_2 : Project_Id;
2791 Data_2 : Project_Data;
2794 if not Interfaces.Default then
2796 -- Set In_Interfaces to False for all sources. It will be set to True
2797 -- later for the sources in the Interfaces list.
2799 Project_2 := Project;
2802 Source := Data_2.First_Source;
2803 while Source /= No_Source loop
2804 Src_Data := In_Tree.Sources.Table (Source);
2805 Src_Data.In_Interfaces := False;
2806 In_Tree.Sources.Table (Source) := Src_Data;
2807 Source := Src_Data.Next_In_Project;
2810 Project_2 := Data_2.Extends;
2812 exit when Project_2 = No_Project;
2814 Data_2 := In_Tree.Projects.Table (Project_2);
2817 List := Interfaces.Values;
2818 while List /= Nil_String loop
2819 Element := In_Tree.String_Elements.Table (List);
2820 Get_Name_String (Element.Value);
2821 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2824 Project_2 := Project;
2828 Source := Data_2.First_Source;
2829 while Source /= No_Source loop
2830 Src_Data := In_Tree.Sources.Table (Source);
2831 if Src_Data.File = Name then
2832 if not Src_Data.Locally_Removed then
2833 In_Tree.Sources.Table (Source).In_Interfaces := True;
2834 In_Tree.Sources.Table
2835 (Source).Declared_In_Interfaces := True;
2837 if Src_Data.Other_Part /= No_Source then
2838 In_Tree.Sources.Table
2839 (Src_Data.Other_Part).In_Interfaces := True;
2840 In_Tree.Sources.Table
2841 (Src_Data.Other_Part).Declared_In_Interfaces :=
2845 if Current_Verbosity = High then
2846 Write_Str (" interface: ");
2847 Write_Line (Get_Name_String (Src_Data.Path));
2854 Source := Src_Data.Next_In_Project;
2857 Project_2 := Data_2.Extends;
2859 exit Big_Loop when Project_2 = No_Project;
2861 Data_2 := In_Tree.Projects.Table (Project_2);
2864 if Source = No_Source then
2865 Error_Msg_File_1 := File_Name_Type (Element.Value);
2866 Error_Msg_Name_1 := Data.Name;
2871 "{ cannot be an interface of project %% " &
2872 "as it is not one of its sources",
2876 List := Element.Next;
2879 Data.Interfaces_Defined := True;
2881 elsif Data.Extends /= No_Project then
2882 Data.Interfaces_Defined :=
2883 In_Tree.Projects.Table (Data.Extends).Interfaces_Defined;
2885 if Data.Interfaces_Defined then
2886 Source := Data.First_Source;
2887 while Source /= No_Source loop
2888 Src_Data := In_Tree.Sources.Table (Source);
2890 if not Src_Data.Declared_In_Interfaces then
2891 Src_Data.In_Interfaces := False;
2892 In_Tree.Sources.Table (Source) := Src_Data;
2895 Source := Src_Data.Next_In_Project;
2899 end Check_Interfaces;
2901 --------------------------
2902 -- Check_Naming_Schemes --
2903 --------------------------
2905 procedure Check_Naming_Schemes
2906 (Data : in out Project_Data;
2907 Project : Project_Id;
2908 In_Tree : Project_Tree_Ref)
2910 Naming_Id : constant Package_Id :=
2911 Util.Value_Of (Name_Naming, Data.Decl.Packages, In_Tree);
2912 Naming : Package_Element;
2914 procedure Check_Unit_Names (List : Array_Element_Id);
2915 -- Check that a list of unit names contains only valid names
2917 procedure Get_Exceptions (Kind : Source_Kind);
2919 procedure Get_Unit_Exceptions (Kind : Source_Kind);
2921 ----------------------
2922 -- Check_Unit_Names --
2923 ----------------------
2925 procedure Check_Unit_Names (List : Array_Element_Id) is
2926 Current : Array_Element_Id;
2927 Element : Array_Element;
2928 Unit_Name : Name_Id;
2931 -- Loop through elements of the string list
2934 while Current /= No_Array_Element loop
2935 Element := In_Tree.Array_Elements.Table (Current);
2937 -- Put file name in canonical case
2939 if not Osint.File_Names_Case_Sensitive then
2940 Get_Name_String (Element.Value.Value);
2941 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2942 Element.Value.Value := Name_Find;
2945 -- Check that it contains a valid unit name
2947 Get_Name_String (Element.Index);
2948 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit_Name);
2950 if Unit_Name = No_Name then
2951 Err_Vars.Error_Msg_Name_1 := Element.Index;
2954 "%% is not a valid unit name.",
2955 Element.Value.Location);
2958 if Current_Verbosity = High then
2959 Write_Str (" Unit (""");
2960 Write_Str (Get_Name_String (Unit_Name));
2964 Element.Index := Unit_Name;
2965 In_Tree.Array_Elements.Table (Current) := Element;
2968 Current := Element.Next;
2970 end Check_Unit_Names;
2972 --------------------
2973 -- Get_Exceptions --
2974 --------------------
2976 procedure Get_Exceptions (Kind : Source_Kind) is
2977 Exceptions : Array_Element_Id;
2978 Exception_List : Variable_Value;
2979 Element_Id : String_List_Id;
2980 Element : String_Element;
2981 File_Name : File_Name_Type;
2982 Lang_Id : Language_Index;
2984 Lang_Kind : Language_Kind;
2991 (Name_Implementation_Exceptions,
2992 In_Arrays => Naming.Decl.Arrays,
2993 In_Tree => In_Tree);
2998 (Name_Specification_Exceptions,
2999 In_Arrays => Naming.Decl.Arrays,
3000 In_Tree => In_Tree);
3003 Lang_Id := Data.First_Language_Processing;
3004 while Lang_Id /= No_Language_Index loop
3005 if In_Tree.Languages_Data.Table (Lang_Id).Config.Kind =
3008 Lang := In_Tree.Languages_Data.Table (Lang_Id).Name;
3010 In_Tree.Languages_Data.Table (Lang_Id).Config.Kind;
3012 Exception_List := Value_Of
3014 In_Array => Exceptions,
3015 In_Tree => In_Tree);
3017 if Exception_List /= Nil_Variable_Value then
3018 Element_Id := Exception_List.Values;
3019 while Element_Id /= Nil_String loop
3020 Element := In_Tree.String_Elements.Table (Element_Id);
3022 if Osint.File_Names_Case_Sensitive then
3023 File_Name := File_Name_Type (Element.Value);
3025 Get_Name_String (Element.Value);
3026 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3027 File_Name := Name_Find;
3030 Source := Data.First_Source;
3031 while Source /= No_Source
3033 In_Tree.Sources.Table (Source).File /= File_Name
3036 In_Tree.Sources.Table (Source).Next_In_Project;
3039 if Source = No_Source then
3048 File_Name => File_Name,
3049 Display_File => File_Name_Type (Element.Value),
3050 Naming_Exception => True,
3051 Lang_Kind => Lang_Kind);
3054 -- Check if the file name is already recorded for
3055 -- another language or another kind.
3058 In_Tree.Sources.Table (Source).Language /= Lang_Id
3063 "the same file cannot be a source " &
3067 elsif In_Tree.Sources.Table (Source).Kind /= Kind then
3071 "the same file cannot be a source " &
3076 -- If the file is already recorded for the same
3077 -- language and the same kind, it means that the file
3078 -- name appears several times in the *_Exceptions
3079 -- attribute; so there is nothing to do.
3083 Element_Id := Element.Next;
3088 Lang_Id := In_Tree.Languages_Data.Table (Lang_Id).Next;
3092 -------------------------
3093 -- Get_Unit_Exceptions --
3094 -------------------------
3096 procedure Get_Unit_Exceptions (Kind : Source_Kind) is
3097 Exceptions : Array_Element_Id;
3098 Element : Array_Element;
3101 File_Name : File_Name_Type;
3102 Lang_Id : constant Language_Index :=
3103 Data.Unit_Based_Language_Index;
3104 Lang : constant Name_Id :=
3105 Data.Unit_Based_Language_Name;
3108 Source_To_Replace : Source_Id := No_Source;
3110 Other_Project : Project_Id;
3111 Other_Part : Source_Id := No_Source;
3114 if Lang_Id = No_Language_Index or else Lang = No_Name then
3119 Exceptions := Value_Of
3121 In_Arrays => Naming.Decl.Arrays,
3122 In_Tree => In_Tree);
3124 if Exceptions = No_Array_Element then
3127 (Name_Implementation,
3128 In_Arrays => Naming.Decl.Arrays,
3129 In_Tree => In_Tree);
3136 In_Arrays => Naming.Decl.Arrays,
3137 In_Tree => In_Tree);
3139 if Exceptions = No_Array_Element then
3140 Exceptions := Value_Of
3141 (Name_Specification,
3142 In_Arrays => Naming.Decl.Arrays,
3143 In_Tree => In_Tree);
3148 while Exceptions /= No_Array_Element loop
3149 Element := In_Tree.Array_Elements.Table (Exceptions);
3151 if Osint.File_Names_Case_Sensitive then
3152 File_Name := File_Name_Type (Element.Value.Value);
3154 Get_Name_String (Element.Value.Value);
3155 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3156 File_Name := Name_Find;
3159 Get_Name_String (Element.Index);
3160 To_Lower (Name_Buffer (1 .. Name_Len));
3163 Index := Element.Value.Index;
3165 -- For Ada, check if it is a valid unit name
3167 if Lang = Name_Ada then
3168 Get_Name_String (Element.Index);
3169 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit);
3171 if Unit = No_Name then
3172 Err_Vars.Error_Msg_Name_1 := Element.Index;
3175 "%% is not a valid unit name.",
3176 Element.Value.Location);
3180 if Unit /= No_Name then
3182 -- Check if the source already exists
3184 Source := In_Tree.First_Source;
3185 Source_To_Replace := No_Source;
3187 while Source /= No_Source and then
3188 (In_Tree.Sources.Table (Source).Unit /= Unit or else
3189 In_Tree.Sources.Table (Source).Index /= Index)
3191 Source := In_Tree.Sources.Table (Source).Next_In_Sources;
3194 if Source /= No_Source then
3195 if In_Tree.Sources.Table (Source).Kind /= Kind then
3196 Other_Part := Source;
3200 In_Tree.Sources.Table (Source).Next_In_Sources;
3202 exit when Source = No_Source or else
3203 (In_Tree.Sources.Table (Source).Unit = Unit
3205 In_Tree.Sources.Table (Source).Index = Index);
3209 if Source /= No_Source then
3210 Other_Project := In_Tree.Sources.Table (Source).Project;
3212 if Is_Extending (Project, Other_Project, In_Tree) then
3214 In_Tree.Sources.Table (Source).Other_Part;
3216 -- Record the source to be removed
3218 Source_To_Replace := Source;
3219 Source := No_Source;
3222 Error_Msg_Name_1 := Unit;
3224 In_Tree.Projects.Table (Other_Project).Name;
3228 "%% is already a source of project %%",
3229 Element.Value.Location);
3234 if Source = No_Source then
3243 File_Name => File_Name,
3244 Display_File => File_Name_Type (Element.Value.Value),
3245 Lang_Kind => Unit_Based,
3246 Other_Part => Other_Part,
3249 Naming_Exception => True,
3250 Source_To_Replace => Source_To_Replace);
3254 Exceptions := Element.Next;
3257 end Get_Unit_Exceptions;
3259 -- Start of processing for Check_Naming_Schemes
3262 if Get_Mode = Ada_Only then
3264 -- If there is a package Naming, we will put in Data.Naming what is
3265 -- in this package Naming.
3267 if Naming_Id /= No_Package then
3268 Naming := In_Tree.Packages.Table (Naming_Id);
3270 if Current_Verbosity = High then
3271 Write_Line ("Checking ""Naming"" for Ada.");
3275 Bodies : constant Array_Element_Id :=
3277 (Name_Body, Naming.Decl.Arrays, In_Tree);
3279 Specs : constant Array_Element_Id :=
3281 (Name_Spec, Naming.Decl.Arrays, In_Tree);
3284 if Bodies /= No_Array_Element then
3286 -- We have elements in the array Body_Part
3288 if Current_Verbosity = High then
3289 Write_Line ("Found Bodies.");
3292 Data.Naming.Bodies := Bodies;
3293 Check_Unit_Names (Bodies);
3296 if Current_Verbosity = High then
3297 Write_Line ("No Bodies.");
3301 if Specs /= No_Array_Element then
3303 -- We have elements in the array Specs
3305 if Current_Verbosity = High then
3306 Write_Line ("Found Specs.");
3309 Data.Naming.Specs := Specs;
3310 Check_Unit_Names (Specs);
3313 if Current_Verbosity = High then
3314 Write_Line ("No Specs.");
3319 -- We are now checking if variables Dot_Replacement, Casing,
3320 -- Spec_Suffix, Body_Suffix and/or Separate_Suffix exist.
3322 -- For each variable, if it does not exist, we do nothing,
3323 -- because we already have the default.
3325 -- Check Dot_Replacement
3328 Dot_Replacement : constant Variable_Value :=
3330 (Name_Dot_Replacement,
3331 Naming.Decl.Attributes, In_Tree);
3334 pragma Assert (Dot_Replacement.Kind = Single,
3335 "Dot_Replacement is not a single string");
3337 if not Dot_Replacement.Default then
3338 Get_Name_String (Dot_Replacement.Value);
3340 if Name_Len = 0 then
3343 "Dot_Replacement cannot be empty",
3344 Dot_Replacement.Location);
3347 if Osint.File_Names_Case_Sensitive then
3348 Data.Naming.Dot_Replacement :=
3349 File_Name_Type (Dot_Replacement.Value);
3351 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3352 Data.Naming.Dot_Replacement := Name_Find;
3354 Data.Naming.Dot_Repl_Loc := Dot_Replacement.Location;
3359 if Current_Verbosity = High then
3360 Write_Str (" Dot_Replacement = """);
3361 Write_Str (Get_Name_String (Data.Naming.Dot_Replacement));
3369 Casing_String : constant Variable_Value :=
3372 Naming.Decl.Attributes,
3376 pragma Assert (Casing_String.Kind = Single,
3377 "Casing is not a single string");
3379 if not Casing_String.Default then
3381 Casing_Image : constant String :=
3382 Get_Name_String (Casing_String.Value);
3385 Casing_Value : constant Casing_Type :=
3386 Value (Casing_Image);
3388 Data.Naming.Casing := Casing_Value;
3392 when Constraint_Error =>
3393 if Casing_Image'Length = 0 then
3396 "Casing cannot be an empty string",
3397 Casing_String.Location);
3400 Name_Len := Casing_Image'Length;
3401 Name_Buffer (1 .. Name_Len) := Casing_Image;
3402 Err_Vars.Error_Msg_Name_1 := Name_Find;
3405 "%% is not a correct Casing",
3406 Casing_String.Location);
3412 if Current_Verbosity = High then
3413 Write_Str (" Casing = ");
3414 Write_Str (Image (Data.Naming.Casing));
3419 -- Check Spec_Suffix
3422 Ada_Spec_Suffix : constant Variable_Value :=
3426 In_Array => Data.Naming.Spec_Suffix,
3427 In_Tree => In_Tree);
3430 if Ada_Spec_Suffix.Kind = Single
3431 and then Get_Name_String (Ada_Spec_Suffix.Value) /= ""
3433 Get_Name_String (Ada_Spec_Suffix.Value);
3434 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3435 Set_Spec_Suffix (In_Tree, "ada", Data.Naming, Name_Find);
3436 Data.Naming.Ada_Spec_Suffix_Loc := Ada_Spec_Suffix.Location;
3443 Default_Ada_Spec_Suffix);
3447 if Current_Verbosity = High then
3448 Write_Str (" Spec_Suffix = """);
3449 Write_Str (Spec_Suffix_Of (In_Tree, "ada", Data.Naming));
3454 -- Check Body_Suffix
3457 Ada_Body_Suffix : constant Variable_Value :=
3461 In_Array => Data.Naming.Body_Suffix,
3462 In_Tree => In_Tree);
3465 if Ada_Body_Suffix.Kind = Single
3466 and then Get_Name_String (Ada_Body_Suffix.Value) /= ""
3468 Get_Name_String (Ada_Body_Suffix.Value);
3469 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3470 Set_Body_Suffix (In_Tree, "ada", Data.Naming, Name_Find);
3471 Data.Naming.Ada_Body_Suffix_Loc := Ada_Body_Suffix.Location;
3478 Default_Ada_Body_Suffix);
3482 if Current_Verbosity = High then
3483 Write_Str (" Body_Suffix = """);
3484 Write_Str (Body_Suffix_Of (In_Tree, "ada", Data.Naming));
3489 -- Check Separate_Suffix
3492 Ada_Sep_Suffix : constant Variable_Value :=
3494 (Variable_Name => Name_Separate_Suffix,
3495 In_Variables => Naming.Decl.Attributes,
3496 In_Tree => In_Tree);
3499 if Ada_Sep_Suffix.Default then
3500 Data.Naming.Separate_Suffix :=
3501 Body_Suffix_Id_Of (In_Tree, Name_Ada, Data.Naming);
3504 Get_Name_String (Ada_Sep_Suffix.Value);
3506 if Name_Len = 0 then
3509 "Separate_Suffix cannot be empty",
3510 Ada_Sep_Suffix.Location);
3513 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3514 Data.Naming.Separate_Suffix := Name_Find;
3515 Data.Naming.Sep_Suffix_Loc := Ada_Sep_Suffix.Location;
3520 if Current_Verbosity = High then
3521 Write_Str (" Separate_Suffix = """);
3522 Write_Str (Get_Name_String (Data.Naming.Separate_Suffix));
3527 -- Check if Data.Naming is valid
3529 Check_Ada_Naming_Scheme_Validity (Project, In_Tree, Data.Naming);
3532 elsif not In_Configuration then
3534 -- Look into package Naming, if there is one
3536 if Naming_Id /= No_Package then
3537 Naming := In_Tree.Packages.Table (Naming_Id);
3539 if Current_Verbosity = High then
3540 Write_Line ("Checking package Naming.");
3543 -- We are now checking if attribute Dot_Replacement, Casing,
3544 -- and/or Separate_Suffix exist.
3546 -- For each attribute, if it does not exist, we do nothing,
3547 -- because we already have the default.
3548 -- Otherwise, for all unit-based languages, we put the declared
3549 -- value in the language config.
3552 Dot_Repl : constant Variable_Value :=
3554 (Name_Dot_Replacement,
3555 Naming.Decl.Attributes, In_Tree);
3556 Dot_Replacement : File_Name_Type := No_File;
3558 Casing_String : constant Variable_Value :=
3561 Naming.Decl.Attributes,
3563 Casing : Casing_Type;
3564 Casing_Defined : Boolean := False;
3566 Sep_Suffix : constant Variable_Value :=
3568 (Variable_Name => Name_Separate_Suffix,
3569 In_Variables => Naming.Decl.Attributes,
3570 In_Tree => In_Tree);
3571 Separate_Suffix : File_Name_Type := No_File;
3573 Lang_Id : Language_Index;
3575 -- Check attribute Dot_Replacement
3577 if not Dot_Repl.Default then
3578 Get_Name_String (Dot_Repl.Value);
3580 if Name_Len = 0 then
3583 "Dot_Replacement cannot be empty",
3587 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3588 Dot_Replacement := Name_Find;
3590 if Current_Verbosity = High then
3591 Write_Str (" Dot_Replacement = """);
3592 Write_Str (Get_Name_String (Dot_Replacement));
3599 -- Check attribute Casing
3601 if not Casing_String.Default then
3603 Casing_Image : constant String :=
3604 Get_Name_String (Casing_String.Value);
3607 Casing_Value : constant Casing_Type :=
3608 Value (Casing_Image);
3610 Casing := Casing_Value;
3611 Casing_Defined := True;
3613 if Current_Verbosity = High then
3614 Write_Str (" Casing = ");
3615 Write_Str (Image (Casing));
3622 when Constraint_Error =>
3623 if Casing_Image'Length = 0 then
3626 "Casing cannot be an empty string",
3627 Casing_String.Location);
3630 Name_Len := Casing_Image'Length;
3631 Name_Buffer (1 .. Name_Len) := Casing_Image;
3632 Err_Vars.Error_Msg_Name_1 := Name_Find;
3635 "%% is not a correct Casing",
3636 Casing_String.Location);
3641 if not Sep_Suffix.Default then
3642 Get_Name_String (Sep_Suffix.Value);
3644 if Name_Len = 0 then
3647 "Separate_Suffix cannot be empty",
3648 Sep_Suffix.Location);
3651 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3652 Separate_Suffix := Name_Find;
3654 if Current_Verbosity = High then
3655 Write_Str (" Separate_Suffix = """);
3656 Write_Str (Get_Name_String (Separate_Suffix));
3663 -- For all unit based languages, if any, set the specified
3664 -- value of Dot_Replacement, Casing and/or Separate_Suffix.
3666 if Dot_Replacement /= No_File
3667 or else Casing_Defined
3668 or else Separate_Suffix /= No_File
3670 Lang_Id := Data.First_Language_Processing;
3671 while Lang_Id /= No_Language_Index loop
3672 if In_Tree.Languages_Data.Table
3673 (Lang_Id).Config.Kind = Unit_Based
3675 if Dot_Replacement /= No_File then
3676 In_Tree.Languages_Data.Table
3677 (Lang_Id).Config.Naming_Data.Dot_Replacement :=
3681 if Casing_Defined then
3682 In_Tree.Languages_Data.Table
3683 (Lang_Id).Config.Naming_Data.Casing := Casing;
3686 if Separate_Suffix /= No_File then
3687 In_Tree.Languages_Data.Table
3688 (Lang_Id).Config.Naming_Data.Separate_Suffix :=
3694 In_Tree.Languages_Data.Table (Lang_Id).Next;
3699 -- Next, get the spec and body suffixes
3702 Suffix : Variable_Value;
3703 Lang_Id : Language_Index;
3707 Lang_Id := Data.First_Language_Processing;
3708 while Lang_Id /= No_Language_Index loop
3709 Lang := In_Tree.Languages_Data.Table (Lang_Id).Name;
3715 Attribute_Or_Array_Name => Name_Spec_Suffix,
3716 In_Package => Naming_Id,
3717 In_Tree => In_Tree);
3719 if Suffix = Nil_Variable_Value then
3722 Attribute_Or_Array_Name => Name_Specification_Suffix,
3723 In_Package => Naming_Id,
3724 In_Tree => In_Tree);
3727 if Suffix /= Nil_Variable_Value then
3728 In_Tree.Languages_Data.Table (Lang_Id).
3729 Config.Naming_Data.Spec_Suffix :=
3730 File_Name_Type (Suffix.Value);
3737 Attribute_Or_Array_Name => Name_Body_Suffix,
3738 In_Package => Naming_Id,
3739 In_Tree => In_Tree);
3741 if Suffix = Nil_Variable_Value then
3744 Attribute_Or_Array_Name => Name_Implementation_Suffix,
3745 In_Package => Naming_Id,
3746 In_Tree => In_Tree);
3749 if Suffix /= Nil_Variable_Value then
3750 In_Tree.Languages_Data.Table (Lang_Id).
3751 Config.Naming_Data.Body_Suffix :=
3752 File_Name_Type (Suffix.Value);
3755 Lang_Id := In_Tree.Languages_Data.Table (Lang_Id).Next;
3759 -- Get the exceptions for file based languages
3761 Get_Exceptions (Spec);
3762 Get_Exceptions (Impl);
3764 -- Get the exceptions for unit based languages
3766 Get_Unit_Exceptions (Spec);
3767 Get_Unit_Exceptions (Impl);
3771 end Check_Naming_Schemes;
3773 ------------------------------
3774 -- Check_Library_Attributes --
3775 ------------------------------
3777 procedure Check_Library_Attributes
3778 (Project : Project_Id;
3779 In_Tree : Project_Tree_Ref;
3780 Current_Dir : String;
3781 Data : in out Project_Data)
3783 Attributes : constant Prj.Variable_Id := Data.Decl.Attributes;
3785 Lib_Dir : constant Prj.Variable_Value :=
3787 (Snames.Name_Library_Dir, Attributes, In_Tree);
3789 Lib_Name : constant Prj.Variable_Value :=
3791 (Snames.Name_Library_Name, Attributes, In_Tree);
3793 Lib_Version : constant Prj.Variable_Value :=
3795 (Snames.Name_Library_Version, Attributes, In_Tree);
3797 Lib_ALI_Dir : constant Prj.Variable_Value :=
3799 (Snames.Name_Library_Ali_Dir, Attributes, In_Tree);
3801 The_Lib_Kind : constant Prj.Variable_Value :=
3803 (Snames.Name_Library_Kind, Attributes, In_Tree);
3805 Imported_Project_List : Project_List := Empty_Project_List;
3807 Continuation : String_Access := No_Continuation_String'Access;
3809 Support_For_Libraries : Library_Support;
3811 Library_Directory_Present : Boolean;
3813 procedure Check_Library (Proj : Project_Id; Extends : Boolean);
3814 -- Check if an imported or extended project if also a library project
3820 procedure Check_Library (Proj : Project_Id; Extends : Boolean) is
3821 Proj_Data : Project_Data;
3826 if Proj /= No_Project then
3827 Proj_Data := In_Tree.Projects.Table (Proj);
3829 if not Proj_Data.Library then
3831 -- The only not library projects that are OK are those that
3832 -- have no sources. However, header files from non-Ada
3833 -- languages are OK, as there is nothing to compile.
3835 Src_Id := Proj_Data.First_Source;
3836 while Src_Id /= No_Source loop
3837 Src := In_Tree.Sources.Table (Src_Id);
3839 exit when Src.Lang_Kind /= File_Based
3840 or else Src.Kind /= Spec;
3842 Src_Id := Src.Next_In_Project;
3845 if Src_Id /= No_Source then
3846 Error_Msg_Name_1 := Data.Name;
3847 Error_Msg_Name_2 := Proj_Data.Name;
3853 "library project %% cannot extend project %% " &
3854 "that is not a library project",
3856 Continuation := Continuation_String'Access;
3858 elsif Data.Library_Kind /= Static then
3862 "shared library project %% cannot import project %% " &
3863 "that is not a shared library project",
3865 Continuation := Continuation_String'Access;
3869 elsif Data.Library_Kind /= Static and then
3870 Proj_Data.Library_Kind = Static
3872 Error_Msg_Name_1 := Data.Name;
3873 Error_Msg_Name_2 := Proj_Data.Name;
3879 "shared library project %% cannot extend static " &
3880 "library project %%",
3887 "shared library project %% cannot import static " &
3888 "library project %%",
3892 Continuation := Continuation_String'Access;
3897 -- Start of processing for Check_Library_Attributes
3900 Library_Directory_Present := Lib_Dir.Value /= Empty_String;
3902 -- Special case of extending project
3904 if Data.Extends /= No_Project then
3906 Extended_Data : constant Project_Data :=
3907 In_Tree.Projects.Table (Data.Extends);
3910 -- If the project extended is a library project, we inherit the
3911 -- library name, if it is not redefined; we check that the library
3912 -- directory is specified.
3914 if Extended_Data.Library then
3915 if Data.Qualifier = Standard then
3918 "a standard project cannot extend a library project",
3922 if Lib_Name.Default then
3923 Data.Library_Name := Extended_Data.Library_Name;
3926 if Lib_Dir.Default then
3927 if not Data.Virtual then
3930 "a project extending a library project must " &
3931 "specify an attribute Library_Dir",
3935 -- For a virtual project extending a library project,
3936 -- inherit library directory.
3938 Data.Library_Dir := Extended_Data.Library_Dir;
3939 Data.Display_Library_Dir :=
3940 Extended_Data.Display_Library_Dir;
3941 Library_Directory_Present := True;
3949 pragma Assert (Lib_Name.Kind = Single);
3951 if Lib_Name.Value = Empty_String then
3952 if Current_Verbosity = High
3953 and then Data.Library_Name = No_Name
3955 Write_Line ("No library name");
3959 -- There is no restriction on the syntax of library names
3961 Data.Library_Name := Lib_Name.Value;
3964 if Data.Library_Name /= No_Name then
3965 if Current_Verbosity = High then
3966 Write_Str ("Library name = """);
3967 Write_Str (Get_Name_String (Data.Library_Name));
3971 pragma Assert (Lib_Dir.Kind = Single);
3973 if not Library_Directory_Present then
3974 if Current_Verbosity = High then
3975 Write_Line ("No library directory");
3979 -- Find path name (unless inherited), check that it is a directory
3981 if Data.Library_Dir = No_Path then
3985 File_Name_Type (Lib_Dir.Value),
3986 Data.Display_Directory,
3988 Data.Display_Library_Dir,
3989 Create => "library",
3990 Current_Dir => Current_Dir,
3991 Location => Lib_Dir.Location);
3994 if Data.Library_Dir = No_Path then
3996 -- Get the absolute name of the library directory that
3997 -- does not exist, to report an error.
4000 Dir_Name : constant String :=
4001 Get_Name_String (Lib_Dir.Value);
4004 if Is_Absolute_Path (Dir_Name) then
4005 Err_Vars.Error_Msg_File_1 :=
4006 File_Name_Type (Lib_Dir.Value);
4009 Get_Name_String (Data.Display_Directory);
4011 if Name_Buffer (Name_Len) /= Directory_Separator then
4012 Name_Len := Name_Len + 1;
4013 Name_Buffer (Name_Len) := Directory_Separator;
4017 (Name_Len + 1 .. Name_Len + Dir_Name'Length) :=
4019 Name_Len := Name_Len + Dir_Name'Length;
4020 Err_Vars.Error_Msg_File_1 := Name_Find;
4027 "library directory { does not exist",
4031 -- The library directory cannot be the same as the Object
4034 elsif Data.Library_Dir = Data.Object_Directory then
4037 "library directory cannot be the same " &
4038 "as object directory",
4040 Data.Library_Dir := No_Path;
4041 Data.Display_Library_Dir := No_Path;
4045 OK : Boolean := True;
4046 Dirs_Id : String_List_Id;
4047 Dir_Elem : String_Element;
4050 -- The library directory cannot be the same as a source
4051 -- directory of the current project.
4053 Dirs_Id := Data.Source_Dirs;
4054 while Dirs_Id /= Nil_String loop
4055 Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id);
4056 Dirs_Id := Dir_Elem.Next;
4058 if Data.Library_Dir = Path_Name_Type (Dir_Elem.Value) then
4059 Err_Vars.Error_Msg_File_1 :=
4060 File_Name_Type (Dir_Elem.Value);
4063 "library directory cannot be the same " &
4064 "as source directory {",
4073 -- The library directory cannot be the same as a source
4074 -- directory of another project either.
4077 for Pid in 1 .. Project_Table.Last (In_Tree.Projects) loop
4078 if Pid /= Project then
4079 Dirs_Id := In_Tree.Projects.Table (Pid).Source_Dirs;
4081 Dir_Loop : while Dirs_Id /= Nil_String loop
4083 In_Tree.String_Elements.Table (Dirs_Id);
4084 Dirs_Id := Dir_Elem.Next;
4086 if Data.Library_Dir =
4087 Path_Name_Type (Dir_Elem.Value)
4089 Err_Vars.Error_Msg_File_1 :=
4090 File_Name_Type (Dir_Elem.Value);
4091 Err_Vars.Error_Msg_Name_1 :=
4092 In_Tree.Projects.Table (Pid).Name;
4096 "library directory cannot be the same " &
4097 "as source directory { of project %%",
4104 end loop Project_Loop;
4108 Data.Library_Dir := No_Path;
4109 Data.Display_Library_Dir := No_Path;
4111 elsif Current_Verbosity = High then
4113 -- Display the Library directory in high verbosity
4115 Write_Str ("Library directory =""");
4116 Write_Str (Get_Name_String (Data.Display_Library_Dir));
4126 Data.Library_Dir /= No_Path
4128 Data.Library_Name /= No_Name;
4130 if Data.Extends = No_Project then
4131 case Data.Qualifier is
4133 if Data.Library then
4136 "a standard project cannot be a library project",
4141 if not Data.Library then
4144 "not a library project",
4154 if Data.Library then
4155 if Get_Mode = Multi_Language then
4156 Support_For_Libraries := Data.Config.Lib_Support;
4159 Support_For_Libraries := MLib.Tgt.Support_For_Libraries;
4162 if Support_For_Libraries = Prj.None then
4165 "?libraries are not supported on this platform",
4167 Data.Library := False;
4170 if Lib_ALI_Dir.Value = Empty_String then
4171 if Current_Verbosity = High then
4172 Write_Line ("No library ALI directory specified");
4174 Data.Library_ALI_Dir := Data.Library_Dir;
4175 Data.Display_Library_ALI_Dir := Data.Display_Library_Dir;
4178 -- Find path name, check that it is a directory
4183 File_Name_Type (Lib_ALI_Dir.Value),
4184 Data.Display_Directory,
4185 Data.Library_ALI_Dir,
4186 Data.Display_Library_ALI_Dir,
4187 Create => "library ALI",
4188 Current_Dir => Current_Dir,
4189 Location => Lib_ALI_Dir.Location);
4191 if Data.Library_ALI_Dir = No_Path then
4193 -- Get the absolute name of the library ALI directory that
4194 -- does not exist, to report an error.
4197 Dir_Name : constant String :=
4198 Get_Name_String (Lib_ALI_Dir.Value);
4201 if Is_Absolute_Path (Dir_Name) then
4202 Err_Vars.Error_Msg_File_1 :=
4203 File_Name_Type (Lib_Dir.Value);
4206 Get_Name_String (Data.Display_Directory);
4208 if Name_Buffer (Name_Len) /= Directory_Separator then
4209 Name_Len := Name_Len + 1;
4210 Name_Buffer (Name_Len) := Directory_Separator;
4214 (Name_Len + 1 .. Name_Len + Dir_Name'Length) :=
4216 Name_Len := Name_Len + Dir_Name'Length;
4217 Err_Vars.Error_Msg_File_1 := Name_Find;
4224 "library 'A'L'I directory { does not exist",
4225 Lib_ALI_Dir.Location);
4229 if Data.Library_ALI_Dir /= Data.Library_Dir then
4231 -- The library ALI directory cannot be the same as the
4232 -- Object directory.
4234 if Data.Library_ALI_Dir = Data.Object_Directory then
4237 "library 'A'L'I directory cannot be the same " &
4238 "as object directory",
4239 Lib_ALI_Dir.Location);
4240 Data.Library_ALI_Dir := No_Path;
4241 Data.Display_Library_ALI_Dir := No_Path;
4245 OK : Boolean := True;
4246 Dirs_Id : String_List_Id;
4247 Dir_Elem : String_Element;
4250 -- The library ALI directory cannot be the same as
4251 -- a source directory of the current project.
4253 Dirs_Id := Data.Source_Dirs;
4254 while Dirs_Id /= Nil_String loop
4255 Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id);
4256 Dirs_Id := Dir_Elem.Next;
4258 if Data.Library_ALI_Dir =
4259 Path_Name_Type (Dir_Elem.Value)
4261 Err_Vars.Error_Msg_File_1 :=
4262 File_Name_Type (Dir_Elem.Value);
4265 "library 'A'L'I directory cannot be " &
4266 "the same as source directory {",
4267 Lib_ALI_Dir.Location);
4275 -- The library ALI directory cannot be the same as
4276 -- a source directory of another project either.
4280 Pid in 1 .. Project_Table.Last (In_Tree.Projects)
4282 if Pid /= Project then
4284 In_Tree.Projects.Table (Pid).Source_Dirs;
4287 while Dirs_Id /= Nil_String loop
4289 In_Tree.String_Elements.Table (Dirs_Id);
4290 Dirs_Id := Dir_Elem.Next;
4292 if Data.Library_ALI_Dir =
4293 Path_Name_Type (Dir_Elem.Value)
4295 Err_Vars.Error_Msg_File_1 :=
4296 File_Name_Type (Dir_Elem.Value);
4297 Err_Vars.Error_Msg_Name_1 :=
4298 In_Tree.Projects.Table (Pid).Name;
4302 "library 'A'L'I directory cannot " &
4303 "be the same as source directory " &
4305 Lib_ALI_Dir.Location);
4307 exit ALI_Project_Loop;
4309 end loop ALI_Dir_Loop;
4311 end loop ALI_Project_Loop;
4315 Data.Library_ALI_Dir := No_Path;
4316 Data.Display_Library_ALI_Dir := No_Path;
4318 elsif Current_Verbosity = High then
4320 -- Display the Library ALI directory in high
4323 Write_Str ("Library ALI directory =""");
4325 (Get_Name_String (Data.Display_Library_ALI_Dir));
4333 pragma Assert (Lib_Version.Kind = Single);
4335 if Lib_Version.Value = Empty_String then
4336 if Current_Verbosity = High then
4337 Write_Line ("No library version specified");
4341 Data.Lib_Internal_Name := Lib_Version.Value;
4344 pragma Assert (The_Lib_Kind.Kind = Single);
4346 if The_Lib_Kind.Value = Empty_String then
4347 if Current_Verbosity = High then
4348 Write_Line ("No library kind specified");
4352 Get_Name_String (The_Lib_Kind.Value);
4355 Kind_Name : constant String :=
4356 To_Lower (Name_Buffer (1 .. Name_Len));
4358 OK : Boolean := True;
4361 if Kind_Name = "static" then
4362 Data.Library_Kind := Static;
4364 elsif Kind_Name = "dynamic" then
4365 Data.Library_Kind := Dynamic;
4367 elsif Kind_Name = "relocatable" then
4368 Data.Library_Kind := Relocatable;
4373 "illegal value for Library_Kind",
4374 The_Lib_Kind.Location);
4378 if Current_Verbosity = High and then OK then
4379 Write_Str ("Library kind = ");
4380 Write_Line (Kind_Name);
4383 if Data.Library_Kind /= Static and then
4384 Support_For_Libraries = Prj.Static_Only
4388 "only static libraries are supported " &
4390 The_Lib_Kind.Location);
4391 Data.Library := False;
4396 if Data.Library then
4397 if Current_Verbosity = High then
4398 Write_Line ("This is a library project file");
4401 if Get_Mode = Multi_Language then
4402 Check_Library (Data.Extends, Extends => True);
4404 Imported_Project_List := Data.Imported_Projects;
4405 while Imported_Project_List /= Empty_Project_List loop
4407 (In_Tree.Project_Lists.Table
4408 (Imported_Project_List).Project,
4410 Imported_Project_List :=
4411 In_Tree.Project_Lists.Table
4412 (Imported_Project_List).Next;
4420 if Data.Extends /= No_Project then
4421 In_Tree.Projects.Table (Data.Extends).Library := False;
4423 end Check_Library_Attributes;
4425 --------------------------
4426 -- Check_Package_Naming --
4427 --------------------------
4429 procedure Check_Package_Naming
4430 (Project : Project_Id;
4431 In_Tree : Project_Tree_Ref;
4432 Data : in out Project_Data)
4434 Naming_Id : constant Package_Id :=
4435 Util.Value_Of (Name_Naming, Data.Decl.Packages, In_Tree);
4437 Naming : Package_Element;
4440 -- If there is a package Naming, we will put in Data.Naming
4441 -- what is in this package Naming.
4443 if Naming_Id /= No_Package then
4444 Naming := In_Tree.Packages.Table (Naming_Id);
4446 if Current_Verbosity = High then
4447 Write_Line ("Checking ""Naming"".");
4450 -- Check Spec_Suffix
4453 Spec_Suffixs : Array_Element_Id :=
4459 Suffix : Array_Element_Id;
4460 Element : Array_Element;
4461 Suffix2 : Array_Element_Id;
4464 -- If some suffixes have been specified, we make sure that
4465 -- for each language for which a default suffix has been
4466 -- specified, there is a suffix specified, either the one
4467 -- in the project file or if there were none, the default.
4469 if Spec_Suffixs /= No_Array_Element then
4470 Suffix := Data.Naming.Spec_Suffix;
4472 while Suffix /= No_Array_Element loop
4474 In_Tree.Array_Elements.Table (Suffix);
4475 Suffix2 := Spec_Suffixs;
4477 while Suffix2 /= No_Array_Element loop
4478 exit when In_Tree.Array_Elements.Table
4479 (Suffix2).Index = Element.Index;
4480 Suffix2 := In_Tree.Array_Elements.Table
4484 -- There is a registered default suffix, but no
4485 -- suffix specified in the project file.
4486 -- Add the default to the array.
4488 if Suffix2 = No_Array_Element then
4489 Array_Element_Table.Increment_Last
4490 (In_Tree.Array_Elements);
4491 In_Tree.Array_Elements.Table
4492 (Array_Element_Table.Last
4493 (In_Tree.Array_Elements)) :=
4494 (Index => Element.Index,
4495 Src_Index => Element.Src_Index,
4496 Index_Case_Sensitive => False,
4497 Value => Element.Value,
4498 Next => Spec_Suffixs);
4499 Spec_Suffixs := Array_Element_Table.Last
4500 (In_Tree.Array_Elements);
4503 Suffix := Element.Next;
4506 -- Put the resulting array as the specification suffixes
4508 Data.Naming.Spec_Suffix := Spec_Suffixs;
4513 Current : Array_Element_Id;
4514 Element : Array_Element;
4517 Current := Data.Naming.Spec_Suffix;
4518 while Current /= No_Array_Element loop
4519 Element := In_Tree.Array_Elements.Table (Current);
4520 Get_Name_String (Element.Value.Value);
4522 if Name_Len = 0 then
4525 "Spec_Suffix cannot be empty",
4526 Element.Value.Location);
4529 In_Tree.Array_Elements.Table (Current) := Element;
4530 Current := Element.Next;
4534 -- Check Body_Suffix
4537 Impl_Suffixs : Array_Element_Id :=
4543 Suffix : Array_Element_Id;
4544 Element : Array_Element;
4545 Suffix2 : Array_Element_Id;
4548 -- If some suffixes have been specified, we make sure that
4549 -- for each language for which a default suffix has been
4550 -- specified, there is a suffix specified, either the one
4551 -- in the project file or if there were none, the default.
4553 if Impl_Suffixs /= No_Array_Element then
4554 Suffix := Data.Naming.Body_Suffix;
4555 while Suffix /= No_Array_Element loop
4557 In_Tree.Array_Elements.Table (Suffix);
4559 Suffix2 := Impl_Suffixs;
4560 while Suffix2 /= No_Array_Element loop
4561 exit when In_Tree.Array_Elements.Table
4562 (Suffix2).Index = Element.Index;
4563 Suffix2 := In_Tree.Array_Elements.Table
4567 -- There is a registered default suffix, but no suffix was
4568 -- specified in the project file. Add default to the array.
4570 if Suffix2 = No_Array_Element then
4571 Array_Element_Table.Increment_Last
4572 (In_Tree.Array_Elements);
4573 In_Tree.Array_Elements.Table
4574 (Array_Element_Table.Last
4575 (In_Tree.Array_Elements)) :=
4576 (Index => Element.Index,
4577 Src_Index => Element.Src_Index,
4578 Index_Case_Sensitive => False,
4579 Value => Element.Value,
4580 Next => Impl_Suffixs);
4581 Impl_Suffixs := Array_Element_Table.Last
4582 (In_Tree.Array_Elements);
4585 Suffix := Element.Next;
4588 -- Put the resulting array as the implementation suffixes
4590 Data.Naming.Body_Suffix := Impl_Suffixs;
4595 Current : Array_Element_Id;
4596 Element : Array_Element;
4599 Current := Data.Naming.Body_Suffix;
4600 while Current /= No_Array_Element loop
4601 Element := In_Tree.Array_Elements.Table (Current);
4602 Get_Name_String (Element.Value.Value);
4604 if Name_Len = 0 then
4607 "Body_Suffix cannot be empty",
4608 Element.Value.Location);
4611 In_Tree.Array_Elements.Table (Current) := Element;
4612 Current := Element.Next;
4616 -- Get the exceptions, if any
4618 Data.Naming.Specification_Exceptions :=
4620 (Name_Specification_Exceptions,
4621 In_Arrays => Naming.Decl.Arrays,
4622 In_Tree => In_Tree);
4624 Data.Naming.Implementation_Exceptions :=
4626 (Name_Implementation_Exceptions,
4627 In_Arrays => Naming.Decl.Arrays,
4628 In_Tree => In_Tree);
4630 end Check_Package_Naming;
4632 ---------------------------------
4633 -- Check_Programming_Languages --
4634 ---------------------------------
4636 procedure Check_Programming_Languages
4637 (In_Tree : Project_Tree_Ref;
4638 Project : Project_Id;
4639 Data : in out Project_Data)
4641 Languages : Variable_Value := Nil_Variable_Value;
4642 Def_Lang : Variable_Value := Nil_Variable_Value;
4643 Def_Lang_Id : Name_Id;
4646 Data.First_Language_Processing := No_Language_Index;
4648 Prj.Util.Value_Of (Name_Languages, Data.Decl.Attributes, In_Tree);
4651 (Name_Default_Language, Data.Decl.Attributes, In_Tree);
4652 Data.Ada_Sources_Present := Data.Source_Dirs /= Nil_String;
4653 Data.Other_Sources_Present := Data.Source_Dirs /= Nil_String;
4655 if Data.Source_Dirs /= Nil_String then
4657 -- Check if languages are specified in this project
4659 if Languages.Default then
4661 -- Attribute Languages is not specified. So, it defaults to
4662 -- a project of the default language only.
4664 Name_List_Table.Increment_Last (In_Tree.Name_Lists);
4665 Data.Languages := Name_List_Table.Last (In_Tree.Name_Lists);
4667 -- In Ada_Only mode, the default language is Ada
4669 if Get_Mode = Ada_Only then
4670 In_Tree.Name_Lists.Table (Data.Languages) :=
4671 (Name => Name_Ada, Next => No_Name_List);
4673 -- Attribute Languages is not specified. So, it defaults to
4674 -- a project of language Ada only.
4676 Data.Langs (Ada_Language_Index) := True;
4678 -- No sources of languages other than Ada
4680 Data.Other_Sources_Present := False;
4683 -- If the configuration file does not define a language either
4685 if Def_Lang.Default then
4686 if not Default_Language_Is_Ada then
4690 "no languages defined for this project",
4692 Def_Lang_Id := No_Name;
4694 Def_Lang_Id := Name_Ada;
4698 -- ??? Are we supporting a single default language in the
4699 -- configuration file ?
4700 Get_Name_String (Def_Lang.Value);
4701 To_Lower (Name_Buffer (1 .. Name_Len));
4702 Def_Lang_Id := Name_Find;
4705 if Def_Lang_Id /= No_Name then
4706 In_Tree.Name_Lists.Table (Data.Languages) :=
4707 (Name => Def_Lang_Id, Next => No_Name_List);
4709 Language_Data_Table.Increment_Last (In_Tree.Languages_Data);
4711 Data.First_Language_Processing :=
4712 Language_Data_Table.Last (In_Tree.Languages_Data);
4713 In_Tree.Languages_Data.Table
4714 (Data.First_Language_Processing) := No_Language_Data;
4715 In_Tree.Languages_Data.Table
4716 (Data.First_Language_Processing).Name := Def_Lang_Id;
4717 Get_Name_String (Def_Lang_Id);
4718 Name_Buffer (1) := GNAT.Case_Util.To_Upper (Name_Buffer (1));
4719 In_Tree.Languages_Data.Table
4720 (Data.First_Language_Processing).Display_Name := Name_Find;
4722 if Def_Lang_Id = Name_Ada then
4723 In_Tree.Languages_Data.Table
4724 (Data.First_Language_Processing).Config.Kind
4726 In_Tree.Languages_Data.Table
4727 (Data.First_Language_Processing).Config.Dependency_Kind
4729 Data.Unit_Based_Language_Name := Name_Ada;
4730 Data.Unit_Based_Language_Index :=
4731 Data.First_Language_Processing;
4733 In_Tree.Languages_Data.Table
4734 (Data.First_Language_Processing).Config.Kind
4742 Current : String_List_Id := Languages.Values;
4743 Element : String_Element;
4744 Lang_Name : Name_Id;
4745 Index : Language_Index;
4746 Lang_Data : Language_Data;
4747 NL_Id : Name_List_Index := No_Name_List;
4750 if Get_Mode = Ada_Only then
4752 -- Assume that there is no language specified yet
4754 Data.Other_Sources_Present := False;
4755 Data.Ada_Sources_Present := False;
4758 -- If there are no languages declared, there are no sources
4760 if Current = Nil_String then
4761 Data.Source_Dirs := Nil_String;
4763 if Data.Qualifier = Standard then
4767 "a standard project cannot have no language declared",
4768 Languages.Location);
4772 -- Look through all the languages specified in attribute
4775 while Current /= Nil_String loop
4777 In_Tree.String_Elements.Table (Current);
4778 Get_Name_String (Element.Value);
4779 To_Lower (Name_Buffer (1 .. Name_Len));
4780 Lang_Name := Name_Find;
4782 NL_Id := Data.Languages;
4783 while NL_Id /= No_Name_List loop
4785 Lang_Name = In_Tree.Name_Lists.Table (NL_Id).Name;
4786 NL_Id := In_Tree.Name_Lists.Table (NL_Id).Next;
4789 if NL_Id = No_Name_List then
4790 Name_List_Table.Increment_Last (In_Tree.Name_Lists);
4792 if Data.Languages = No_Name_List then
4794 Name_List_Table.Last (In_Tree.Name_Lists);
4797 NL_Id := Data.Languages;
4798 while In_Tree.Name_Lists.Table (NL_Id).Next /=
4801 NL_Id := In_Tree.Name_Lists.Table (NL_Id).Next;
4804 In_Tree.Name_Lists.Table (NL_Id).Next :=
4805 Name_List_Table.Last (In_Tree.Name_Lists);
4808 NL_Id := Name_List_Table.Last (In_Tree.Name_Lists);
4809 In_Tree.Name_Lists.Table (NL_Id) :=
4810 (Lang_Name, No_Name_List);
4812 if Get_Mode = Ada_Only then
4813 Index := Language_Indexes.Get (Lang_Name);
4815 if Index = No_Language_Index then
4816 Add_Language_Name (Lang_Name);
4817 Index := Last_Language_Index;
4820 Set (Index, True, Data, In_Tree);
4821 Set (Language_Processing =>
4822 Default_Language_Processing_Data,
4823 For_Language => Index,
4825 In_Tree => In_Tree);
4827 if Index = Ada_Language_Index then
4828 Data.Ada_Sources_Present := True;
4831 Data.Other_Sources_Present := True;
4835 Language_Data_Table.Increment_Last
4836 (In_Tree.Languages_Data);
4838 Language_Data_Table.Last (In_Tree.Languages_Data);
4839 Lang_Data.Name := Lang_Name;
4840 Lang_Data.Display_Name := Element.Value;
4841 Lang_Data.Next := Data.First_Language_Processing;
4843 if Lang_Name = Name_Ada then
4844 Lang_Data.Config.Kind := Unit_Based;
4845 Lang_Data.Config.Dependency_Kind := ALI_File;
4846 Data.Unit_Based_Language_Name := Name_Ada;
4847 Data.Unit_Based_Language_Index := Index;
4850 Lang_Data.Config.Kind := File_Based;
4851 Lang_Data.Config.Dependency_Kind := None;
4854 In_Tree.Languages_Data.Table (Index) := Lang_Data;
4855 Data.First_Language_Processing := Index;
4859 Current := Element.Next;
4865 end Check_Programming_Languages;
4871 function Check_Project
4873 Root_Project : Project_Id;
4874 In_Tree : Project_Tree_Ref;
4875 Extending : Boolean) return Boolean
4878 if P = Root_Project then
4881 elsif Extending then
4883 Data : Project_Data := In_Tree.Projects.Table (Root_Project);
4886 while Data.Extends /= No_Project loop
4887 if P = Data.Extends then
4891 Data := In_Tree.Projects.Table (Data.Extends);
4899 -------------------------------
4900 -- Check_Stand_Alone_Library --
4901 -------------------------------
4903 procedure Check_Stand_Alone_Library
4904 (Project : Project_Id;
4905 In_Tree : Project_Tree_Ref;
4906 Data : in out Project_Data;
4907 Current_Dir : String;
4908 Extending : Boolean)
4910 Lib_Interfaces : constant Prj.Variable_Value :=
4912 (Snames.Name_Library_Interface,
4913 Data.Decl.Attributes,
4916 Lib_Auto_Init : constant Prj.Variable_Value :=
4918 (Snames.Name_Library_Auto_Init,
4919 Data.Decl.Attributes,
4922 Lib_Src_Dir : constant Prj.Variable_Value :=
4924 (Snames.Name_Library_Src_Dir,
4925 Data.Decl.Attributes,
4928 Lib_Symbol_File : constant Prj.Variable_Value :=
4930 (Snames.Name_Library_Symbol_File,
4931 Data.Decl.Attributes,
4934 Lib_Symbol_Policy : constant Prj.Variable_Value :=
4936 (Snames.Name_Library_Symbol_Policy,
4937 Data.Decl.Attributes,
4940 Lib_Ref_Symbol_File : constant Prj.Variable_Value :=
4942 (Snames.Name_Library_Reference_Symbol_File,
4943 Data.Decl.Attributes,
4946 Auto_Init_Supported : Boolean;
4947 OK : Boolean := True;
4949 Next_Proj : Project_Id;
4952 if Get_Mode = Multi_Language then
4953 Auto_Init_Supported := Data.Config.Auto_Init_Supported;
4955 Auto_Init_Supported :=
4956 MLib.Tgt.Standalone_Library_Auto_Init_Is_Supported;
4959 pragma Assert (Lib_Interfaces.Kind = List);
4961 -- It is a stand-alone library project file if attribute
4962 -- Library_Interface is defined.
4964 if not Lib_Interfaces.Default then
4965 SAL_Library : declare
4966 Interfaces : String_List_Id := Lib_Interfaces.Values;
4967 Interface_ALIs : String_List_Id := Nil_String;
4969 The_Unit_Id : Unit_Index;
4970 The_Unit_Data : Unit_Data;
4972 procedure Add_ALI_For (Source : File_Name_Type);
4973 -- Add an ALI file name to the list of Interface ALIs
4979 procedure Add_ALI_For (Source : File_Name_Type) is
4981 Get_Name_String (Source);
4984 ALI : constant String :=
4985 ALI_File_Name (Name_Buffer (1 .. Name_Len));
4986 ALI_Name_Id : Name_Id;
4989 Name_Len := ALI'Length;
4990 Name_Buffer (1 .. Name_Len) := ALI;
4991 ALI_Name_Id := Name_Find;
4993 String_Element_Table.Increment_Last
4994 (In_Tree.String_Elements);
4995 In_Tree.String_Elements.Table
4996 (String_Element_Table.Last
4997 (In_Tree.String_Elements)) :=
4998 (Value => ALI_Name_Id,
5000 Display_Value => ALI_Name_Id,
5002 In_Tree.String_Elements.Table
5003 (Interfaces).Location,
5005 Next => Interface_ALIs);
5006 Interface_ALIs := String_Element_Table.Last
5007 (In_Tree.String_Elements);
5011 -- Start of processing for SAL_Library
5014 Data.Standalone_Library := True;
5016 -- Library_Interface cannot be an empty list
5018 if Interfaces = Nil_String then
5021 "Library_Interface cannot be an empty list",
5022 Lib_Interfaces.Location);
5025 -- Process each unit name specified in the attribute
5026 -- Library_Interface.
5028 while Interfaces /= Nil_String loop
5030 (In_Tree.String_Elements.Table (Interfaces).Value);
5031 To_Lower (Name_Buffer (1 .. Name_Len));
5033 if Name_Len = 0 then
5036 "an interface cannot be an empty string",
5037 In_Tree.String_Elements.Table (Interfaces).Location);
5041 Error_Msg_Name_1 := Unit;
5043 if Get_Mode = Ada_Only then
5045 Units_Htable.Get (In_Tree.Units_HT, Unit);
5047 if The_Unit_Id = No_Unit_Index then
5051 In_Tree.String_Elements.Table
5052 (Interfaces).Location);
5055 -- Check that the unit is part of the project
5058 In_Tree.Units.Table (The_Unit_Id);
5060 if The_Unit_Data.File_Names (Body_Part).Name /= No_File
5061 and then The_Unit_Data.File_Names (Body_Part).Path /=
5065 (The_Unit_Data.File_Names (Body_Part).Project,
5066 Project, In_Tree, Extending)
5068 -- There is a body for this unit.
5069 -- If there is no spec, we need to check
5070 -- that it is not a subunit.
5072 if The_Unit_Data.File_Names
5073 (Specification).Name = No_File
5076 Src_Ind : Source_File_Index;
5079 Src_Ind := Sinput.P.Load_Project_File
5081 (The_Unit_Data.File_Names
5084 if Sinput.P.Source_File_Is_Subunit
5089 "%% is a subunit; " &
5090 "it cannot be an interface",
5092 String_Elements.Table
5093 (Interfaces).Location);
5098 -- The unit is not a subunit, so we add
5099 -- to the Interface ALIs the ALI file
5100 -- corresponding to the body.
5103 (The_Unit_Data.File_Names (Body_Part).Name);
5108 "%% is not an unit of this project",
5109 In_Tree.String_Elements.Table
5110 (Interfaces).Location);
5113 elsif The_Unit_Data.File_Names
5114 (Specification).Name /= No_File
5115 and then The_Unit_Data.File_Names
5116 (Specification).Path /= Slash
5117 and then Check_Project
5118 (The_Unit_Data.File_Names
5119 (Specification).Project,
5120 Project, In_Tree, Extending)
5123 -- The unit is part of the project, it has
5124 -- a spec, but no body. We add to the Interface
5125 -- ALIs the ALI file corresponding to the spec.
5128 (The_Unit_Data.File_Names (Specification).Name);
5133 "%% is not an unit of this project",
5134 In_Tree.String_Elements.Table
5135 (Interfaces).Location);
5140 -- Multi_Language mode
5142 Next_Proj := Data.Extends;
5143 Source := Data.First_Source;
5146 while Source /= No_Source and then
5147 In_Tree.Sources.Table (Source).Unit /= Unit
5150 In_Tree.Sources.Table (Source).Next_In_Project;
5153 exit when Source /= No_Source or else
5154 Next_Proj = No_Project;
5157 In_Tree.Projects.Table (Next_Proj).First_Source;
5159 In_Tree.Projects.Table (Next_Proj).Extends;
5162 if Source /= No_Source then
5163 if In_Tree.Sources.Table (Source).Kind = Sep then
5164 Source := No_Source;
5166 elsif In_Tree.Sources.Table (Source).Kind = Spec
5168 In_Tree.Sources.Table (Source).Other_Part /=
5171 Source := In_Tree.Sources.Table (Source).Other_Part;
5175 if Source /= No_Source then
5176 if In_Tree.Sources.Table (Source).Project /= Project
5180 In_Tree.Sources.Table (Source).Project,
5183 Source := No_Source;
5187 if Source = No_Source then
5190 "%% is not an unit of this project",
5191 In_Tree.String_Elements.Table
5192 (Interfaces).Location);
5195 if In_Tree.Sources.Table (Source).Kind = Spec and then
5196 In_Tree.Sources.Table (Source).Other_Part /=
5200 In_Tree.Sources.Table (Source).Other_Part;
5203 String_Element_Table.Increment_Last
5204 (In_Tree.String_Elements);
5205 In_Tree.String_Elements.Table
5206 (String_Element_Table.Last
5207 (In_Tree.String_Elements)) :=
5209 Name_Id (In_Tree.Sources.Table (Source).Dep_Name),
5212 Name_Id (In_Tree.Sources.Table (Source).Dep_Name),
5214 In_Tree.String_Elements.Table
5215 (Interfaces).Location,
5217 Next => Interface_ALIs);
5218 Interface_ALIs := String_Element_Table.Last
5219 (In_Tree.String_Elements);
5227 In_Tree.String_Elements.Table (Interfaces).Next;
5230 -- Put the list of Interface ALIs in the project data
5232 Data.Lib_Interface_ALIs := Interface_ALIs;
5234 -- Check value of attribute Library_Auto_Init and set
5235 -- Lib_Auto_Init accordingly.
5237 if Lib_Auto_Init.Default then
5239 -- If no attribute Library_Auto_Init is declared, then set auto
5240 -- init only if it is supported.
5242 Data.Lib_Auto_Init := Auto_Init_Supported;
5245 Get_Name_String (Lib_Auto_Init.Value);
5246 To_Lower (Name_Buffer (1 .. Name_Len));
5248 if Name_Buffer (1 .. Name_Len) = "false" then
5249 Data.Lib_Auto_Init := False;
5251 elsif Name_Buffer (1 .. Name_Len) = "true" then
5252 if Auto_Init_Supported then
5253 Data.Lib_Auto_Init := True;
5256 -- Library_Auto_Init cannot be "true" if auto init is not
5261 "library auto init not supported " &
5263 Lib_Auto_Init.Location);
5269 "invalid value for attribute Library_Auto_Init",
5270 Lib_Auto_Init.Location);
5275 -- If attribute Library_Src_Dir is defined and not the empty string,
5276 -- check if the directory exist and is not the object directory or
5277 -- one of the source directories. This is the directory where copies
5278 -- of the interface sources will be copied. Note that this directory
5279 -- may be the library directory.
5281 if Lib_Src_Dir.Value /= Empty_String then
5283 Dir_Id : constant File_Name_Type :=
5284 File_Name_Type (Lib_Src_Dir.Value);
5291 Data.Display_Directory,
5292 Data.Library_Src_Dir,
5293 Data.Display_Library_Src_Dir,
5294 Create => "library source copy",
5295 Current_Dir => Current_Dir,
5296 Location => Lib_Src_Dir.Location);
5298 -- If directory does not exist, report an error
5300 if Data.Library_Src_Dir = No_Path then
5302 -- Get the absolute name of the library directory that does
5303 -- not exist, to report an error.
5306 Dir_Name : constant String :=
5307 Get_Name_String (Dir_Id);
5310 if Is_Absolute_Path (Dir_Name) then
5311 Err_Vars.Error_Msg_File_1 := Dir_Id;
5314 Get_Name_String (Data.Directory);
5316 if Name_Buffer (Name_Len) /=
5319 Name_Len := Name_Len + 1;
5320 Name_Buffer (Name_Len) :=
5321 Directory_Separator;
5326 Name_Len + Dir_Name'Length) :=
5328 Name_Len := Name_Len + Dir_Name'Length;
5329 Err_Vars.Error_Msg_Name_1 := Name_Find;
5334 Error_Msg_File_1 := Dir_Id;
5337 "Directory { does not exist",
5338 Lib_Src_Dir.Location);
5341 -- Report error if it is the same as the object directory
5343 elsif Data.Library_Src_Dir = Data.Object_Directory then
5346 "directory to copy interfaces cannot be " &
5347 "the object directory",
5348 Lib_Src_Dir.Location);
5349 Data.Library_Src_Dir := No_Path;
5353 Src_Dirs : String_List_Id;
5354 Src_Dir : String_Element;
5357 -- Interface copy directory cannot be one of the source
5358 -- directory of the current project.
5360 Src_Dirs := Data.Source_Dirs;
5361 while Src_Dirs /= Nil_String loop
5362 Src_Dir := In_Tree.String_Elements.Table (Src_Dirs);
5364 -- Report error if it is one of the source directories
5366 if Data.Library_Src_Dir =
5367 Path_Name_Type (Src_Dir.Value)
5371 "directory to copy interfaces cannot " &
5372 "be one of the source directories",
5373 Lib_Src_Dir.Location);
5374 Data.Library_Src_Dir := No_Path;
5378 Src_Dirs := Src_Dir.Next;
5381 if Data.Library_Src_Dir /= No_Path then
5383 -- It cannot be a source directory of any other
5386 Project_Loop : for Pid in 1 ..
5387 Project_Table.Last (In_Tree.Projects)
5390 In_Tree.Projects.Table (Pid).Source_Dirs;
5391 Dir_Loop : while Src_Dirs /= Nil_String loop
5393 In_Tree.String_Elements.Table (Src_Dirs);
5395 -- Report error if it is one of the source
5398 if Data.Library_Src_Dir =
5399 Path_Name_Type (Src_Dir.Value)
5402 File_Name_Type (Src_Dir.Value);
5404 In_Tree.Projects.Table (Pid).Name;
5407 "directory to copy interfaces cannot " &
5408 "be the same as source directory { of " &
5410 Lib_Src_Dir.Location);
5411 Data.Library_Src_Dir := No_Path;
5415 Src_Dirs := Src_Dir.Next;
5417 end loop Project_Loop;
5421 -- In high verbosity, if there is a valid Library_Src_Dir,
5422 -- display its path name.
5424 if Data.Library_Src_Dir /= No_Path
5425 and then Current_Verbosity = High
5427 Write_Str ("Directory to copy interfaces =""");
5428 Write_Str (Get_Name_String (Data.Library_Src_Dir));
5435 -- Check the symbol related attributes
5437 -- First, the symbol policy
5439 if not Lib_Symbol_Policy.Default then
5441 Value : constant String :=
5443 (Get_Name_String (Lib_Symbol_Policy.Value));
5446 -- Symbol policy must hove one of a limited number of values
5448 if Value = "autonomous" or else Value = "default" then
5449 Data.Symbol_Data.Symbol_Policy := Autonomous;
5451 elsif Value = "compliant" then
5452 Data.Symbol_Data.Symbol_Policy := Compliant;
5454 elsif Value = "controlled" then
5455 Data.Symbol_Data.Symbol_Policy := Controlled;
5457 elsif Value = "restricted" then
5458 Data.Symbol_Data.Symbol_Policy := Restricted;
5460 elsif Value = "direct" then
5461 Data.Symbol_Data.Symbol_Policy := Direct;
5466 "illegal value for Library_Symbol_Policy",
5467 Lib_Symbol_Policy.Location);
5472 -- If attribute Library_Symbol_File is not specified, symbol policy
5473 -- cannot be Restricted.
5475 if Lib_Symbol_File.Default then
5476 if Data.Symbol_Data.Symbol_Policy = Restricted then
5479 "Library_Symbol_File needs to be defined when " &
5480 "symbol policy is Restricted",
5481 Lib_Symbol_Policy.Location);
5485 -- Library_Symbol_File is defined
5487 Data.Symbol_Data.Symbol_File :=
5488 Path_Name_Type (Lib_Symbol_File.Value);
5490 Get_Name_String (Lib_Symbol_File.Value);
5492 if Name_Len = 0 then
5495 "symbol file name cannot be an empty string",
5496 Lib_Symbol_File.Location);
5499 OK := not Is_Absolute_Path (Name_Buffer (1 .. Name_Len));
5502 for J in 1 .. Name_Len loop
5503 if Name_Buffer (J) = '/'
5504 or else Name_Buffer (J) = Directory_Separator
5513 Error_Msg_File_1 := File_Name_Type (Lib_Symbol_File.Value);
5516 "symbol file name { is illegal. " &
5517 "Name cannot include directory info.",
5518 Lib_Symbol_File.Location);
5523 -- If attribute Library_Reference_Symbol_File is not defined,
5524 -- symbol policy cannot be Compliant or Controlled.
5526 if Lib_Ref_Symbol_File.Default then
5527 if Data.Symbol_Data.Symbol_Policy = Compliant
5528 or else Data.Symbol_Data.Symbol_Policy = Controlled
5532 "a reference symbol file need to be defined",
5533 Lib_Symbol_Policy.Location);
5537 -- Library_Reference_Symbol_File is defined, check file exists
5539 Data.Symbol_Data.Reference :=
5540 Path_Name_Type (Lib_Ref_Symbol_File.Value);
5542 Get_Name_String (Lib_Ref_Symbol_File.Value);
5544 if Name_Len = 0 then
5547 "reference symbol file name cannot be an empty string",
5548 Lib_Symbol_File.Location);
5551 if not Is_Absolute_Path (Name_Buffer (1 .. Name_Len)) then
5553 Add_Str_To_Name_Buffer (Get_Name_String (Data.Directory));
5554 Add_Char_To_Name_Buffer (Directory_Separator);
5555 Add_Str_To_Name_Buffer
5556 (Get_Name_String (Lib_Ref_Symbol_File.Value));
5557 Data.Symbol_Data.Reference := Name_Find;
5560 if not Is_Regular_File
5561 (Get_Name_String (Data.Symbol_Data.Reference))
5564 File_Name_Type (Lib_Ref_Symbol_File.Value);
5566 -- For controlled and direct symbol policies, it is an error
5567 -- if the reference symbol file does not exist. For other
5568 -- symbol policies, this is just a warning
5571 Data.Symbol_Data.Symbol_Policy /= Controlled
5572 and then Data.Symbol_Data.Symbol_Policy /= Direct;
5576 "<library reference symbol file { does not exist",
5577 Lib_Ref_Symbol_File.Location);
5579 -- In addition in the non-controlled case, if symbol policy
5580 -- is Compliant, it is changed to Autonomous, because there
5581 -- is no reference to check against, and we don't want to
5582 -- fail in this case.
5584 if Data.Symbol_Data.Symbol_Policy /= Controlled then
5585 if Data.Symbol_Data.Symbol_Policy = Compliant then
5586 Data.Symbol_Data.Symbol_Policy := Autonomous;
5591 -- If both the reference symbol file and the symbol file are
5592 -- defined, then check that they are not the same file.
5594 if Data.Symbol_Data.Symbol_File /= No_Path then
5595 Get_Name_String (Data.Symbol_Data.Symbol_File);
5597 if Name_Len > 0 then
5599 Symb_Path : constant String :=
5602 (Data.Object_Directory) &
5603 Directory_Separator &
5604 Name_Buffer (1 .. Name_Len),
5605 Directory => Current_Dir,
5607 Opt.Follow_Links_For_Files);
5608 Ref_Path : constant String :=
5611 (Data.Symbol_Data.Reference),
5612 Directory => Current_Dir,
5614 Opt.Follow_Links_For_Files);
5616 if Symb_Path = Ref_Path then
5619 "library reference symbol file and library" &
5620 " symbol file cannot be the same file",
5621 Lib_Ref_Symbol_File.Location);
5629 end Check_Stand_Alone_Library;
5631 ----------------------------
5632 -- Compute_Directory_Last --
5633 ----------------------------
5635 function Compute_Directory_Last (Dir : String) return Natural is
5638 and then (Dir (Dir'Last - 1) = Directory_Separator
5639 or else Dir (Dir'Last - 1) = '/')
5641 return Dir'Last - 1;
5645 end Compute_Directory_Last;
5652 (Project : Project_Id;
5653 In_Tree : Project_Tree_Ref;
5655 Flag_Location : Source_Ptr)
5657 Real_Location : Source_Ptr := Flag_Location;
5658 Error_Buffer : String (1 .. 5_000);
5659 Error_Last : Natural := 0;
5660 Name_Number : Natural := 0;
5661 File_Number : Natural := 0;
5662 First : Positive := Msg'First;
5665 procedure Add (C : Character);
5666 -- Add a character to the buffer
5668 procedure Add (S : String);
5669 -- Add a string to the buffer
5672 -- Add a name to the buffer
5675 -- Add a file name to the buffer
5681 procedure Add (C : Character) is
5683 Error_Last := Error_Last + 1;
5684 Error_Buffer (Error_Last) := C;
5687 procedure Add (S : String) is
5689 Error_Buffer (Error_Last + 1 .. Error_Last + S'Length) := S;
5690 Error_Last := Error_Last + S'Length;
5697 procedure Add_File is
5698 File : File_Name_Type;
5702 File_Number := File_Number + 1;
5706 File := Err_Vars.Error_Msg_File_1;
5708 File := Err_Vars.Error_Msg_File_2;
5710 File := Err_Vars.Error_Msg_File_3;
5715 Get_Name_String (File);
5716 Add (Name_Buffer (1 .. Name_Len));
5724 procedure Add_Name is
5729 Name_Number := Name_Number + 1;
5733 Name := Err_Vars.Error_Msg_Name_1;
5735 Name := Err_Vars.Error_Msg_Name_2;
5737 Name := Err_Vars.Error_Msg_Name_3;
5742 Get_Name_String (Name);
5743 Add (Name_Buffer (1 .. Name_Len));
5747 -- Start of processing for Error_Msg
5750 -- If location of error is unknown, use the location of the project
5752 if Real_Location = No_Location then
5753 Real_Location := In_Tree.Projects.Table (Project).Location;
5756 if Error_Report = null then
5757 Prj.Err.Error_Msg (Msg, Real_Location);
5761 -- Ignore continuation character
5763 if Msg (First) = '\' then
5767 -- Warning character is always the first one in this package
5768 -- this is an undocumented kludge???
5770 if Msg (First) = '?' then
5774 elsif Msg (First) = '<' then
5777 if Err_Vars.Error_Msg_Warn then
5783 while Index <= Msg'Last loop
5784 if Msg (Index) = '{' then
5787 elsif Msg (Index) = '%' then
5788 if Index < Msg'Last and then Msg (Index + 1) = '%' then
5800 Error_Report (Error_Buffer (1 .. Error_Last), Project, In_Tree);
5803 ----------------------
5804 -- Find_Ada_Sources --
5805 ----------------------
5807 procedure Find_Ada_Sources
5808 (Project : Project_Id;
5809 In_Tree : Project_Tree_Ref;
5810 Data : in out Project_Data;
5811 Current_Dir : String)
5813 Source_Dir : String_List_Id := Data.Source_Dirs;
5814 Element : String_Element;
5816 Current_Source : String_List_Id := Nil_String;
5817 Source_Recorded : Boolean := False;
5820 if Current_Verbosity = High then
5821 Write_Line ("Looking for sources:");
5824 -- For each subdirectory
5826 while Source_Dir /= Nil_String loop
5828 Source_Recorded := False;
5829 Element := In_Tree.String_Elements.Table (Source_Dir);
5830 if Element.Value /= No_Name then
5831 Get_Name_String (Element.Display_Value);
5834 Source_Directory : constant String :=
5835 Name_Buffer (1 .. Name_Len) & Directory_Separator;
5836 Dir_Last : constant Natural :=
5837 Compute_Directory_Last (Source_Directory);
5840 if Current_Verbosity = High then
5841 Write_Str ("Source_Dir = ");
5842 Write_Line (Source_Directory);
5845 -- We look at every entry in the source directory
5848 Source_Directory (Source_Directory'First .. Dir_Last));
5851 Read (Dir, Name_Buffer, Name_Len);
5853 if Current_Verbosity = High then
5854 Write_Str (" Checking ");
5855 Write_Line (Name_Buffer (1 .. Name_Len));
5858 exit when Name_Len = 0;
5861 File_Name : constant File_Name_Type := Name_Find;
5863 -- ??? We could probably optimize the following call:
5864 -- we need to resolve links only once for the
5865 -- directory itself, and then do a single call to
5866 -- readlink() for each file. Unfortunately that would
5867 -- require a change in Normalize_Pathname so that it
5868 -- has the option of not resolving links for its
5869 -- Directory parameter, only for Name.
5871 Path : constant String :=
5873 (Name => Name_Buffer (1 .. Name_Len),
5876 (Source_Directory'First .. Dir_Last),
5878 Opt.Follow_Links_For_Files,
5879 Case_Sensitive => True);
5881 Path_Name : Path_Name_Type;
5884 Name_Len := Path'Length;
5885 Name_Buffer (1 .. Name_Len) := Path;
5886 Path_Name := Name_Find;
5888 -- We attempt to register it as a source. However,
5889 -- there is no error if the file does not contain a
5890 -- valid source. But there is an error if we have a
5891 -- duplicate unit name.
5894 (File_Name => File_Name,
5895 Path_Name => Path_Name,
5899 Location => No_Location,
5900 Current_Source => Current_Source,
5901 Source_Recorded => Source_Recorded,
5902 Current_Dir => Current_Dir);
5911 when Directory_Error =>
5915 if Source_Recorded then
5916 In_Tree.String_Elements.Table (Source_Dir).Flag :=
5920 Source_Dir := Element.Next;
5923 if Current_Verbosity = High then
5924 Write_Line ("end Looking for sources.");
5927 end Find_Ada_Sources;
5933 procedure Find_Sources
5934 (Project : Project_Id;
5935 In_Tree : Project_Tree_Ref;
5936 Data : in out Project_Data;
5937 For_Language : Language_Index;
5938 Current_Dir : String)
5940 Source_Dir : String_List_Id;
5941 Element : String_Element;
5943 Current_Source : String_List_Id := Nil_String;
5944 Source_Recorded : Boolean := False;
5947 if Current_Verbosity = High then
5948 Write_Line ("Looking for sources:");
5951 -- Loop through subdirectories
5953 Source_Dir := Data.Source_Dirs;
5954 while Source_Dir /= Nil_String loop
5956 Source_Recorded := False;
5957 Element := In_Tree.String_Elements.Table (Source_Dir);
5959 if Element.Value /= No_Name then
5960 Get_Name_String (Element.Display_Value);
5963 Source_Directory : constant String :=
5964 Name_Buffer (1 .. Name_Len) &
5965 Directory_Separator;
5967 Dir_Last : constant Natural :=
5968 Compute_Directory_Last (Source_Directory);
5971 if Current_Verbosity = High then
5972 Write_Str ("Source_Dir = ");
5973 Write_Line (Source_Directory);
5976 -- We look to every entry in the source directory
5978 Open (Dir, Source_Directory
5979 (Source_Directory'First .. Dir_Last));
5982 Read (Dir, Name_Buffer, Name_Len);
5984 if Current_Verbosity = High then
5985 Write_Str (" Checking ");
5986 Write_Line (Name_Buffer (1 .. Name_Len));
5989 exit when Name_Len = 0;
5992 File_Name : constant File_Name_Type := Name_Find;
5993 Path : constant String :=
5995 (Name => Name_Buffer (1 .. Name_Len),
5996 Directory => Source_Directory
5997 (Source_Directory'First .. Dir_Last),
5998 Resolve_Links => Opt.Follow_Links_For_Files,
5999 Case_Sensitive => True);
6000 Path_Name : Path_Name_Type;
6003 Name_Len := Path'Length;
6004 Name_Buffer (1 .. Name_Len) := Path;
6005 Path_Name := Name_Find;
6007 if For_Language = Ada_Language_Index then
6009 -- We attempt to register it as a source. However,
6010 -- there is no error if the file does not contain
6011 -- a valid source. But there is an error if we have
6012 -- a duplicate unit name.
6015 (File_Name => File_Name,
6016 Path_Name => Path_Name,
6020 Location => No_Location,
6021 Current_Source => Current_Source,
6022 Source_Recorded => Source_Recorded,
6023 Current_Dir => Current_Dir);
6027 (File_Name => File_Name,
6028 Path_Name => Path_Name,
6032 Location => No_Location,
6033 Language => For_Language,
6035 Body_Suffix_Of (For_Language, Data, In_Tree),
6036 Naming_Exception => False);
6046 when Directory_Error =>
6050 if Source_Recorded then
6051 In_Tree.String_Elements.Table (Source_Dir).Flag :=
6055 Source_Dir := Element.Next;
6058 if Current_Verbosity = High then
6059 Write_Line ("end Looking for sources.");
6062 if For_Language = Ada_Language_Index then
6064 -- If we have looked for sources and found none, then it is an error,
6065 -- except if it is an extending project. If a non extending project
6066 -- is not supposed to contain any source files, then never call
6069 if Current_Source /= Nil_String then
6070 Data.Ada_Sources_Present := True;
6072 elsif Data.Extends = No_Project then
6073 Report_No_Sources (Project, "Ada", In_Tree, Data.Location);
6078 --------------------------------
6079 -- Free_Ada_Naming_Exceptions --
6080 --------------------------------
6082 procedure Free_Ada_Naming_Exceptions is
6084 Ada_Naming_Exception_Table.Set_Last (0);
6085 Ada_Naming_Exceptions.Reset;
6086 Reverse_Ada_Naming_Exceptions.Reset;
6087 end Free_Ada_Naming_Exceptions;
6089 ---------------------
6090 -- Get_Directories --
6091 ---------------------
6093 procedure Get_Directories
6094 (Project : Project_Id;
6095 In_Tree : Project_Tree_Ref;
6096 Current_Dir : String;
6097 Data : in out Project_Data)
6099 Object_Dir : constant Variable_Value :=
6101 (Name_Object_Dir, Data.Decl.Attributes, In_Tree);
6103 Exec_Dir : constant Variable_Value :=
6105 (Name_Exec_Dir, Data.Decl.Attributes, In_Tree);
6107 Source_Dirs : constant Variable_Value :=
6109 (Name_Source_Dirs, Data.Decl.Attributes, In_Tree);
6111 Excluded_Source_Dirs : constant Variable_Value :=
6113 (Name_Excluded_Source_Dirs,
6114 Data.Decl.Attributes,
6117 Source_Files : constant Variable_Value :=
6119 (Name_Source_Files, Data.Decl.Attributes, In_Tree);
6121 Last_Source_Dir : String_List_Id := Nil_String;
6123 procedure Find_Source_Dirs
6124 (From : File_Name_Type;
6125 Location : Source_Ptr;
6126 Removed : Boolean := False);
6127 -- Find one or several source directories, and add (or remove, if
6128 -- Removed is True) them to list of source directories of the project.
6130 ----------------------
6131 -- Find_Source_Dirs --
6132 ----------------------
6134 procedure Find_Source_Dirs
6135 (From : File_Name_Type;
6136 Location : Source_Ptr;
6137 Removed : Boolean := False)
6139 Directory : constant String := Get_Name_String (From);
6140 Element : String_Element;
6142 procedure Recursive_Find_Dirs (Path : Name_Id);
6143 -- Find all the subdirectories (recursively) of Path and add them
6144 -- to the list of source directories of the project.
6146 -------------------------
6147 -- Recursive_Find_Dirs --
6148 -------------------------
6150 procedure Recursive_Find_Dirs (Path : Name_Id) is
6152 Name : String (1 .. 250);
6154 List : String_List_Id;
6155 Prev : String_List_Id;
6156 Element : String_Element;
6157 Found : Boolean := False;
6159 Non_Canonical_Path : Name_Id := No_Name;
6160 Canonical_Path : Name_Id := No_Name;
6162 The_Path : constant String :=
6164 (Get_Name_String (Path),
6165 Directory => Current_Dir,
6166 Resolve_Links => Opt.Follow_Links_For_Dirs) &
6167 Directory_Separator;
6169 The_Path_Last : constant Natural :=
6170 Compute_Directory_Last (The_Path);
6173 Name_Len := The_Path_Last - The_Path'First + 1;
6174 Name_Buffer (1 .. Name_Len) :=
6175 The_Path (The_Path'First .. The_Path_Last);
6176 Non_Canonical_Path := Name_Find;
6178 if Osint.File_Names_Case_Sensitive then
6179 Canonical_Path := Non_Canonical_Path;
6181 Get_Name_String (Non_Canonical_Path);
6182 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
6183 Canonical_Path := Name_Find;
6186 -- To avoid processing the same directory several times, check
6187 -- if the directory is already in Recursive_Dirs. If it is, then
6188 -- there is nothing to do, just return. If it is not, put it there
6189 -- and continue recursive processing.
6192 if Recursive_Dirs.Get (Canonical_Path) then
6195 Recursive_Dirs.Set (Canonical_Path, True);
6199 -- Check if directory is already in list
6201 List := Data.Source_Dirs;
6203 while List /= Nil_String loop
6204 Element := In_Tree.String_Elements.Table (List);
6206 if Element.Value /= No_Name then
6207 Found := Element.Value = Canonical_Path;
6212 List := Element.Next;
6215 -- If directory is not already in list, put it there
6217 if (not Removed) and (not Found) then
6218 if Current_Verbosity = High then
6220 Write_Line (The_Path (The_Path'First .. The_Path_Last));
6223 String_Element_Table.Increment_Last
6224 (In_Tree.String_Elements);
6226 (Value => Canonical_Path,
6227 Display_Value => Non_Canonical_Path,
6228 Location => No_Location,
6233 -- Case of first source directory
6235 if Last_Source_Dir = Nil_String then
6236 Data.Source_Dirs := String_Element_Table.Last
6237 (In_Tree.String_Elements);
6239 -- Here we already have source directories
6242 -- Link the previous last to the new one
6244 In_Tree.String_Elements.Table
6245 (Last_Source_Dir).Next :=
6246 String_Element_Table.Last
6247 (In_Tree.String_Elements);
6250 -- And register this source directory as the new last
6252 Last_Source_Dir := String_Element_Table.Last
6253 (In_Tree.String_Elements);
6254 In_Tree.String_Elements.Table (Last_Source_Dir) :=
6257 elsif Removed and Found then
6258 if Prev = Nil_String then
6260 In_Tree.String_Elements.Table (List).Next;
6262 In_Tree.String_Elements.Table (Prev).Next :=
6263 In_Tree.String_Elements.Table (List).Next;
6267 -- Now look for subdirectories. We do that even when this
6268 -- directory is already in the list, because some of its
6269 -- subdirectories may not be in the list yet.
6271 Open (Dir, The_Path (The_Path'First .. The_Path_Last));
6274 Read (Dir, Name, Last);
6277 if Name (1 .. Last) /= "."
6278 and then Name (1 .. Last) /= ".."
6280 -- Avoid . and .. directories
6282 if Current_Verbosity = High then
6283 Write_Str (" Checking ");
6284 Write_Line (Name (1 .. Last));
6288 Path_Name : constant String :=
6290 (Name => Name (1 .. Last),
6292 The_Path (The_Path'First .. The_Path_Last),
6293 Resolve_Links => Opt.Follow_Links_For_Dirs,
6294 Case_Sensitive => True);
6297 if Is_Directory (Path_Name) then
6298 -- We have found a new subdirectory, call self
6300 Name_Len := Path_Name'Length;
6301 Name_Buffer (1 .. Name_Len) := Path_Name;
6302 Recursive_Find_Dirs (Name_Find);
6311 when Directory_Error =>
6313 end Recursive_Find_Dirs;
6315 -- Start of processing for Find_Source_Dirs
6318 if Current_Verbosity = High and then not Removed then
6319 Write_Str ("Find_Source_Dirs (""");
6320 Write_Str (Directory);
6324 -- First, check if we are looking for a directory tree, indicated
6325 -- by "/**" at the end.
6327 if Directory'Length >= 3
6328 and then Directory (Directory'Last - 1 .. Directory'Last) = "**"
6329 and then (Directory (Directory'Last - 2) = '/'
6331 Directory (Directory'Last - 2) = Directory_Separator)
6334 Data.Known_Order_Of_Source_Dirs := False;
6337 Name_Len := Directory'Length - 3;
6339 if Name_Len = 0 then
6341 -- Case of "/**": all directories in file system
6344 Name_Buffer (1) := Directory (Directory'First);
6347 Name_Buffer (1 .. Name_Len) :=
6348 Directory (Directory'First .. Directory'Last - 3);
6351 if Current_Verbosity = High then
6352 Write_Str ("Looking for all subdirectories of """);
6353 Write_Str (Name_Buffer (1 .. Name_Len));
6358 Base_Dir : constant File_Name_Type := Name_Find;
6359 Root_Dir : constant String :=
6361 (Name => Get_Name_String (Base_Dir),
6363 Get_Name_String (Data.Display_Directory),
6364 Resolve_Links => False,
6365 Case_Sensitive => True);
6368 if Root_Dir'Length = 0 then
6369 Err_Vars.Error_Msg_File_1 := Base_Dir;
6371 if Location = No_Location then
6374 "{ is not a valid directory.",
6379 "{ is not a valid directory.",
6384 -- We have an existing directory, we register it and all of
6385 -- its subdirectories.
6387 if Current_Verbosity = High then
6388 Write_Line ("Looking for source directories:");
6391 Name_Len := Root_Dir'Length;
6392 Name_Buffer (1 .. Name_Len) := Root_Dir;
6393 Recursive_Find_Dirs (Name_Find);
6395 if Current_Verbosity = High then
6396 Write_Line ("End of looking for source directories.");
6401 -- We have a single directory
6405 Path_Name : Path_Name_Type;
6406 Display_Path_Name : Path_Name_Type;
6407 List : String_List_Id;
6408 Prev : String_List_Id;
6412 (Project => Project,
6415 Parent => Data.Display_Directory,
6417 Display => Display_Path_Name,
6418 Current_Dir => Current_Dir);
6420 if Path_Name = No_Path then
6421 Err_Vars.Error_Msg_File_1 := From;
6423 if Location = No_Location then
6426 "{ is not a valid directory",
6431 "{ is not a valid directory",
6437 Path : constant String :=
6438 Get_Name_String (Path_Name) &
6439 Directory_Separator;
6440 Last_Path : constant Natural :=
6441 Compute_Directory_Last (Path);
6443 Display_Path : constant String :=
6445 (Display_Path_Name) &
6446 Directory_Separator;
6447 Last_Display_Path : constant Natural :=
6448 Compute_Directory_Last
6450 Display_Path_Id : Name_Id;
6454 Add_Str_To_Name_Buffer (Path (Path'First .. Last_Path));
6455 Path_Id := Name_Find;
6457 Add_Str_To_Name_Buffer
6459 (Display_Path'First .. Last_Display_Path));
6460 Display_Path_Id := Name_Find;
6464 -- As it is an existing directory, we add it to the
6465 -- list of directories.
6467 String_Element_Table.Increment_Last
6468 (In_Tree.String_Elements);
6472 Display_Value => Display_Path_Id,
6473 Location => No_Location,
6475 Next => Nil_String);
6477 if Last_Source_Dir = Nil_String then
6479 -- This is the first source directory
6481 Data.Source_Dirs := String_Element_Table.Last
6482 (In_Tree.String_Elements);
6485 -- We already have source directories, link the
6486 -- previous last to the new one.
6488 In_Tree.String_Elements.Table
6489 (Last_Source_Dir).Next :=
6490 String_Element_Table.Last
6491 (In_Tree.String_Elements);
6494 -- And register this source directory as the new last
6496 Last_Source_Dir := String_Element_Table.Last
6497 (In_Tree.String_Elements);
6498 In_Tree.String_Elements.Table
6499 (Last_Source_Dir) := Element;
6502 -- Remove source dir, if present
6504 List := Data.Source_Dirs;
6507 -- Look for source dir in current list
6509 while List /= Nil_String loop
6510 Element := In_Tree.String_Elements.Table (List);
6511 exit when Element.Value = Path_Id;
6513 List := Element.Next;
6516 if List /= Nil_String then
6517 -- Source dir was found, remove it from the list
6519 if Prev = Nil_String then
6521 In_Tree.String_Elements.Table (List).Next;
6524 In_Tree.String_Elements.Table (Prev).Next :=
6525 In_Tree.String_Elements.Table (List).Next;
6533 end Find_Source_Dirs;
6535 -- Start of processing for Get_Directories
6538 if Current_Verbosity = High then
6539 Write_Line ("Starting to look for directories");
6542 -- Check the object directory
6544 pragma Assert (Object_Dir.Kind = Single,
6545 "Object_Dir is not a single string");
6547 -- We set the object directory to its default
6549 Data.Object_Directory := Data.Directory;
6550 Data.Display_Object_Dir := Data.Display_Directory;
6552 if Object_Dir.Value /= Empty_String then
6553 Get_Name_String (Object_Dir.Value);
6555 if Name_Len = 0 then
6558 "Object_Dir cannot be empty",
6559 Object_Dir.Location);
6562 -- We check that the specified object directory does exist
6567 File_Name_Type (Object_Dir.Value),
6568 Data.Display_Directory,
6569 Data.Object_Directory,
6570 Data.Display_Object_Dir,
6572 Location => Object_Dir.Location,
6573 Current_Dir => Current_Dir);
6575 if Data.Object_Directory = No_Path then
6577 -- The object directory does not exist, report an error if the
6578 -- project is not externally built.
6580 if not Data.Externally_Built then
6581 Err_Vars.Error_Msg_File_1 :=
6582 File_Name_Type (Object_Dir.Value);
6585 "the object directory { cannot be found",
6589 -- Do not keep a nil Object_Directory. Set it to the specified
6590 -- (relative or absolute) path. This is for the benefit of
6591 -- tools that recover from errors; for example, these tools
6592 -- could create the non existent directory.
6594 Data.Display_Object_Dir := Path_Name_Type (Object_Dir.Value);
6596 if Osint.File_Names_Case_Sensitive then
6597 Data.Object_Directory := Path_Name_Type (Object_Dir.Value);
6599 Get_Name_String (Object_Dir.Value);
6600 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
6601 Data.Object_Directory := Name_Find;
6606 elsif Subdirs /= null then
6608 Name_Buffer (1) := '.';
6613 Data.Display_Directory,
6614 Data.Object_Directory,
6615 Data.Display_Object_Dir,
6617 Location => Object_Dir.Location,
6618 Current_Dir => Current_Dir);
6621 if Current_Verbosity = High then
6622 if Data.Object_Directory = No_Path then
6623 Write_Line ("No object directory");
6625 Write_Str ("Object directory: """);
6626 Write_Str (Get_Name_String (Data.Display_Object_Dir));
6631 -- Check the exec directory
6633 pragma Assert (Exec_Dir.Kind = Single,
6634 "Exec_Dir is not a single string");
6636 -- We set the object directory to its default
6638 Data.Exec_Directory := Data.Object_Directory;
6639 Data.Display_Exec_Dir := Data.Display_Object_Dir;
6641 if Exec_Dir.Value /= Empty_String then
6642 Get_Name_String (Exec_Dir.Value);
6644 if Name_Len = 0 then
6647 "Exec_Dir cannot be empty",
6651 -- We check that the specified exec directory does exist
6656 File_Name_Type (Exec_Dir.Value),
6657 Data.Display_Directory,
6658 Data.Exec_Directory,
6659 Data.Display_Exec_Dir,
6661 Location => Exec_Dir.Location,
6662 Current_Dir => Current_Dir);
6664 if Data.Exec_Directory = No_Path then
6665 Err_Vars.Error_Msg_File_1 := File_Name_Type (Exec_Dir.Value);
6668 "the exec directory { cannot be found",
6674 if Current_Verbosity = High then
6675 if Data.Exec_Directory = No_Path then
6676 Write_Line ("No exec directory");
6678 Write_Str ("Exec directory: """);
6679 Write_Str (Get_Name_String (Data.Display_Exec_Dir));
6684 -- Look for the source directories
6686 if Current_Verbosity = High then
6687 Write_Line ("Starting to look for source directories");
6690 pragma Assert (Source_Dirs.Kind = List, "Source_Dirs is not a list");
6692 if (not Source_Files.Default) and then
6693 Source_Files.Values = Nil_String
6695 Data.Source_Dirs := Nil_String;
6697 if Data.Qualifier = Standard then
6701 "a standard project cannot have no sources",
6702 Source_Files.Location);
6705 if Data.Extends = No_Project
6706 and then Data.Object_Directory = Data.Directory
6708 Data.Object_Directory := No_Path;
6711 elsif Source_Dirs.Default then
6713 -- No Source_Dirs specified: the single source directory is the one
6714 -- containing the project file
6716 String_Element_Table.Increment_Last
6717 (In_Tree.String_Elements);
6718 Data.Source_Dirs := String_Element_Table.Last
6719 (In_Tree.String_Elements);
6720 In_Tree.String_Elements.Table (Data.Source_Dirs) :=
6721 (Value => Name_Id (Data.Directory),
6722 Display_Value => Name_Id (Data.Display_Directory),
6723 Location => No_Location,
6728 if Current_Verbosity = High then
6729 Write_Line ("Single source directory:");
6731 Write_Str (Get_Name_String (Data.Display_Directory));
6735 elsif Source_Dirs.Values = Nil_String then
6736 if Data.Qualifier = Standard then
6740 "a standard project cannot have no source directories",
6741 Source_Dirs.Location);
6744 -- If Source_Dirs is an empty string list, this means that this
6745 -- project contains no source. For projects that don't extend other
6746 -- projects, this also means that there is no need for an object
6747 -- directory, if not specified.
6749 if Data.Extends = No_Project
6750 and then Data.Object_Directory = Data.Directory
6752 Data.Object_Directory := No_Path;
6755 Data.Source_Dirs := Nil_String;
6759 Source_Dir : String_List_Id;
6760 Element : String_Element;
6763 -- Process the source directories for each element of the list
6765 Source_Dir := Source_Dirs.Values;
6766 while Source_Dir /= Nil_String loop
6768 In_Tree.String_Elements.Table (Source_Dir);
6770 (File_Name_Type (Element.Value), Element.Location);
6771 Source_Dir := Element.Next;
6776 if not Excluded_Source_Dirs.Default
6777 and then Excluded_Source_Dirs.Values /= Nil_String
6780 Source_Dir : String_List_Id;
6781 Element : String_Element;
6784 -- Process the source directories for each element of the list
6786 Source_Dir := Excluded_Source_Dirs.Values;
6787 while Source_Dir /= Nil_String loop
6789 In_Tree.String_Elements.Table (Source_Dir);
6791 (File_Name_Type (Element.Value),
6794 Source_Dir := Element.Next;
6799 if Current_Verbosity = High then
6800 Write_Line ("Putting source directories in canonical cases");
6804 Current : String_List_Id := Data.Source_Dirs;
6805 Element : String_Element;
6808 while Current /= Nil_String loop
6809 Element := In_Tree.String_Elements.Table (Current);
6810 if Element.Value /= No_Name then
6811 if not Osint.File_Names_Case_Sensitive then
6812 Get_Name_String (Element.Value);
6813 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
6814 Element.Value := Name_Find;
6817 In_Tree.String_Elements.Table (Current) := Element;
6820 Current := Element.Next;
6824 end Get_Directories;
6831 (Project : Project_Id;
6832 In_Tree : Project_Tree_Ref;
6833 Data : in out Project_Data)
6835 Mains : constant Variable_Value :=
6836 Prj.Util.Value_Of (Name_Main, Data.Decl.Attributes, In_Tree);
6839 Data.Mains := Mains.Values;
6841 -- If no Mains were specified, and if we are an extending project,
6842 -- inherit the Mains from the project we are extending.
6844 if Mains.Default then
6845 if Data.Extends /= No_Project then
6847 In_Tree.Projects.Table (Data.Extends).Mains;
6850 -- In a library project file, Main cannot be specified
6852 elsif Data.Library then
6855 "a library project file cannot have Main specified",
6860 ---------------------------
6861 -- Get_Sources_From_File --
6862 ---------------------------
6864 procedure Get_Sources_From_File
6866 Location : Source_Ptr;
6867 Project : Project_Id;
6868 In_Tree : Project_Tree_Ref)
6870 File : Prj.Util.Text_File;
6871 Line : String (1 .. 250);
6873 Source_Name : File_Name_Type;
6874 Name_Loc : Name_Location;
6877 if Get_Mode = Ada_Only then
6881 if Current_Verbosity = High then
6882 Write_Str ("Opening """);
6889 Prj.Util.Open (File, Path);
6891 if not Prj.Util.Is_Valid (File) then
6892 Error_Msg (Project, In_Tree, "file does not exist", Location);
6894 -- Read the lines one by one
6896 while not Prj.Util.End_Of_File (File) loop
6897 Prj.Util.Get_Line (File, Line, Last);
6899 -- A non empty, non comment line should contain a file name
6902 and then (Last = 1 or else Line (1 .. 2) /= "--")
6905 Name_Buffer (1 .. Name_Len) := Line (1 .. Last);
6906 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
6907 Source_Name := Name_Find;
6909 -- Check that there is no directory information
6911 for J in 1 .. Last loop
6912 if Line (J) = '/' or else Line (J) = Directory_Separator then
6913 Error_Msg_File_1 := Source_Name;
6917 "file name cannot include directory information ({)",
6923 Name_Loc := Source_Names.Get (Source_Name);
6925 if Name_Loc = No_Name_Location then
6927 (Name => Source_Name,
6928 Location => Location,
6929 Source => No_Source,
6934 Source_Names.Set (Source_Name, Name_Loc);
6938 Prj.Util.Close (File);
6941 end Get_Sources_From_File;
6948 (In_Tree : Project_Tree_Ref;
6949 Canonical_File_Name : File_Name_Type;
6950 Naming : Naming_Data;
6951 Exception_Id : out Ada_Naming_Exception_Id;
6952 Unit_Name : out Name_Id;
6953 Unit_Kind : out Spec_Or_Body;
6954 Needs_Pragma : out Boolean)
6956 Info_Id : Ada_Naming_Exception_Id :=
6957 Ada_Naming_Exceptions.Get (Canonical_File_Name);
6958 VMS_Name : File_Name_Type;
6961 if Info_Id = No_Ada_Naming_Exception then
6962 if Hostparm.OpenVMS then
6963 VMS_Name := Canonical_File_Name;
6964 Get_Name_String (VMS_Name);
6966 if Name_Buffer (Name_Len) = '.' then
6967 Name_Len := Name_Len - 1;
6968 VMS_Name := Name_Find;
6971 Info_Id := Ada_Naming_Exceptions.Get (VMS_Name);
6976 if Info_Id /= No_Ada_Naming_Exception then
6977 Exception_Id := Info_Id;
6978 Unit_Name := No_Name;
6979 Unit_Kind := Specification;
6980 Needs_Pragma := True;
6984 Needs_Pragma := False;
6985 Exception_Id := No_Ada_Naming_Exception;
6987 Get_Name_String (Canonical_File_Name);
6989 -- How about some comments and a name for this declare block ???
6990 -- In fact the whole code below needs more comments ???
6993 File : String := Name_Buffer (1 .. Name_Len);
6994 First : constant Positive := File'First;
6995 Last : Natural := File'Last;
6996 Standard_GNAT : Boolean;
6997 Spec : constant File_Name_Type :=
6998 Spec_Suffix_Id_Of (In_Tree, Name_Ada, Naming);
6999 Body_Suff : constant File_Name_Type :=
7000 Body_Suffix_Id_Of (In_Tree, Name_Ada, Naming);
7003 Standard_GNAT := Spec = Default_Ada_Spec_Suffix
7004 and then Body_Suff = Default_Ada_Body_Suffix;
7007 Spec_Suffix : constant String := Get_Name_String (Spec);
7008 Body_Suffix : constant String := Get_Name_String (Body_Suff);
7009 Sep_Suffix : constant String :=
7010 Get_Name_String (Naming.Separate_Suffix);
7012 May_Be_Spec : Boolean;
7013 May_Be_Body : Boolean;
7014 May_Be_Sep : Boolean;
7018 File'Length > Spec_Suffix'Length
7020 File (Last - Spec_Suffix'Length + 1 .. Last) = Spec_Suffix;
7023 File'Length > Body_Suffix'Length
7025 File (Last - Body_Suffix'Length + 1 .. Last) = Body_Suffix;
7028 File'Length > Sep_Suffix'Length
7030 File (Last - Sep_Suffix'Length + 1 .. Last) = Sep_Suffix;
7032 -- If two May_Be_ booleans are True, always choose the longer one
7035 if May_Be_Body and then
7036 Spec_Suffix'Length < Body_Suffix'Length
7038 Unit_Kind := Body_Part;
7040 if May_Be_Sep and then
7041 Body_Suffix'Length < Sep_Suffix'Length
7043 Last := Last - Sep_Suffix'Length;
7044 May_Be_Body := False;
7047 Last := Last - Body_Suffix'Length;
7048 May_Be_Sep := False;
7051 elsif May_Be_Sep and then
7052 Spec_Suffix'Length < Sep_Suffix'Length
7054 Unit_Kind := Body_Part;
7055 Last := Last - Sep_Suffix'Length;
7058 Unit_Kind := Specification;
7059 Last := Last - Spec_Suffix'Length;
7062 elsif May_Be_Body then
7063 Unit_Kind := Body_Part;
7065 if May_Be_Sep and then
7066 Body_Suffix'Length < Sep_Suffix'Length
7068 Last := Last - Sep_Suffix'Length;
7069 May_Be_Body := False;
7071 Last := Last - Body_Suffix'Length;
7072 May_Be_Sep := False;
7075 elsif May_Be_Sep then
7076 Unit_Kind := Body_Part;
7077 Last := Last - Sep_Suffix'Length;
7085 -- This is not a source file
7087 Unit_Name := No_Name;
7088 Unit_Kind := Specification;
7090 if Current_Verbosity = High then
7091 Write_Line (" Not a valid file name.");
7096 elsif Current_Verbosity = High then
7098 when Specification =>
7099 Write_Str (" Specification: ");
7100 Write_Line (File (First .. Last + Spec_Suffix'Length));
7104 Write_Str (" Body: ");
7105 Write_Line (File (First .. Last + Body_Suffix'Length));
7108 Write_Str (" Separate: ");
7109 Write_Line (File (First .. Last + Sep_Suffix'Length));
7115 Get_Name_String (Naming.Dot_Replacement);
7117 Standard_GNAT and then Name_Buffer (1 .. Name_Len) = "-";
7119 if Name_Buffer (1 .. Name_Len) /= "." then
7121 -- If Dot_Replacement is not a single dot, then there should not
7122 -- be any dot in the name.
7124 for Index in First .. Last loop
7125 if File (Index) = '.' then
7126 if Current_Verbosity = High then
7128 (" Not a valid file name (some dot not replaced).");
7131 Unit_Name := No_Name;
7137 -- Replace the substring Dot_Replacement with dots
7140 Index : Positive := First;
7143 while Index <= Last - Name_Len + 1 loop
7145 if File (Index .. Index + Name_Len - 1) =
7146 Name_Buffer (1 .. Name_Len)
7148 File (Index) := '.';
7150 if Name_Len > 1 and then Index < Last then
7151 File (Index + 1 .. Last - Name_Len + 1) :=
7152 File (Index + Name_Len .. Last);
7155 Last := Last - Name_Len + 1;
7163 -- Check if the casing is right
7166 Src : String := File (First .. Last);
7167 Src_Last : Positive := Last;
7170 case Naming.Casing is
7171 when All_Lower_Case =>
7174 Mapping => Lower_Case_Map);
7176 when All_Upper_Case =>
7179 Mapping => Upper_Case_Map);
7181 when Mixed_Case | Unknown =>
7185 if Src /= File (First .. Last) then
7186 if Current_Verbosity = High then
7187 Write_Line (" Not a valid file name (casing).");
7190 Unit_Name := No_Name;
7194 -- We put the name in lower case
7198 Mapping => Lower_Case_Map);
7200 -- In the standard GNAT naming scheme, check for special cases:
7201 -- children or separates of A, G, I or S, and run time sources.
7203 if Standard_GNAT and then Src'Length >= 3 then
7205 S1 : constant Character := Src (Src'First);
7206 S2 : constant Character := Src (Src'First + 1);
7207 S3 : constant Character := Src (Src'First + 2);
7215 -- Children or separates of packages A, G, I or S. These
7216 -- names are x__ ... or x~... (where x is a, g, i, or s).
7217 -- Both versions (x__... and x~...) are allowed in all
7218 -- platforms, because it is not possible to know the
7219 -- platform before processing of the project files.
7221 if S2 = '_' and then S3 = '_' then
7222 Src (Src'First + 1) := '.';
7223 Src_Last := Src_Last - 1;
7224 Src (Src'First + 2 .. Src_Last) :=
7225 Src (Src'First + 3 .. Src_Last + 1);
7228 Src (Src'First + 1) := '.';
7230 -- If it is potentially a run time source, disable
7231 -- filling of the mapping file to avoid warnings.
7234 Set_Mapping_File_Initial_State_To_Empty;
7240 if Current_Verbosity = High then
7242 Write_Line (Src (Src'First .. Src_Last));
7245 -- Now, we check if this name is a valid unit name
7248 (Name => Src (Src'First .. Src_Last), Unit => Unit_Name);
7258 function Hash (Unit : Unit_Info) return Header_Num is
7260 return Header_Num (Unit.Unit mod 2048);
7263 -----------------------
7264 -- Is_Illegal_Suffix --
7265 -----------------------
7267 function Is_Illegal_Suffix
7269 Dot_Replacement_Is_A_Single_Dot : Boolean) return Boolean
7272 if Suffix'Length = 0 or else Index (Suffix, ".") = 0 then
7276 -- If dot replacement is a single dot, and first character of suffix is
7279 if Dot_Replacement_Is_A_Single_Dot
7280 and then Suffix (Suffix'First) = '.'
7282 for Index in Suffix'First + 1 .. Suffix'Last loop
7284 -- If there is another dot
7286 if Suffix (Index) = '.' then
7288 -- It is illegal to have a letter following the initial dot
7290 return Is_Letter (Suffix (Suffix'First + 1));
7298 end Is_Illegal_Suffix;
7300 ----------------------
7301 -- Locate_Directory --
7302 ----------------------
7304 procedure Locate_Directory
7305 (Project : Project_Id;
7306 In_Tree : Project_Tree_Ref;
7307 Name : File_Name_Type;
7308 Parent : Path_Name_Type;
7309 Dir : out Path_Name_Type;
7310 Display : out Path_Name_Type;
7311 Create : String := "";
7312 Current_Dir : String;
7313 Location : Source_Ptr := No_Location)
7315 The_Parent : constant String :=
7316 Get_Name_String (Parent) & Directory_Separator;
7318 The_Parent_Last : constant Natural :=
7319 Compute_Directory_Last (The_Parent);
7321 Full_Name : File_Name_Type;
7323 The_Name : File_Name_Type;
7326 Get_Name_String (Name);
7328 -- Add Subdirs.all if it is a directory that may be created and
7329 -- Subdirs is not null;
7331 if Create /= "" and then Subdirs /= null then
7332 if Name_Buffer (Name_Len) /= Directory_Separator then
7333 Add_Char_To_Name_Buffer (Directory_Separator);
7336 Add_Str_To_Name_Buffer (Subdirs.all);
7339 -- Convert '/' to directory separator (for Windows)
7341 for J in 1 .. Name_Len loop
7342 if Name_Buffer (J) = '/' then
7343 Name_Buffer (J) := Directory_Separator;
7347 The_Name := Name_Find;
7349 if Current_Verbosity = High then
7350 Write_Str ("Locate_Directory (""");
7351 Write_Str (Get_Name_String (The_Name));
7352 Write_Str (""", """);
7353 Write_Str (The_Parent);
7360 if Is_Absolute_Path (Get_Name_String (The_Name)) then
7361 Full_Name := The_Name;
7365 Add_Str_To_Name_Buffer
7366 (The_Parent (The_Parent'First .. The_Parent_Last));
7367 Add_Str_To_Name_Buffer (Get_Name_String (The_Name));
7368 Full_Name := Name_Find;
7372 Full_Path_Name : constant String := Get_Name_String (Full_Name);
7375 if (Setup_Projects or else Subdirs /= null)
7376 and then Create'Length > 0
7377 and then not Is_Directory (Full_Path_Name)
7380 Create_Path (Full_Path_Name);
7382 if not Quiet_Output then
7384 Write_Str (" directory """);
7385 Write_Str (Full_Path_Name);
7386 Write_Line (""" created");
7393 "could not create " & Create &
7394 " directory " & Full_Path_Name,
7399 if Is_Directory (Full_Path_Name) then
7401 Normed : constant String :=
7404 Directory => Current_Dir,
7405 Resolve_Links => False,
7406 Case_Sensitive => True);
7408 Canonical_Path : constant String :=
7411 Directory => Current_Dir,
7413 Opt.Follow_Links_For_Dirs,
7414 Case_Sensitive => False);
7417 Name_Len := Normed'Length;
7418 Name_Buffer (1 .. Name_Len) := Normed;
7419 Display := Name_Find;
7421 Name_Len := Canonical_Path'Length;
7422 Name_Buffer (1 .. Name_Len) := Canonical_Path;
7427 end Locate_Directory;
7429 ---------------------------
7430 -- Find_Excluded_Sources --
7431 ---------------------------
7433 procedure Find_Excluded_Sources
7434 (Project : Project_Id;
7435 In_Tree : Project_Tree_Ref;
7436 Data : Project_Data)
7438 Excluded_Sources : Variable_Value;
7440 Excluded_Source_List_File : Variable_Value;
7442 Current : String_List_Id;
7444 Element : String_Element;
7446 Location : Source_Ptr;
7448 Name : File_Name_Type;
7450 File : Prj.Util.Text_File;
7451 Line : String (1 .. 300);
7454 Locally_Removed : Boolean := False;
7456 Excluded_Source_List_File :=
7458 (Name_Excluded_Source_List_File, Data.Decl.Attributes, In_Tree);
7462 (Name_Excluded_Source_Files, Data.Decl.Attributes, In_Tree);
7464 -- If Excluded_Source_Files is not declared, check
7465 -- Locally_Removed_Files.
7467 if Excluded_Sources.Default then
7468 Locally_Removed := True;
7471 (Name_Locally_Removed_Files, Data.Decl.Attributes, In_Tree);
7474 Excluded_Sources_Htable.Reset;
7476 -- If there are excluded sources, put them in the table
7478 if not Excluded_Sources.Default then
7479 if not Excluded_Source_List_File.Default then
7480 if Locally_Removed then
7483 "?both attributes Locally_Removed_Files and " &
7484 "Excluded_Source_List_File are present",
7485 Excluded_Source_List_File.Location);
7489 "?both attributes Excluded_Source_Files and " &
7490 "Excluded_Source_List_File are present",
7491 Excluded_Source_List_File.Location);
7495 Current := Excluded_Sources.Values;
7496 while Current /= Nil_String loop
7497 Element := In_Tree.String_Elements.Table (Current);
7499 if Osint.File_Names_Case_Sensitive then
7500 Name := File_Name_Type (Element.Value);
7502 Get_Name_String (Element.Value);
7503 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7507 -- If the element has no location, then use the location
7508 -- of Excluded_Sources to report possible errors.
7510 if Element.Location = No_Location then
7511 Location := Excluded_Sources.Location;
7513 Location := Element.Location;
7516 Excluded_Sources_Htable.Set (Name, (Name, False, Location));
7517 Current := Element.Next;
7520 elsif not Excluded_Source_List_File.Default then
7521 Location := Excluded_Source_List_File.Location;
7524 Source_File_Path_Name : constant String :=
7527 (Excluded_Source_List_File.Value),
7531 if Source_File_Path_Name'Length = 0 then
7532 Err_Vars.Error_Msg_File_1 :=
7533 File_Name_Type (Excluded_Source_List_File.Value);
7536 "file with excluded sources { does not exist",
7537 Excluded_Source_List_File.Location);
7542 Prj.Util.Open (File, Source_File_Path_Name);
7544 if not Prj.Util.Is_Valid (File) then
7546 (Project, In_Tree, "file does not exist", Location);
7548 -- Read the lines one by one
7550 while not Prj.Util.End_Of_File (File) loop
7551 Prj.Util.Get_Line (File, Line, Last);
7553 -- A non empty, non comment line should contain a file
7557 and then (Last = 1 or else Line (1 .. 2) /= "--")
7560 Name_Buffer (1 .. Name_Len) := Line (1 .. Last);
7561 Canonical_Case_File_Name
7562 (Name_Buffer (1 .. Name_Len));
7565 -- Check that there is no directory information
7567 for J in 1 .. Last loop
7569 or else Line (J) = Directory_Separator
7571 Error_Msg_File_1 := Name;
7575 "file name cannot include " &
7576 "directory information ({)",
7582 Excluded_Sources_Htable.Set
7583 (Name, (Name, False, Location));
7587 Prj.Util.Close (File);
7592 end Find_Excluded_Sources;
7594 ---------------------------
7595 -- Find_Explicit_Sources --
7596 ---------------------------
7598 procedure Find_Explicit_Sources
7599 (Lang : Language_Index;
7600 Current_Dir : String;
7601 Project : Project_Id;
7602 In_Tree : Project_Tree_Ref;
7603 Data : in out Project_Data)
7605 Sources : constant Variable_Value :=
7608 Data.Decl.Attributes,
7610 Source_List_File : constant Variable_Value :=
7612 (Name_Source_List_File,
7613 Data.Decl.Attributes,
7615 Name_Loc : Name_Location;
7618 pragma Assert (Sources.Kind = List, "Source_Files is not a list");
7620 (Source_List_File.Kind = Single,
7621 "Source_List_File is not a single string");
7623 -- If the user has specified a Sources attribute
7625 if not Sources.Default then
7626 if not Source_List_File.Default then
7629 "?both attributes source_files and " &
7630 "source_list_file are present",
7631 Source_List_File.Location);
7634 -- Sources is a list of file names
7637 Current : String_List_Id := Sources.Values;
7638 Element : String_Element;
7639 Location : Source_Ptr;
7640 Name : File_Name_Type;
7643 if Get_Mode = Ada_Only then
7644 Data.Ada_Sources_Present := Current /= Nil_String;
7647 -- If we are processing other languages in the case of gprmake,
7648 -- we should not reset the list of sources, which was already
7649 -- initialized for the Ada files.
7651 if Get_Mode /= Ada_Only or else Lang /= Ada_Language_Index then
7652 if Current = Nil_String then
7655 Data.Source_Dirs := Nil_String;
7656 when Multi_Language =>
7657 Data.First_Language_Processing := No_Language_Index;
7660 -- This project contains no source. For projects that
7661 -- don't extend other projects, this also means that
7662 -- there is no need for an object directory, if not
7665 if Data.Extends = No_Project
7666 and then Data.Object_Directory = Data.Directory
7668 Data.Object_Directory := No_Path;
7673 while Current /= Nil_String loop
7674 Element := In_Tree.String_Elements.Table (Current);
7675 Get_Name_String (Element.Value);
7677 if Osint.File_Names_Case_Sensitive then
7678 Name := File_Name_Type (Element.Value);
7680 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7684 -- If the element has no location, then use the
7685 -- location of Sources to report possible errors.
7687 if Element.Location = No_Location then
7688 Location := Sources.Location;
7690 Location := Element.Location;
7693 -- Check that there is no directory information
7695 for J in 1 .. Name_Len loop
7696 if Name_Buffer (J) = '/'
7697 or else Name_Buffer (J) = Directory_Separator
7699 Error_Msg_File_1 := Name;
7703 "file name cannot include directory " &
7710 -- In Multi_Language mode, check whether the file is
7711 -- already there: the same file name may be in the list; if
7712 -- the source is missing, the error will be on the first
7713 -- mention of the source file name.
7717 Name_Loc := No_Name_Location;
7718 when Multi_Language =>
7719 Name_Loc := Source_Names.Get (Name);
7722 if Name_Loc = No_Name_Location then
7725 Location => Location,
7726 Source => No_Source,
7729 Source_Names.Set (Name, Name_Loc);
7732 Current := Element.Next;
7735 if Get_Mode = Ada_Only then
7736 if Lang = Ada_Language_Index then
7737 Get_Path_Names_And_Record_Ada_Sources
7738 (Project, In_Tree, Data, Current_Dir);
7740 Record_Other_Sources
7741 (Project => Project,
7745 Naming_Exceptions => False);
7750 -- If we have no Source_Files attribute, check the Source_List_File
7753 elsif not Source_List_File.Default then
7755 -- Source_List_File is the name of the file
7756 -- that contains the source file names
7759 Source_File_Path_Name : constant String :=
7761 (File_Name_Type (Source_List_File.Value), Data.Directory);
7764 if Source_File_Path_Name'Length = 0 then
7765 Err_Vars.Error_Msg_File_1 :=
7766 File_Name_Type (Source_List_File.Value);
7769 "file with sources { does not exist",
7770 Source_List_File.Location);
7773 Get_Sources_From_File
7774 (Source_File_Path_Name, Source_List_File.Location,
7777 if Get_Mode = Ada_Only then
7778 -- Look in the source directories to find those sources
7780 if Lang = Ada_Language_Index then
7781 Get_Path_Names_And_Record_Ada_Sources
7782 (Project, In_Tree, Data, Current_Dir);
7785 Record_Other_Sources
7786 (Project => Project,
7790 Naming_Exceptions => False);
7797 -- Neither Source_Files nor Source_List_File has been
7798 -- specified. Find all the files that satisfy the naming
7799 -- scheme in all the source directories.
7803 if Lang = Ada_Language_Index then
7804 Find_Ada_Sources (Project, In_Tree, Data, Current_Dir);
7806 -- Find all the files that satisfy the naming scheme in
7807 -- all the source directories. All the naming exceptions
7808 -- that effectively exist are also part of the source
7809 -- of this language.
7811 Find_Sources (Project, In_Tree, Data, Lang, Current_Dir);
7814 when Multi_Language =>
7819 if Get_Mode = Multi_Language then
7821 (Project, In_Tree, Data,
7823 Sources.Default and then Source_List_File.Default);
7825 -- Check if all exceptions have been found.
7826 -- For Ada, it is an error if an exception is not found.
7827 -- For other language, the source is removed.
7831 Src_Data : Source_Data;
7834 Source := Data.First_Source;
7835 while Source /= No_Source loop
7836 Src_Data := In_Tree.Sources.Table (Source);
7838 if Src_Data.Naming_Exception
7839 and then Src_Data.Path = No_Path
7841 if Src_Data.Unit /= No_Name then
7842 Error_Msg_Name_1 := Name_Id (Src_Data.Display_File);
7843 Error_Msg_Name_2 := Name_Id (Src_Data.Unit);
7846 "source file %% for unit %% not found",
7851 (Source, No_Source, Project, Data, In_Tree);
7855 Source := Src_Data.Next_In_Project;
7859 -- Check that all sources in Source_Files or the file
7860 -- Source_List_File has been found.
7863 Name_Loc : Name_Location;
7866 Name_Loc := Source_Names.Get_First;
7867 while Name_Loc /= No_Name_Location loop
7868 if (not Name_Loc.Except) and then (not Name_Loc.Found) then
7869 Error_Msg_Name_1 := Name_Id (Name_Loc.Name);
7873 "file %% not found",
7877 Name_Loc := Source_Names.Get_Next;
7882 if Get_Mode = Ada_Only
7883 and then Lang = Ada_Language_Index
7884 and then Data.Extends = No_Project
7886 -- We should have found at least one source, if not report an error
7888 if Data.Ada_Sources = Nil_String then
7890 (Project, "Ada", In_Tree, Source_List_File.Location);
7894 end Find_Explicit_Sources;
7896 -------------------------------------------
7897 -- Get_Path_Names_And_Record_Ada_Sources --
7898 -------------------------------------------
7900 procedure Get_Path_Names_And_Record_Ada_Sources
7901 (Project : Project_Id;
7902 In_Tree : Project_Tree_Ref;
7903 Data : in out Project_Data;
7904 Current_Dir : String)
7906 Source_Dir : String_List_Id;
7907 Element : String_Element;
7908 Path : Path_Name_Type;
7910 Name : File_Name_Type;
7911 Canonical_Name : File_Name_Type;
7912 Name_Str : String (1 .. 1_024);
7913 Last : Natural := 0;
7915 Current_Source : String_List_Id := Nil_String;
7916 First_Error : Boolean := True;
7917 Source_Recorded : Boolean := False;
7920 -- We look in all source directories for the file names in the hash
7921 -- table Source_Names.
7923 Source_Dir := Data.Source_Dirs;
7924 while Source_Dir /= Nil_String loop
7925 Source_Recorded := False;
7926 Element := In_Tree.String_Elements.Table (Source_Dir);
7929 Dir_Path : constant String :=
7930 Get_Name_String (Element.Display_Value);
7932 if Current_Verbosity = High then
7933 Write_Str ("checking directory """);
7934 Write_Str (Dir_Path);
7938 Open (Dir, Dir_Path);
7941 Read (Dir, Name_Str, Last);
7945 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
7948 if Osint.File_Names_Case_Sensitive then
7949 Canonical_Name := Name;
7951 Canonical_Case_File_Name (Name_Str (1 .. Last));
7952 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
7953 Canonical_Name := Name_Find;
7956 NL := Source_Names.Get (Canonical_Name);
7958 if NL /= No_Name_Location and then not NL.Found then
7960 Source_Names.Set (Canonical_Name, NL);
7961 Name_Len := Dir_Path'Length;
7962 Name_Buffer (1 .. Name_Len) := Dir_Path;
7964 if Name_Buffer (Name_Len) /= Directory_Separator then
7965 Add_Char_To_Name_Buffer (Directory_Separator);
7968 Add_Str_To_Name_Buffer (Name_Str (1 .. Last));
7971 if Current_Verbosity = High then
7972 Write_Str (" found ");
7973 Write_Line (Get_Name_String (Name));
7976 -- Register the source if it is an Ada compilation unit
7984 Location => NL.Location,
7985 Current_Source => Current_Source,
7986 Source_Recorded => Source_Recorded,
7987 Current_Dir => Current_Dir);
7994 if Source_Recorded then
7995 In_Tree.String_Elements.Table (Source_Dir).Flag :=
7999 Source_Dir := Element.Next;
8002 -- It is an error if a source file name in a source list or
8003 -- in a source list file is not found.
8005 NL := Source_Names.Get_First;
8006 while NL /= No_Name_Location loop
8007 if not NL.Found then
8008 Err_Vars.Error_Msg_File_1 := NL.Name;
8013 "source file { cannot be found",
8015 First_Error := False;
8020 "\source file { cannot be found",
8025 NL := Source_Names.Get_Next;
8027 end Get_Path_Names_And_Record_Ada_Sources;
8029 --------------------------
8030 -- Check_Naming_Schemes --
8031 --------------------------
8033 procedure Check_Naming_Schemes
8034 (In_Tree : Project_Tree_Ref;
8035 Data : in out Project_Data;
8037 File_Name : File_Name_Type;
8038 Alternate_Languages : out Alternate_Language_Id;
8039 Language : out Language_Index;
8040 Language_Name : out Name_Id;
8041 Display_Language_Name : out Name_Id;
8043 Lang_Kind : out Language_Kind;
8044 Kind : out Source_Kind)
8046 Last : Positive := Filename'Last;
8047 Config : Language_Config;
8048 Lang : Name_List_Index := Data.Languages;
8049 Header_File : Boolean := False;
8050 First_Language : Language_Index;
8053 Last_Spec : Natural;
8054 Last_Body : Natural;
8059 Alternate_Languages := No_Alternate_Language;
8061 while Lang /= No_Name_List loop
8062 Language_Name := In_Tree.Name_Lists.Table (Lang).Name;
8063 Language := Data.First_Language_Processing;
8065 if Current_Verbosity = High then
8067 (" Testing language "
8068 & Get_Name_String (Language_Name)
8069 & " Header_File=" & Header_File'Img);
8072 while Language /= No_Language_Index loop
8073 if In_Tree.Languages_Data.Table (Language).Name =
8076 Display_Language_Name :=
8077 In_Tree.Languages_Data.Table (Language).Display_Name;
8078 Config := In_Tree.Languages_Data.Table (Language).Config;
8079 Lang_Kind := Config.Kind;
8081 if Config.Kind = File_Based then
8083 -- For file based languages, there is no Unit. Just
8084 -- check if the file name has the implementation or,
8085 -- if it is specified, the template suffix of the
8091 and then Config.Naming_Data.Body_Suffix /= No_File
8094 Impl_Suffix : constant String :=
8095 Get_Name_String (Config.Naming_Data.Body_Suffix);
8098 if Filename'Length > Impl_Suffix'Length
8101 (Last - Impl_Suffix'Length + 1 .. Last) =
8106 if Current_Verbosity = High then
8107 Write_Str (" source of language ");
8109 (Get_Name_String (Display_Language_Name));
8117 if Config.Naming_Data.Spec_Suffix /= No_File then
8119 Spec_Suffix : constant String :=
8121 (Config.Naming_Data.Spec_Suffix);
8124 if Filename'Length > Spec_Suffix'Length
8127 (Last - Spec_Suffix'Length + 1 .. Last) =
8132 if Current_Verbosity = High then
8133 Write_Str (" header file of language ");
8135 (Get_Name_String (Display_Language_Name));
8139 Alternate_Language_Table.Increment_Last
8140 (In_Tree.Alt_Langs);
8141 In_Tree.Alt_Langs.Table
8142 (Alternate_Language_Table.Last
8143 (In_Tree.Alt_Langs)) :=
8144 (Language => Language,
8145 Next => Alternate_Languages);
8146 Alternate_Languages :=
8147 Alternate_Language_Table.Last
8148 (In_Tree.Alt_Langs);
8150 Header_File := True;
8151 First_Language := Language;
8157 elsif not Header_File then
8158 -- Unit based language
8160 OK := Config.Naming_Data.Dot_Replacement /= No_File;
8165 -- ??? Are we doing this once per file in the project ?
8166 -- It should be done only once per project.
8168 case Config.Naming_Data.Casing is
8169 when All_Lower_Case =>
8170 for J in Filename'Range loop
8171 if Is_Letter (Filename (J)) then
8172 if not Is_Lower (Filename (J)) then
8179 when All_Upper_Case =>
8180 for J in Filename'Range loop
8181 if Is_Letter (Filename (J)) then
8182 if not Is_Upper (Filename (J)) then
8195 Last_Spec := Natural'Last;
8196 Last_Body := Natural'Last;
8197 Last_Sep := Natural'Last;
8199 if Config.Naming_Data.Separate_Suffix /= No_File
8201 Config.Naming_Data.Separate_Suffix /=
8202 Config.Naming_Data.Body_Suffix
8205 Suffix : constant String :=
8207 (Config.Naming_Data.Separate_Suffix);
8209 if Filename'Length > Suffix'Length
8212 (Last - Suffix'Length + 1 .. Last) =
8215 Last_Sep := Last - Suffix'Length;
8220 if Config.Naming_Data.Body_Suffix /= No_File then
8222 Suffix : constant String :=
8224 (Config.Naming_Data.Body_Suffix);
8226 if Filename'Length > Suffix'Length
8229 (Last - Suffix'Length + 1 .. Last) =
8232 Last_Body := Last - Suffix'Length;
8237 if Config.Naming_Data.Spec_Suffix /= No_File then
8239 Suffix : constant String :=
8241 (Config.Naming_Data.Spec_Suffix);
8243 if Filename'Length > Suffix'Length
8246 (Last - Suffix'Length + 1 .. Last) =
8249 Last_Spec := Last - Suffix'Length;
8255 Last_Min : constant Natural :=
8256 Natural'Min (Natural'Min (Last_Spec,
8261 OK := Last_Min < Last;
8266 if Last_Min = Last_Spec then
8269 elsif Last_Min = Last_Body then
8281 -- Replace dot replacements with dots
8286 J : Positive := Filename'First;
8288 Dot_Replacement : constant String :=
8290 (Config.Naming_Data.
8293 Max : constant Positive :=
8294 Last - Dot_Replacement'Length + 1;
8298 Name_Len := Name_Len + 1;
8300 if J <= Max and then
8302 (J .. J + Dot_Replacement'Length - 1) =
8305 Name_Buffer (Name_Len) := '.';
8306 J := J + Dot_Replacement'Length;
8309 if Filename (J) = '.' then
8314 Name_Buffer (Name_Len) :=
8315 GNAT.Case_Util.To_Lower (Filename (J));
8326 -- The name buffer should contain the name of the
8327 -- the unit, if it is one.
8329 -- Check that this is a valid unit name
8331 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit);
8333 if Unit /= No_Name then
8335 if Current_Verbosity = High then
8337 Write_Str (" spec of ");
8339 Write_Str (" body of ");
8342 Write_Str (Get_Name_String (Unit));
8343 Write_Str (" (language ");
8345 (Get_Name_String (Display_Language_Name));
8349 -- Comments required, declare block should
8353 Unit_Except : constant Unit_Exception :=
8354 Unit_Exceptions.Get (Unit);
8356 procedure Masked_Unit (Spec : Boolean);
8357 -- Indicate that there is an exception for
8358 -- the same unit, so the file is not a
8359 -- source for the unit.
8365 procedure Masked_Unit (Spec : Boolean) is
8367 if Current_Verbosity = High then
8369 Write_Str (Filename);
8370 Write_Str (""" contains the ");
8379 (" of a unit that is found in """);
8384 (Unit_Except.Spec));
8388 (Unit_Except.Impl));
8391 Write_Line (""" (ignored)");
8394 Language := No_Language_Index;
8399 if Unit_Except.Spec /= No_File
8400 and then Unit_Except.Spec /= File_Name
8402 Masked_Unit (Spec => True);
8406 if Unit_Except.Impl /= No_File
8407 and then Unit_Except.Impl /= File_Name
8409 Masked_Unit (Spec => False);
8420 Language := In_Tree.Languages_Data.Table (Language).Next;
8423 Lang := In_Tree.Name_Lists.Table (Lang).Next;
8426 -- Comment needed here ???
8429 Language := First_Language;
8432 Language := No_Language_Index;
8434 if Current_Verbosity = High then
8435 Write_Line (" not a source of any language");
8438 end Check_Naming_Schemes;
8444 procedure Check_File
8445 (Project : Project_Id;
8446 In_Tree : Project_Tree_Ref;
8447 Data : in out Project_Data;
8449 File_Name : File_Name_Type;
8450 Display_File_Name : File_Name_Type;
8451 Source_Directory : String;
8452 For_All_Sources : Boolean)
8454 Display_Path : constant String :=
8457 Directory => Source_Directory,
8458 Resolve_Links => Opt.Follow_Links_For_Files,
8459 Case_Sensitive => True);
8461 Name_Loc : Name_Location := Source_Names.Get (File_Name);
8462 Path_Id : Path_Name_Type;
8463 Display_Path_Id : Path_Name_Type;
8464 Check_Name : Boolean := False;
8465 Alternate_Languages : Alternate_Language_Id := No_Alternate_Language;
8466 Language : Language_Index;
8468 Other_Part : Source_Id;
8470 Src_Ind : Source_File_Index;
8471 Src_Data : Source_Data;
8473 Source_To_Replace : Source_Id := No_Source;
8474 Language_Name : Name_Id;
8475 Display_Language_Name : Name_Id;
8476 Lang_Kind : Language_Kind;
8477 Kind : Source_Kind := Spec;
8480 Name_Len := Display_Path'Length;
8481 Name_Buffer (1 .. Name_Len) := Display_Path;
8482 Display_Path_Id := Name_Find;
8484 if Osint.File_Names_Case_Sensitive then
8485 Path_Id := Display_Path_Id;
8487 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
8488 Path_Id := Name_Find;
8491 if Name_Loc = No_Name_Location then
8492 Check_Name := For_All_Sources;
8495 if Name_Loc.Found then
8497 -- Check if it is OK to have the same file name in several
8498 -- source directories.
8500 if not Data.Known_Order_Of_Source_Dirs then
8501 Error_Msg_File_1 := File_Name;
8504 "{ is found in several source directories",
8509 Name_Loc.Found := True;
8511 Source_Names.Set (File_Name, Name_Loc);
8513 if Name_Loc.Source = No_Source then
8517 In_Tree.Sources.Table (Name_Loc.Source).Path := Path_Id;
8518 In_Tree.Sources.Table
8519 (Name_Loc.Source).Display_Path := Display_Path_Id;
8521 Source_Paths_Htable.Set
8522 (In_Tree.Source_Paths_HT,
8526 -- Check if this is a subunit
8528 if In_Tree.Sources.Table (Name_Loc.Source).Unit /= No_Name
8530 In_Tree.Sources.Table (Name_Loc.Source).Kind = Impl
8532 Src_Ind := Sinput.P.Load_Project_File
8533 (Get_Name_String (Path_Id));
8535 if Sinput.P.Source_File_Is_Subunit (Src_Ind) then
8536 In_Tree.Sources.Table (Name_Loc.Source).Kind := Sep;
8544 Other_Part := No_Source;
8546 Check_Naming_Schemes
8547 (In_Tree => In_Tree,
8549 Filename => Get_Name_String (File_Name),
8550 File_Name => File_Name,
8551 Alternate_Languages => Alternate_Languages,
8552 Language => Language,
8553 Language_Name => Language_Name,
8554 Display_Language_Name => Display_Language_Name,
8556 Lang_Kind => Lang_Kind,
8559 if Language = No_Language_Index then
8561 -- A file name in a list must be a source of a language
8563 if Name_Loc.Found then
8564 Error_Msg_File_1 := File_Name;
8568 "language unknown for {",
8573 -- Check if the same file name or unit is used in the prj tree
8575 Source := In_Tree.First_Source;
8577 while Source /= No_Source loop
8578 Src_Data := In_Tree.Sources.Table (Source);
8581 and then Src_Data.Unit = Unit
8582 and then Src_Data.Kind /= Kind
8584 Other_Part := Source;
8586 elsif (Unit /= No_Name
8587 and then Src_Data.Unit = Unit
8588 and then Src_Data.Kind = Kind)
8589 or else (Unit = No_Name and then Src_Data.File = File_Name)
8591 -- Duplication of file/unit in same project is only
8592 -- allowed if order of source directories is known.
8594 if Project = Src_Data.Project then
8595 if Data.Known_Order_Of_Source_Dirs then
8598 elsif Unit /= No_Name then
8599 Error_Msg_Name_1 := Unit;
8601 (Project, In_Tree, "duplicate unit %%", No_Location);
8605 Error_Msg_File_1 := File_Name;
8607 (Project, In_Tree, "duplicate source file name {",
8612 -- Do not allow the same unit name in different
8613 -- projects, except if one is extending the other.
8615 -- For a file based language, the same file name
8616 -- replaces a file in a project being extended, but
8617 -- it is allowed to have the same file name in
8618 -- unrelated projects.
8621 (Project, Src_Data.Project, In_Tree)
8623 Source_To_Replace := Source;
8625 elsif Unit /= No_Name then
8626 Error_Msg_Name_1 := Unit;
8629 "unit %% cannot belong to several projects",
8632 Error_Msg_Name_1 := In_Tree.Projects.Table (Project).Name;
8633 Error_Msg_Name_2 := Name_Id (Display_Path_Id);
8635 (Project, In_Tree, "\ project %%, %%", No_Location);
8638 In_Tree.Projects.Table (Src_Data.Project).Name;
8639 Error_Msg_Name_2 := Name_Id (Src_Data.Display_Path);
8641 (Project, In_Tree, "\ project %%, %%", No_Location);
8647 Source := Src_Data.Next_In_Sources;
8656 Lang => Language_Name,
8657 Lang_Id => Language,
8658 Lang_Kind => Lang_Kind,
8660 Alternate_Languages => Alternate_Languages,
8661 File_Name => File_Name,
8662 Display_File => Display_File_Name,
8663 Other_Part => Other_Part,
8666 Display_Path => Display_Path_Id,
8667 Source_To_Replace => Source_To_Replace);
8673 ------------------------
8674 -- Search_Directories --
8675 ------------------------
8677 procedure Search_Directories
8678 (Project : Project_Id;
8679 In_Tree : Project_Tree_Ref;
8680 Data : in out Project_Data;
8681 For_All_Sources : Boolean)
8683 Source_Dir : String_List_Id;
8684 Element : String_Element;
8686 Name : String (1 .. 1_000);
8688 File_Name : File_Name_Type;
8689 Display_File_Name : File_Name_Type;
8692 if Current_Verbosity = High then
8693 Write_Line ("Looking for sources:");
8696 -- Loop through subdirectories
8698 Source_Dir := Data.Source_Dirs;
8699 while Source_Dir /= Nil_String loop
8701 Element := In_Tree.String_Elements.Table (Source_Dir);
8702 if Element.Value /= No_Name then
8703 Get_Name_String (Element.Display_Value);
8706 Source_Directory : constant String :=
8707 Name_Buffer (1 .. Name_Len) &
8708 Directory_Separator;
8710 Dir_Last : constant Natural :=
8711 Compute_Directory_Last
8715 if Current_Verbosity = High then
8716 Write_Str ("Source_Dir = ");
8717 Write_Line (Source_Directory);
8720 -- We look to every entry in the source directory
8722 Open (Dir, Source_Directory);
8725 Read (Dir, Name, Last);
8729 -- ??? Duplicate system call here, we just did a
8730 -- a similar one. Maybe Ada.Directories would be more
8734 (Source_Directory & Name (1 .. Last))
8736 if Current_Verbosity = High then
8737 Write_Str (" Checking ");
8738 Write_Line (Name (1 .. Last));
8742 Name_Buffer (1 .. Name_Len) := Name (1 .. Last);
8743 Display_File_Name := Name_Find;
8745 if Osint.File_Names_Case_Sensitive then
8746 File_Name := Display_File_Name;
8748 Canonical_Case_File_Name
8749 (Name_Buffer (1 .. Name_Len));
8750 File_Name := Name_Find;
8755 Excluded_Sources_Htable.Get (File_Name);
8758 if FF /= No_File_Found then
8759 if not FF.Found then
8761 Excluded_Sources_Htable.Set
8764 if Current_Verbosity = High then
8765 Write_Str (" excluded source """);
8766 Write_Str (Get_Name_String (File_Name));
8773 (Project => Project,
8776 Name => Name (1 .. Last),
8777 File_Name => File_Name,
8778 Display_File_Name => Display_File_Name,
8779 Source_Directory => Source_Directory
8780 (Source_Directory'First .. Dir_Last),
8781 For_All_Sources => For_All_Sources);
8792 when Directory_Error =>
8796 Source_Dir := Element.Next;
8799 if Current_Verbosity = High then
8800 Write_Line ("end Looking for sources.");
8802 end Search_Directories;
8804 ----------------------
8805 -- Look_For_Sources --
8806 ----------------------
8808 procedure Look_For_Sources
8809 (Project : Project_Id;
8810 In_Tree : Project_Tree_Ref;
8811 Data : in out Project_Data;
8812 Current_Dir : String)
8814 procedure Remove_Locally_Removed_Files_From_Units;
8815 -- Mark all locally removed sources as such in the Units table
8817 procedure Process_Other_Sources_In_Ada_Only_Mode;
8818 -- Find sources for language other than Ada when in Ada_Only mode
8820 procedure Process_Sources_In_Multi_Language_Mode;
8821 -- Find all source files when in multi language mode
8823 ---------------------------------------------
8824 -- Remove_Locally_Removed_Files_From_Units --
8825 ---------------------------------------------
8827 procedure Remove_Locally_Removed_Files_From_Units is
8828 Excluded : File_Found;
8831 Extended : Project_Id;
8834 Excluded := Excluded_Sources_Htable.Get_First;
8835 while Excluded /= No_File_Found loop
8839 for Index in Unit_Table.First ..
8840 Unit_Table.Last (In_Tree.Units)
8842 Unit := In_Tree.Units.Table (Index);
8844 for Kind in Spec_Or_Body'Range loop
8845 if Unit.File_Names (Kind).Name = Excluded.File then
8848 -- Check that this is from the current project or
8849 -- that the current project extends.
8851 Extended := Unit.File_Names (Kind).Project;
8853 if Extended = Project
8854 or else Project_Extends (Project, Extended, In_Tree)
8856 Unit.File_Names (Kind).Path := Slash;
8857 Unit.File_Names (Kind).Needs_Pragma := False;
8858 In_Tree.Units.Table (Index) := Unit;
8859 Add_Forbidden_File_Name
8860 (Unit.File_Names (Kind).Name);
8864 "cannot remove a source from " &
8871 end loop For_Each_Unit;
8874 Err_Vars.Error_Msg_File_1 := Excluded.File;
8876 (Project, In_Tree, "unknown file {", Excluded.Location);
8879 Excluded := Excluded_Sources_Htable.Get_Next;
8881 end Remove_Locally_Removed_Files_From_Units;
8883 --------------------------------------------
8884 -- Process_Other_Sources_In_Ada_Only_Mode --
8885 --------------------------------------------
8887 procedure Process_Other_Sources_In_Ada_Only_Mode is
8889 -- Set Source_Present to False. It will be set back to True
8890 -- whenever a source is found.
8892 Data.Other_Sources_Present := False;
8893 for Lang in Ada_Language_Index + 1 .. Last_Language_Index loop
8895 -- For each language (other than Ada) in the project file
8897 if Is_Present (Lang, Data, In_Tree) then
8899 -- Reset the indication that there are sources of this
8900 -- language. It will be set back to True whenever we find
8901 -- a source of the language.
8903 Set (Lang, False, Data, In_Tree);
8905 -- First, get the source suffix for the language
8907 Set (Suffix => Suffix_For (Lang, Data.Naming, In_Tree),
8908 For_Language => Lang,
8910 In_Tree => In_Tree);
8912 -- Then, deal with the naming exceptions, if any
8917 Naming_Exceptions : constant Variable_Value :=
8919 (Index => Language_Names.Table (Lang),
8921 In_Array => Data.Naming.Implementation_Exceptions,
8922 In_Tree => In_Tree);
8923 Element_Id : String_List_Id;
8924 Element : String_Element;
8925 File_Id : File_Name_Type;
8926 Source_Found : Boolean := False;
8929 -- If there are naming exceptions, look through them one
8932 if Naming_Exceptions /= Nil_Variable_Value then
8933 Element_Id := Naming_Exceptions.Values;
8935 while Element_Id /= Nil_String loop
8936 Element := In_Tree.String_Elements.Table (Element_Id);
8938 if Osint.File_Names_Case_Sensitive then
8939 File_Id := File_Name_Type (Element.Value);
8941 Get_Name_String (Element.Value);
8942 Canonical_Case_File_Name
8943 (Name_Buffer (1 .. Name_Len));
8944 File_Id := Name_Find;
8947 -- Put each naming exception in the Source_Names hash
8948 -- table, but if there are repetition, don't bother
8949 -- after the first instance.
8951 if Source_Names.Get (File_Id) = No_Name_Location then
8952 Source_Found := True;
8956 Location => Element.Location,
8957 Source => No_Source,
8962 Element_Id := Element.Next;
8965 -- If there is at least one naming exception, record
8966 -- those that are found in the source directories.
8968 if Source_Found then
8969 Record_Other_Sources
8970 (Project => Project,
8974 Naming_Exceptions => True);
8980 -- Now, check if a list of sources is declared either through
8981 -- a string list (attribute Source_Files) or a text file
8982 -- (attribute Source_List_File). If a source list is declared,
8983 -- we will consider only those naming exceptions that are
8987 Find_Explicit_Sources
8988 (Lang, Current_Dir, Project, In_Tree, Data);
8991 end Process_Other_Sources_In_Ada_Only_Mode;
8993 --------------------------------------------
8994 -- Process_Sources_In_Multi_Language_Mode --
8995 --------------------------------------------
8997 procedure Process_Sources_In_Multi_Language_Mode is
8999 Src_Data : Source_Data;
9000 Name_Loc : Name_Location;
9005 -- First, put all naming exceptions if any, in the Source_Names table
9007 Unit_Exceptions.Reset;
9009 Source := Data.First_Source;
9010 while Source /= No_Source loop
9011 Src_Data := In_Tree.Sources.Table (Source);
9013 -- A file that is excluded cannot also be an exception file name
9015 if Excluded_Sources_Htable.Get (Src_Data.File) /=
9018 Error_Msg_File_1 := Src_Data.File;
9021 "{ cannot be both excluded and an exception file name",
9025 Name_Loc := (Name => Src_Data.File,
9026 Location => No_Location,
9028 Except => Src_Data.Unit /= No_Name,
9031 if Current_Verbosity = High then
9032 Write_Str ("Putting source #");
9033 Write_Str (Source'Img);
9034 Write_Str (", file ");
9035 Write_Str (Get_Name_String (Src_Data.File));
9036 Write_Line (" in Source_Names");
9039 Source_Names.Set (K => Src_Data.File, E => Name_Loc);
9041 -- If this is an Ada exception, record it in table Unit_Exceptions
9043 if Src_Data.Unit /= No_Name then
9045 Unit_Except : Unit_Exception :=
9046 Unit_Exceptions.Get (Src_Data.Unit);
9049 Unit_Except.Name := Src_Data.Unit;
9051 if Src_Data.Kind = Spec then
9052 Unit_Except.Spec := Src_Data.File;
9054 Unit_Except.Impl := Src_Data.File;
9057 Unit_Exceptions.Set (Src_Data.Unit, Unit_Except);
9061 Source := Src_Data.Next_In_Project;
9064 Find_Explicit_Sources
9065 (Ada_Language_Index, Current_Dir, Project, In_Tree, Data);
9067 FF := Excluded_Sources_Htable.Get_First;
9068 while FF /= No_File_Found loop
9070 Source := In_Tree.First_Source;
9072 while Source /= No_Source loop
9073 Src_Data := In_Tree.Sources.Table (Source);
9075 if Src_Data.File = FF.File then
9077 -- Check that this is from this project or a project that
9078 -- the current project extends.
9080 if Src_Data.Project = Project or else
9081 Is_Extending (Project, Src_Data.Project, In_Tree)
9083 Src_Data.Locally_Removed := True;
9084 Src_Data.In_Interfaces := False;
9085 In_Tree.Sources.Table (Source) := Src_Data;
9086 Add_Forbidden_File_Name (FF.File);
9092 Source := Src_Data.Next_In_Sources;
9095 if not FF.Found and not OK then
9096 Err_Vars.Error_Msg_File_1 := FF.File;
9097 Error_Msg (Project, In_Tree, "unknown file {", FF.Location);
9100 FF := Excluded_Sources_Htable.Get_Next;
9102 end Process_Sources_In_Multi_Language_Mode;
9104 -- Start of processing for Look_For_Sources
9108 Find_Excluded_Sources (Project, In_Tree, Data);
9112 if Is_A_Language (In_Tree, Data, Name_Ada) then
9113 Find_Explicit_Sources
9114 (Ada_Language_Index, Current_Dir, Project, In_Tree, Data);
9115 Remove_Locally_Removed_Files_From_Units;
9118 if Data.Other_Sources_Present then
9119 Process_Other_Sources_In_Ada_Only_Mode;
9122 when Multi_Language =>
9123 if Data.First_Language_Processing /= No_Language_Index then
9124 Process_Sources_In_Multi_Language_Mode;
9127 end Look_For_Sources;
9133 function Path_Name_Of
9134 (File_Name : File_Name_Type;
9135 Directory : Path_Name_Type) return String
9137 Result : String_Access;
9139 The_Directory : constant String := Get_Name_String (Directory);
9142 Get_Name_String (File_Name);
9143 Result := Locate_Regular_File
9144 (File_Name => Name_Buffer (1 .. Name_Len),
9145 Path => The_Directory);
9147 if Result = null then
9150 Canonical_Case_File_Name (Result.all);
9155 -------------------------------
9156 -- Prepare_Ada_Naming_Exceptions --
9157 -------------------------------
9159 procedure Prepare_Ada_Naming_Exceptions
9160 (List : Array_Element_Id;
9161 In_Tree : Project_Tree_Ref;
9162 Kind : Spec_Or_Body)
9164 Current : Array_Element_Id;
9165 Element : Array_Element;
9169 -- Traverse the list
9172 while Current /= No_Array_Element loop
9173 Element := In_Tree.Array_Elements.Table (Current);
9175 if Element.Index /= No_Name then
9178 Unit => Element.Index,
9179 Next => No_Ada_Naming_Exception);
9180 Reverse_Ada_Naming_Exceptions.Set
9181 (Unit, (Element.Value.Value, Element.Value.Index));
9183 Ada_Naming_Exceptions.Get (File_Name_Type (Element.Value.Value));
9184 Ada_Naming_Exception_Table.Increment_Last;
9185 Ada_Naming_Exception_Table.Table
9186 (Ada_Naming_Exception_Table.Last) := Unit;
9187 Ada_Naming_Exceptions.Set
9188 (File_Name_Type (Element.Value.Value),
9189 Ada_Naming_Exception_Table.Last);
9192 Current := Element.Next;
9194 end Prepare_Ada_Naming_Exceptions;
9196 ---------------------
9197 -- Project_Extends --
9198 ---------------------
9200 function Project_Extends
9201 (Extending : Project_Id;
9202 Extended : Project_Id;
9203 In_Tree : Project_Tree_Ref) return Boolean
9205 Current : Project_Id := Extending;
9209 if Current = No_Project then
9212 elsif Current = Extended then
9216 Current := In_Tree.Projects.Table (Current).Extends;
9218 end Project_Extends;
9220 -----------------------
9221 -- Record_Ada_Source --
9222 -----------------------
9224 procedure Record_Ada_Source
9225 (File_Name : File_Name_Type;
9226 Path_Name : Path_Name_Type;
9227 Project : Project_Id;
9228 In_Tree : Project_Tree_Ref;
9229 Data : in out Project_Data;
9230 Location : Source_Ptr;
9231 Current_Source : in out String_List_Id;
9232 Source_Recorded : in out Boolean;
9233 Current_Dir : String)
9235 Canonical_File_Name : File_Name_Type;
9236 Canonical_Path_Name : Path_Name_Type;
9238 Exception_Id : Ada_Naming_Exception_Id;
9239 Unit_Name : Name_Id;
9240 Unit_Kind : Spec_Or_Body;
9241 Unit_Ind : Int := 0;
9243 Name_Index : Name_And_Index;
9244 Needs_Pragma : Boolean;
9246 The_Location : Source_Ptr := Location;
9247 Previous_Source : constant String_List_Id := Current_Source;
9248 Except_Name : Name_And_Index := No_Name_And_Index;
9250 Unit_Prj : Unit_Project;
9252 File_Name_Recorded : Boolean := False;
9255 if Osint.File_Names_Case_Sensitive then
9256 Canonical_File_Name := File_Name;
9257 Canonical_Path_Name := Path_Name;
9259 Get_Name_String (File_Name);
9260 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
9261 Canonical_File_Name := Name_Find;
9264 Canonical_Path : constant String :=
9266 (Get_Name_String (Path_Name),
9267 Directory => Current_Dir,
9268 Resolve_Links => Opt.Follow_Links_For_Files,
9269 Case_Sensitive => False);
9272 Add_Str_To_Name_Buffer (Canonical_Path);
9273 Canonical_Path_Name := Name_Find;
9277 -- Find out the unit name, the unit kind and if it needs
9278 -- a specific SFN pragma.
9281 (In_Tree => In_Tree,
9282 Canonical_File_Name => Canonical_File_Name,
9283 Naming => Data.Naming,
9284 Exception_Id => Exception_Id,
9285 Unit_Name => Unit_Name,
9286 Unit_Kind => Unit_Kind,
9287 Needs_Pragma => Needs_Pragma);
9289 if Exception_Id = No_Ada_Naming_Exception
9290 and then Unit_Name = No_Name
9292 if Current_Verbosity = High then
9294 Write_Str (Get_Name_String (Canonical_File_Name));
9295 Write_Line (""" is not a valid source file name (ignored).");
9299 -- Check to see if the source has been hidden by an exception,
9300 -- but only if it is not an exception.
9302 if not Needs_Pragma then
9304 Reverse_Ada_Naming_Exceptions.Get
9305 ((Unit_Kind, Unit_Name, No_Ada_Naming_Exception));
9307 if Except_Name /= No_Name_And_Index then
9308 if Current_Verbosity = High then
9310 Write_Str (Get_Name_String (Canonical_File_Name));
9311 Write_Str (""" contains a unit that is found in """);
9312 Write_Str (Get_Name_String (Except_Name.Name));
9313 Write_Line (""" (ignored).");
9316 -- The file is not included in the source of the project since
9317 -- it is hidden by the exception. So, nothing else to do.
9324 if Exception_Id /= No_Ada_Naming_Exception then
9325 Info := Ada_Naming_Exception_Table.Table (Exception_Id);
9326 Exception_Id := Info.Next;
9327 Info.Next := No_Ada_Naming_Exception;
9328 Name_Index := Reverse_Ada_Naming_Exceptions.Get (Info);
9330 Unit_Name := Info.Unit;
9331 Unit_Ind := Name_Index.Index;
9332 Unit_Kind := Info.Kind;
9335 -- Put the file name in the list of sources of the project
9337 String_Element_Table.Increment_Last (In_Tree.String_Elements);
9338 In_Tree.String_Elements.Table
9339 (String_Element_Table.Last (In_Tree.String_Elements)) :=
9340 (Value => Name_Id (Canonical_File_Name),
9341 Display_Value => Name_Id (File_Name),
9342 Location => No_Location,
9347 if Current_Source = Nil_String then
9349 String_Element_Table.Last (In_Tree.String_Elements);
9350 Data.Sources := Data.Ada_Sources;
9352 In_Tree.String_Elements.Table (Current_Source).Next :=
9353 String_Element_Table.Last (In_Tree.String_Elements);
9357 String_Element_Table.Last (In_Tree.String_Elements);
9359 -- Put the unit in unit list
9362 The_Unit : Unit_Index :=
9363 Units_Htable.Get (In_Tree.Units_HT, Unit_Name);
9365 The_Unit_Data : Unit_Data;
9368 if Current_Verbosity = High then
9369 Write_Str ("Putting ");
9370 Write_Str (Get_Name_String (Unit_Name));
9371 Write_Line (" in the unit list.");
9374 -- The unit is already in the list, but may be it is
9375 -- only the other unit kind (spec or body), or what is
9376 -- in the unit list is a unit of a project we are extending.
9378 if The_Unit /= No_Unit_Index then
9379 The_Unit_Data := In_Tree.Units.Table (The_Unit);
9381 if (The_Unit_Data.File_Names (Unit_Kind).Name =
9384 The_Unit_Data.File_Names (Unit_Kind).Path = Slash)
9385 or else The_Unit_Data.File_Names (Unit_Kind).Name = No_File
9386 or else Project_Extends
9388 The_Unit_Data.File_Names (Unit_Kind).Project,
9391 if The_Unit_Data.File_Names (Unit_Kind).Path = Slash then
9392 Remove_Forbidden_File_Name
9393 (The_Unit_Data.File_Names (Unit_Kind).Name);
9396 -- Record the file name in the hash table Files_Htable
9398 Unit_Prj := (Unit => The_Unit, Project => Project);
9401 Canonical_File_Name,
9404 The_Unit_Data.File_Names (Unit_Kind) :=
9405 (Name => Canonical_File_Name,
9407 Display_Name => File_Name,
9408 Path => Canonical_Path_Name,
9409 Display_Path => Path_Name,
9411 Needs_Pragma => Needs_Pragma);
9412 In_Tree.Units.Table (The_Unit) := The_Unit_Data;
9413 Source_Recorded := True;
9415 elsif The_Unit_Data.File_Names (Unit_Kind).Project = Project
9416 and then (Data.Known_Order_Of_Source_Dirs
9418 The_Unit_Data.File_Names (Unit_Kind).Path =
9419 Canonical_Path_Name)
9421 if Previous_Source = Nil_String then
9422 Data.Ada_Sources := Nil_String;
9423 Data.Sources := Nil_String;
9425 In_Tree.String_Elements.Table (Previous_Source).Next :=
9427 String_Element_Table.Decrement_Last
9428 (In_Tree.String_Elements);
9431 Current_Source := Previous_Source;
9434 -- It is an error to have two units with the same name
9435 -- and the same kind (spec or body).
9437 if The_Location = No_Location then
9439 In_Tree.Projects.Table (Project).Location;
9442 Err_Vars.Error_Msg_Name_1 := Unit_Name;
9444 (Project, In_Tree, "duplicate unit %%", The_Location);
9446 Err_Vars.Error_Msg_Name_1 :=
9447 In_Tree.Projects.Table
9448 (The_Unit_Data.File_Names (Unit_Kind).Project).Name;
9449 Err_Vars.Error_Msg_File_1 :=
9451 (The_Unit_Data.File_Names (Unit_Kind).Path);
9454 "\ project file %%, {", The_Location);
9456 Err_Vars.Error_Msg_Name_1 :=
9457 In_Tree.Projects.Table (Project).Name;
9458 Err_Vars.Error_Msg_File_1 :=
9459 File_Name_Type (Canonical_Path_Name);
9462 "\ project file %%, {", The_Location);
9465 -- It is a new unit, create a new record
9468 -- First, check if there is no other unit with this file
9469 -- name in another project. If it is, report error but note
9470 -- we do that only for the first unit in the source file.
9473 Files_Htable.Get (In_Tree.Files_HT, Canonical_File_Name);
9475 if not File_Name_Recorded and then
9476 Unit_Prj /= No_Unit_Project
9478 Error_Msg_File_1 := File_Name;
9480 In_Tree.Projects.Table (Unit_Prj.Project).Name;
9483 "{ is already a source of project %%",
9487 Unit_Table.Increment_Last (In_Tree.Units);
9488 The_Unit := Unit_Table.Last (In_Tree.Units);
9490 (In_Tree.Units_HT, Unit_Name, The_Unit);
9491 Unit_Prj := (Unit => The_Unit, Project => Project);
9494 Canonical_File_Name,
9496 The_Unit_Data.Name := Unit_Name;
9497 The_Unit_Data.File_Names (Unit_Kind) :=
9498 (Name => Canonical_File_Name,
9500 Display_Name => File_Name,
9501 Path => Canonical_Path_Name,
9502 Display_Path => Path_Name,
9504 Needs_Pragma => Needs_Pragma);
9505 In_Tree.Units.Table (The_Unit) := The_Unit_Data;
9506 Source_Recorded := True;
9511 exit when Exception_Id = No_Ada_Naming_Exception;
9512 File_Name_Recorded := True;
9515 end Record_Ada_Source;
9517 --------------------------
9518 -- Record_Other_Sources --
9519 --------------------------
9521 procedure Record_Other_Sources
9522 (Project : Project_Id;
9523 In_Tree : Project_Tree_Ref;
9524 Data : in out Project_Data;
9525 Language : Language_Index;
9526 Naming_Exceptions : Boolean)
9528 Source_Dir : String_List_Id;
9529 Element : String_Element;
9530 Path : Path_Name_Type;
9532 Canonical_Name : File_Name_Type;
9533 Name_Str : String (1 .. 1_024);
9534 Last : Natural := 0;
9536 First_Error : Boolean := True;
9537 Suffix : constant String :=
9538 Body_Suffix_Of (Language, Data, In_Tree);
9541 Source_Dir := Data.Source_Dirs;
9542 while Source_Dir /= Nil_String loop
9543 Element := In_Tree.String_Elements.Table (Source_Dir);
9546 Dir_Path : constant String :=
9547 Get_Name_String (Element.Display_Value);
9549 if Current_Verbosity = High then
9550 Write_Str ("checking directory """);
9551 Write_Str (Dir_Path);
9552 Write_Str (""" for ");
9554 if Naming_Exceptions then
9555 Write_Str ("naming exceptions");
9557 Write_Str ("sources");
9560 Write_Str (" of Language ");
9561 Display_Language_Name (Language);
9564 Open (Dir, Dir_Path);
9567 Read (Dir, Name_Str, Last);
9571 (Dir_Path & Directory_Separator & Name_Str (1 .. Last))
9574 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
9575 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
9576 Canonical_Name := Name_Find;
9577 NL := Source_Names.Get (Canonical_Name);
9579 if NL /= No_Name_Location then
9581 if not Data.Known_Order_Of_Source_Dirs then
9582 Error_Msg_File_1 := Canonical_Name;
9585 "{ is found in several source directories",
9591 Source_Names.Set (Canonical_Name, NL);
9592 Name_Len := Dir_Path'Length;
9593 Name_Buffer (1 .. Name_Len) := Dir_Path;
9594 Add_Char_To_Name_Buffer (Directory_Separator);
9595 Add_Str_To_Name_Buffer (Name_Str (1 .. Last));
9599 (File_Name => Canonical_Name,
9604 Location => NL.Location,
9605 Language => Language,
9607 Naming_Exception => Naming_Exceptions);
9616 Source_Dir := Element.Next;
9619 if not Naming_Exceptions then
9620 NL := Source_Names.Get_First;
9622 -- It is an error if a source file name in a source list or
9623 -- in a source list file is not found.
9625 while NL /= No_Name_Location loop
9626 if not NL.Found then
9627 Err_Vars.Error_Msg_File_1 := NL.Name;
9631 (Project, In_Tree, "source file { cannot be found",
9633 First_Error := False;
9637 (Project, In_Tree, "\source file { cannot be found",
9642 NL := Source_Names.Get_Next;
9645 -- Any naming exception of this language that is not in a list
9646 -- of sources must be removed.
9649 Source_Id : Other_Source_Id;
9650 Prev_Id : Other_Source_Id;
9651 Source : Other_Source;
9654 Prev_Id := No_Other_Source;
9655 Source_Id := Data.First_Other_Source;
9656 while Source_Id /= No_Other_Source loop
9657 Source := In_Tree.Other_Sources.Table (Source_Id);
9659 if Source.Language = Language
9660 and then Source.Naming_Exception
9662 if Current_Verbosity = High then
9663 Write_Str ("Naming exception """);
9664 Write_Str (Get_Name_String (Source.File_Name));
9665 Write_Str (""" is not in the list of sources,");
9666 Write_Line (" so it is removed.");
9669 if Prev_Id = No_Other_Source then
9670 Data.First_Other_Source := Source.Next;
9672 In_Tree.Other_Sources.Table (Prev_Id).Next := Source.Next;
9675 Source_Id := Source.Next;
9677 if Source_Id = No_Other_Source then
9678 Data.Last_Other_Source := Prev_Id;
9682 Prev_Id := Source_Id;
9683 Source_Id := Source.Next;
9688 end Record_Other_Sources;
9694 procedure Remove_Source
9696 Replaced_By : Source_Id;
9697 Project : Project_Id;
9698 Data : in out Project_Data;
9699 In_Tree : Project_Tree_Ref)
9701 Src_Data : constant Source_Data := In_Tree.Sources.Table (Id);
9705 if Current_Verbosity = High then
9706 Write_Str ("Removing source #");
9707 Write_Line (Id'Img);
9710 if Replaced_By /= No_Source then
9711 In_Tree.Sources.Table (Id).Replaced_By := Replaced_By;
9712 In_Tree.Sources.Table (Replaced_By).Declared_In_Interfaces :=
9713 In_Tree.Sources.Table (Id).Declared_In_Interfaces;
9716 -- Remove the source from the global source list
9718 Source := In_Tree.First_Source;
9721 In_Tree.First_Source := Src_Data.Next_In_Sources;
9724 while In_Tree.Sources.Table (Source).Next_In_Sources /= Id loop
9725 Source := In_Tree.Sources.Table (Source).Next_In_Sources;
9728 In_Tree.Sources.Table (Source).Next_In_Sources :=
9729 Src_Data.Next_In_Sources;
9732 -- Remove the source from the project list
9734 if Src_Data.Project = Project then
9735 Source := Data.First_Source;
9738 Data.First_Source := Src_Data.Next_In_Project;
9740 if Src_Data.Next_In_Project = No_Source then
9741 Data.Last_Source := No_Source;
9745 while In_Tree.Sources.Table (Source).Next_In_Project /= Id loop
9746 Source := In_Tree.Sources.Table (Source).Next_In_Project;
9749 In_Tree.Sources.Table (Source).Next_In_Project :=
9750 Src_Data.Next_In_Project;
9752 if Src_Data.Next_In_Project = No_Source then
9753 In_Tree.Projects.Table (Src_Data.Project).Last_Source := Source;
9758 Source := In_Tree.Projects.Table (Src_Data.Project).First_Source;
9761 In_Tree.Projects.Table (Src_Data.Project).First_Source :=
9762 Src_Data.Next_In_Project;
9764 if Src_Data.Next_In_Project = No_Source then
9765 In_Tree.Projects.Table (Src_Data.Project).Last_Source :=
9770 while In_Tree.Sources.Table (Source).Next_In_Project /= Id loop
9771 Source := In_Tree.Sources.Table (Source).Next_In_Project;
9774 In_Tree.Sources.Table (Source).Next_In_Project :=
9775 Src_Data.Next_In_Project;
9777 if Src_Data.Next_In_Project = No_Source then
9778 In_Tree.Projects.Table (Src_Data.Project).Last_Source := Source;
9783 -- Remove source from the language list
9785 Source := In_Tree.Languages_Data.Table (Src_Data.Language).First_Source;
9788 In_Tree.Languages_Data.Table (Src_Data.Language).First_Source :=
9789 Src_Data.Next_In_Lang;
9792 while In_Tree.Sources.Table (Source).Next_In_Lang /= Id loop
9793 Source := In_Tree.Sources.Table (Source).Next_In_Lang;
9796 In_Tree.Sources.Table (Source).Next_In_Lang :=
9797 Src_Data.Next_In_Lang;
9801 -----------------------
9802 -- Report_No_Sources --
9803 -----------------------
9805 procedure Report_No_Sources
9806 (Project : Project_Id;
9808 In_Tree : Project_Tree_Ref;
9809 Location : Source_Ptr;
9810 Continuation : Boolean := False)
9813 case When_No_Sources is
9817 when Warning | Error =>
9819 Msg : constant String :=
9822 " sources in this project";
9825 Error_Msg_Warn := When_No_Sources = Warning;
9827 if Continuation then
9829 (Project, In_Tree, "\" & Msg, Location);
9833 (Project, In_Tree, Msg, Location);
9837 end Report_No_Sources;
9839 ----------------------
9840 -- Show_Source_Dirs --
9841 ----------------------
9843 procedure Show_Source_Dirs
9844 (Data : Project_Data;
9845 In_Tree : Project_Tree_Ref)
9847 Current : String_List_Id;
9848 Element : String_Element;
9851 Write_Line ("Source_Dirs:");
9853 Current := Data.Source_Dirs;
9854 while Current /= Nil_String loop
9855 Element := In_Tree.String_Elements.Table (Current);
9857 Write_Line (Get_Name_String (Element.Value));
9858 Current := Element.Next;
9861 Write_Line ("end Source_Dirs.");
9862 end Show_Source_Dirs;
9869 (Language : Language_Index;
9870 Naming : Naming_Data;
9871 In_Tree : Project_Tree_Ref) return File_Name_Type
9873 Suffix : constant Variable_Value :=
9875 (Index => Language_Names.Table (Language),
9877 In_Array => Naming.Body_Suffix,
9878 In_Tree => In_Tree);
9881 -- If no suffix for this language in package Naming, use the default
9883 if Suffix = Nil_Variable_Value then
9887 when Ada_Language_Index =>
9888 Add_Str_To_Name_Buffer (".adb");
9890 when C_Language_Index =>
9891 Add_Str_To_Name_Buffer (".c");
9893 when C_Plus_Plus_Language_Index =>
9894 Add_Str_To_Name_Buffer (".cpp");
9900 -- Otherwise use the one specified
9903 Get_Name_String (Suffix.Value);
9906 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
9910 -------------------------
9911 -- Warn_If_Not_Sources --
9912 -------------------------
9914 -- comments needed in this body ???
9916 procedure Warn_If_Not_Sources
9917 (Project : Project_Id;
9918 In_Tree : Project_Tree_Ref;
9919 Conventions : Array_Element_Id;
9921 Extending : Boolean)
9923 Conv : Array_Element_Id;
9925 The_Unit_Id : Unit_Index;
9926 The_Unit_Data : Unit_Data;
9927 Location : Source_Ptr;
9930 Conv := Conventions;
9931 while Conv /= No_Array_Element loop
9932 Unit := In_Tree.Array_Elements.Table (Conv).Index;
9933 Error_Msg_Name_1 := Unit;
9934 Get_Name_String (Unit);
9935 To_Lower (Name_Buffer (1 .. Name_Len));
9937 The_Unit_Id := Units_Htable.Get (In_Tree.Units_HT, Unit);
9938 Location := In_Tree.Array_Elements.Table (Conv).Value.Location;
9940 if The_Unit_Id = No_Unit_Index then
9941 Error_Msg (Project, In_Tree, "?unknown unit %%", Location);
9944 The_Unit_Data := In_Tree.Units.Table (The_Unit_Id);
9946 In_Tree.Array_Elements.Table (Conv).Value.Value;
9949 if not Check_Project
9950 (The_Unit_Data.File_Names (Specification).Project,
9951 Project, In_Tree, Extending)
9955 "?source of spec of unit %% (%%)" &
9956 " cannot be found in this project",
9961 if not Check_Project
9962 (The_Unit_Data.File_Names (Body_Part).Project,
9963 Project, In_Tree, Extending)
9967 "?source of body of unit %% (%%)" &
9968 " cannot be found in this project",
9974 Conv := In_Tree.Array_Elements.Table (Conv).Next;
9976 end Warn_If_Not_Sources;