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 package Object_File_Names is new GNAT.HTable.Simple_HTable
166 (Header_Num => Header_Num,
167 Element => File_Name_Type,
168 No_Element => No_File,
169 Key => File_Name_Type,
172 -- A hash table to store the object file names for a project, to check that
173 -- two different sources have different object file names.
175 type File_Found is record
176 File : File_Name_Type := No_File;
177 Found : Boolean := False;
178 Location : Source_Ptr := No_Location;
180 No_File_Found : constant File_Found := (No_File, False, No_Location);
181 -- Comments needed ???
183 package Excluded_Sources_Htable is new GNAT.HTable.Simple_HTable
184 (Header_Num => Header_Num,
185 Element => File_Found,
186 No_Element => No_File_Found,
187 Key => File_Name_Type,
190 -- A hash table to store the excluded files, if any. This is filled by
191 -- Find_Excluded_Sources below.
193 procedure Find_Excluded_Sources
194 (Project : Project_Id;
195 In_Tree : Project_Tree_Ref;
196 Data : Project_Data);
197 -- Find the list of files that should not be considered as source files
198 -- for this project. Sets the list in the Excluded_Sources_Htable.
200 function Hash (Unit : Unit_Info) return Header_Num;
202 type Name_And_Index is record
203 Name : Name_Id := No_Name;
206 No_Name_And_Index : constant Name_And_Index :=
207 (Name => No_Name, Index => 0);
209 package Reverse_Ada_Naming_Exceptions is new GNAT.HTable.Simple_HTable
210 (Header_Num => Header_Num,
211 Element => Name_And_Index,
212 No_Element => No_Name_And_Index,
216 -- A table to check if a unit with an exceptional name will hide a source
217 -- with a file name following the naming convention.
221 Data : in out Project_Data;
222 In_Tree : Project_Tree_Ref;
223 Project : Project_Id;
225 Lang_Id : Language_Index;
227 File_Name : File_Name_Type;
228 Display_File : File_Name_Type;
229 Lang_Kind : Language_Kind;
230 Naming_Exception : Boolean := False;
231 Path : Path_Name_Type := No_Path;
232 Display_Path : Path_Name_Type := No_Path;
233 Alternate_Languages : Alternate_Language_Id := No_Alternate_Language;
234 Other_Part : Source_Id := No_Source;
235 Unit : Name_Id := No_Name;
237 Source_To_Replace : Source_Id := No_Source);
238 -- Add a new source to the different lists: list of all sources in the
239 -- project tree, list of source of a project and list of sources of a
242 -- If Path is specified, the file is also added to Source_Paths_HT.
243 -- If Source_To_Replace is specified, it points to the source in the
244 -- extended project that the new file is overriding.
246 function ALI_File_Name (Source : String) return String;
247 -- Return the ALI file name corresponding to a source
249 procedure Check_Ada_Name (Name : String; Unit : out Name_Id);
250 -- Check that a name is a valid Ada unit name
252 procedure Check_Naming_Schemes
253 (Data : in out Project_Data;
254 Project : Project_Id;
255 In_Tree : Project_Tree_Ref);
256 -- Check the naming scheme part of Data
258 procedure Check_Ada_Naming_Scheme_Validity
259 (Project : Project_Id;
260 In_Tree : Project_Tree_Ref;
261 Naming : Naming_Data);
262 -- Check that the package Naming is correct
264 procedure Check_Configuration
265 (Project : Project_Id;
266 In_Tree : Project_Tree_Ref;
267 Data : in out Project_Data);
268 -- Check the configuration attributes for the project
270 procedure Check_For_Source
271 (File_Name : File_Name_Type;
272 Path_Name : Path_Name_Type;
273 Project : Project_Id;
274 In_Tree : Project_Tree_Ref;
275 Data : in out Project_Data;
276 Location : Source_Ptr;
277 Language : Language_Index;
279 Naming_Exception : Boolean);
280 -- Check if a file, with name File_Name and path Path_Name, in a source
281 -- directory is a source for language Language in project Project of
282 -- project tree In_Tree. ???
284 procedure Check_If_Externally_Built
285 (Project : Project_Id;
286 In_Tree : Project_Tree_Ref;
287 Data : in out Project_Data);
288 -- Check attribute Externally_Built of project Project in project tree
289 -- In_Tree and modify its data Data if it has the value "true".
291 procedure Check_Interfaces
292 (Project : Project_Id;
293 In_Tree : Project_Tree_Ref;
294 Data : in out Project_Data);
295 -- If a list of sources is specified in attribute Interfaces, set
296 -- In_Interfaces only for the sources specified in the list.
298 procedure Check_Library_Attributes
299 (Project : Project_Id;
300 In_Tree : Project_Tree_Ref;
301 Current_Dir : String;
302 Data : in out Project_Data);
303 -- Check the library attributes of project Project in project tree In_Tree
304 -- and modify its data Data accordingly.
305 -- Current_Dir should represent the current directory, and is passed for
306 -- efficiency to avoid system calls to recompute it.
308 procedure Check_Package_Naming
309 (Project : Project_Id;
310 In_Tree : Project_Tree_Ref;
311 Data : in out Project_Data);
312 -- Check package Naming of project Project in project tree In_Tree and
313 -- modify its data Data accordingly.
315 procedure Check_Programming_Languages
316 (In_Tree : Project_Tree_Ref;
317 Project : Project_Id;
318 Data : in out Project_Data);
319 -- Check attribute Languages for the project with data Data in project
320 -- tree In_Tree and set the components of Data for all the programming
321 -- languages indicated in attribute Languages, if any.
323 function Check_Project
325 Root_Project : Project_Id;
326 In_Tree : Project_Tree_Ref;
327 Extending : Boolean) return Boolean;
328 -- Returns True if P is Root_Project or, if Extending is True, a project
329 -- extended by Root_Project.
331 procedure Check_Stand_Alone_Library
332 (Project : Project_Id;
333 In_Tree : Project_Tree_Ref;
334 Data : in out Project_Data;
335 Current_Dir : String;
336 Extending : Boolean);
337 -- Check if project Project in project tree In_Tree is a Stand-Alone
338 -- Library project, and modify its data Data accordingly if it is one.
339 -- Current_Dir should represent the current directory, and is passed for
340 -- efficiency to avoid system calls to recompute it.
342 procedure Get_Path_Names_And_Record_Ada_Sources
343 (Project : Project_Id;
344 In_Tree : Project_Tree_Ref;
345 Data : in out Project_Data;
346 Current_Dir : String);
347 -- Find the path names of the source files in the Source_Names table
348 -- in the source directories and record those that are Ada sources.
350 function Compute_Directory_Last (Dir : String) return Natural;
351 -- Return the index of the last significant character in Dir. This is used
352 -- to avoid duplicate '/' (slash) characters at the end of directory names.
355 (Project : Project_Id;
356 In_Tree : Project_Tree_Ref;
358 Flag_Location : Source_Ptr);
359 -- Output an error message. If Error_Report is null, simply call
360 -- Prj.Err.Error_Msg. Otherwise, disregard Flag_Location and use
363 procedure Find_Ada_Sources
364 (Project : Project_Id;
365 In_Tree : Project_Tree_Ref;
366 Data : in out Project_Data;
367 Current_Dir : String);
368 -- Find all the Ada sources in all of the source directories of a project
369 -- Current_Dir should represent the current directory, and is passed for
370 -- efficiency to avoid system calls to recompute it.
372 procedure Find_Sources
373 (Project : Project_Id;
374 In_Tree : Project_Tree_Ref;
375 Data : in out Project_Data;
376 For_Language : Language_Index;
377 Current_Dir : String);
378 -- Find all the sources in all of the source directories of a project for
379 -- a specified language.
381 procedure Search_Directories
382 (Project : Project_Id;
383 In_Tree : Project_Tree_Ref;
384 Data : in out Project_Data;
385 For_All_Sources : Boolean);
386 -- Search the source directories to find the sources.
387 -- If For_All_Sources is True, check each regular file name against the
388 -- naming schemes of the different languages. Otherwise consider only the
389 -- file names in the hash table Source_Names.
392 (Project : Project_Id;
393 In_Tree : Project_Tree_Ref;
394 Data : in out Project_Data;
396 File_Name : File_Name_Type;
397 Display_File_Name : File_Name_Type;
398 Source_Directory : String;
399 For_All_Sources : Boolean);
400 -- Check if file File_Name is a valid source of the project. This is used
401 -- in multi-language mode only.
402 -- When the file matches one of the naming schemes, it is added to
403 -- various htables through Add_Source and to Source_Paths_Htable.
405 -- Name is the name of the candidate file. It hasn't been normalized yet
406 -- and is the direct result of readdir().
408 -- File_Name is the same as Name, but has been normalized.
409 -- Display_File_Name, however, has not been normalized.
411 -- Source_Directory is the directory in which the file
412 -- was found. It hasn't been normalized (nor has had links resolved).
413 -- It should not end with a directory separator, to avoid duplicates
416 -- If For_All_Sources is True, then all possible file names are analyzed
417 -- otherwise only those currently set in the Source_Names htable.
419 procedure Check_Naming_Schemes
420 (In_Tree : Project_Tree_Ref;
421 Data : in out Project_Data;
423 File_Name : File_Name_Type;
424 Alternate_Languages : out Alternate_Language_Id;
425 Language : out Language_Index;
426 Language_Name : out Name_Id;
427 Display_Language_Name : out Name_Id;
429 Lang_Kind : out Language_Kind;
430 Kind : out Source_Kind);
431 -- Check if the file name File_Name conforms to one of the naming
432 -- schemes of the project.
434 -- If the file does not match one of the naming schemes, set Language
435 -- to No_Language_Index.
437 -- Filename is the name of the file being investigated. It has been
438 -- normalized (case-folded). File_Name is the same value.
440 procedure Free_Ada_Naming_Exceptions;
441 -- Free the internal hash tables used for checking naming exceptions
443 procedure Get_Directories
444 (Project : Project_Id;
445 In_Tree : Project_Tree_Ref;
446 Current_Dir : String;
447 Data : in out Project_Data);
448 -- Get the object directory, the exec directory and the source directories
451 -- Current_Dir should represent the current directory, and is passed for
452 -- efficiency to avoid system calls to recompute it.
455 (Project : Project_Id;
456 In_Tree : Project_Tree_Ref;
457 Data : in out Project_Data);
458 -- Get the mains of a project from attribute Main, if it exists, and put
459 -- them in the project data.
461 procedure Get_Sources_From_File
463 Location : Source_Ptr;
464 Project : Project_Id;
465 In_Tree : Project_Tree_Ref);
466 -- Get the list of sources from a text file and put them in hash table
469 procedure Find_Explicit_Sources
470 (Lang : Language_Index;
471 Current_Dir : String;
472 Project : Project_Id;
473 In_Tree : Project_Tree_Ref;
474 Data : in out Project_Data);
475 -- Process the Source_Files and Source_List_File attributes, and store
476 -- the list of source files into the Source_Names htable.
478 -- Lang indicates which language is being processed when in Ada_Only mode
479 -- (all languages are processed anyway when in Multi_Language mode).
482 (In_Tree : Project_Tree_Ref;
483 Canonical_File_Name : File_Name_Type;
484 Naming : Naming_Data;
485 Exception_Id : out Ada_Naming_Exception_Id;
486 Unit_Name : out Name_Id;
487 Unit_Kind : out Spec_Or_Body;
488 Needs_Pragma : out Boolean);
489 -- Find out, from a file name, the unit name, the unit kind and if a
490 -- specific SFN pragma is needed. If the file name corresponds to no unit,
491 -- then Unit_Name will be No_Name. If the file is a multi-unit source or an
492 -- exception to the naming scheme, then Exception_Id is set to the unit or
493 -- units that the source contains.
495 function Is_Illegal_Suffix
497 Dot_Replacement_Is_A_Single_Dot : Boolean) return Boolean;
498 -- Returns True if the string Suffix cannot be used as a spec suffix, a
499 -- body suffix or a separate suffix.
501 procedure Locate_Directory
502 (Project : Project_Id;
503 In_Tree : Project_Tree_Ref;
504 Name : File_Name_Type;
505 Parent : Path_Name_Type;
506 Dir : out Path_Name_Type;
507 Display : out Path_Name_Type;
508 Create : String := "";
509 Current_Dir : String;
510 Location : Source_Ptr := No_Location);
511 -- Locate a directory. Name is the directory name. Parent is the root
512 -- directory, if Name a relative path name. Dir is set to the canonical
513 -- case path name of the directory, and Display is the directory path name
514 -- for display purposes. If the directory does not exist and Project_Setup
515 -- is True and Create is a non null string, an attempt is made to create
516 -- the directory. If the directory does not exist and Project_Setup is
517 -- false, then Dir and Display are set to No_Name.
519 -- Current_Dir should represent the current directory, and is passed for
520 -- efficiency to avoid system calls to recompute it.
522 procedure Look_For_Sources
523 (Project : Project_Id;
524 In_Tree : Project_Tree_Ref;
525 Data : in out Project_Data;
526 Current_Dir : String);
527 -- Find all the sources of project Project in project tree In_Tree and
528 -- update its Data accordingly.
530 -- Current_Dir should represent the current directory, and is passed for
531 -- efficiency to avoid system calls to recompute it.
533 function Path_Name_Of
534 (File_Name : File_Name_Type;
535 Directory : Path_Name_Type) return String;
536 -- Returns the path name of a (non project) file. Returns an empty string
537 -- if file cannot be found.
539 procedure Prepare_Ada_Naming_Exceptions
540 (List : Array_Element_Id;
541 In_Tree : Project_Tree_Ref;
542 Kind : Spec_Or_Body);
543 -- Prepare the internal hash tables used for checking naming exceptions
544 -- for Ada. Insert all elements of List in the tables.
546 function Project_Extends
547 (Extending : Project_Id;
548 Extended : Project_Id;
549 In_Tree : Project_Tree_Ref) return Boolean;
550 -- Returns True if Extending is extending Extended either directly or
553 procedure Record_Ada_Source
554 (File_Name : File_Name_Type;
555 Path_Name : Path_Name_Type;
556 Project : Project_Id;
557 In_Tree : Project_Tree_Ref;
558 Data : in out Project_Data;
559 Location : Source_Ptr;
560 Current_Source : in out String_List_Id;
561 Source_Recorded : in out Boolean;
562 Current_Dir : String);
563 -- Put a unit in the list of units of a project, if the file name
564 -- corresponds to a valid unit name.
566 -- Current_Dir should represent the current directory, and is passed for
567 -- efficiency to avoid system calls to recompute it.
569 procedure Record_Other_Sources
570 (Project : Project_Id;
571 In_Tree : Project_Tree_Ref;
572 Data : in out Project_Data;
573 Language : Language_Index;
574 Naming_Exceptions : Boolean);
575 -- Record the sources of a language in a project. When Naming_Exceptions is
576 -- True, mark the found sources as such, to later remove those that are not
577 -- named in a list of sources.
579 procedure Remove_Source
581 Replaced_By : Source_Id;
582 Project : Project_Id;
583 Data : in out Project_Data;
584 In_Tree : Project_Tree_Ref);
587 procedure Report_No_Sources
588 (Project : Project_Id;
590 In_Tree : Project_Tree_Ref;
591 Location : Source_Ptr;
592 Continuation : Boolean := False);
593 -- Report an error or a warning depending on the value of When_No_Sources
594 -- when there are no sources for language Lang_Name.
596 procedure Show_Source_Dirs
597 (Data : Project_Data; In_Tree : Project_Tree_Ref);
598 -- List all the source directories of a project
601 (Language : Language_Index;
602 Naming : Naming_Data;
603 In_Tree : Project_Tree_Ref) return File_Name_Type;
604 -- Get the suffix for the source of a language from a package naming. If
605 -- not specified, return the default for the language.
607 procedure Warn_If_Not_Sources
608 (Project : Project_Id;
609 In_Tree : Project_Tree_Ref;
610 Conventions : Array_Element_Id;
612 Extending : Boolean);
613 -- Check that individual naming conventions apply to immediate sources of
614 -- the project. If not, issue a warning.
622 Data : in out Project_Data;
623 In_Tree : Project_Tree_Ref;
624 Project : Project_Id;
626 Lang_Id : Language_Index;
628 File_Name : File_Name_Type;
629 Display_File : File_Name_Type;
630 Lang_Kind : Language_Kind;
631 Naming_Exception : Boolean := False;
632 Path : Path_Name_Type := No_Path;
633 Display_Path : Path_Name_Type := No_Path;
634 Alternate_Languages : Alternate_Language_Id := No_Alternate_Language;
635 Other_Part : Source_Id := No_Source;
636 Unit : Name_Id := No_Name;
638 Source_To_Replace : Source_Id := No_Source)
640 Source : constant Source_Id := Data.Last_Source;
641 Src_Data : Source_Data := No_Source_Data;
642 Config : constant Language_Config :=
643 In_Tree.Languages_Data.Table (Lang_Id).Config;
646 -- This is a new source so create an entry for it in the Sources table
648 Source_Data_Table.Increment_Last (In_Tree.Sources);
649 Id := Source_Data_Table.Last (In_Tree.Sources);
651 if Current_Verbosity = High then
652 Write_Str ("Adding source #
");
654 Write_Str (", File
: ");
655 Write_Str (Get_Name_String (File_Name));
657 if Lang_Kind = Unit_Based then
658 Write_Str (", Unit
: ");
659 Write_Str (Get_Name_String (Unit));
665 Src_Data.Project := Project;
666 Src_Data.Language_Name := Lang;
667 Src_Data.Language := Lang_Id;
668 Src_Data.Lang_Kind := Lang_Kind;
669 Src_Data.Compiled := In_Tree.Languages_Data.Table
670 (Lang_Id).Config.Compiler_Driver /=
672 Src_Data.Kind := Kind;
673 Src_Data.Alternate_Languages := Alternate_Languages;
674 Src_Data.Other_Part := Other_Part;
676 Src_Data.Object_Exists := Config.Object_Generated;
677 Src_Data.Object_Linked := Config.Objects_Linked;
679 if Other_Part /= No_Source then
680 In_Tree.Sources.Table (Other_Part).Other_Part := Id;
683 Src_Data.Unit := Unit;
684 Src_Data.Index := Index;
685 Src_Data.File := File_Name;
686 Src_Data.Display_File := Display_File;
687 Src_Data.Dependency := In_Tree.Languages_Data.Table
688 (Lang_Id).Config.Dependency_Kind;
689 Src_Data.Naming_Exception := Naming_Exception;
691 if Src_Data.Compiled and then Src_Data.Object_Exists then
692 Src_Data.Object := Object_Name (File_Name);
694 Dependency_Name (File_Name, Src_Data.Dependency);
695 Src_Data.Switches := Switches_Name (File_Name);
698 if Path /= No_Path then
699 Src_Data.Path := (Path, Display_Path);
700 Source_Paths_Htable.Set (In_Tree.Source_Paths_HT, Path, Id);
703 -- Add the source to the global list
705 Src_Data.Next_In_Sources := In_Tree.First_Source;
706 In_Tree.First_Source := Id;
708 -- Add the source to the project list
710 if Source = No_Source then
711 Data.First_Source := Id;
713 In_Tree.Sources.Table (Source).Next_In_Project := Id;
716 Data.Last_Source := Id;
718 -- Add the source to the language list
720 Src_Data.Next_In_Lang :=
721 In_Tree.Languages_Data.Table (Lang_Id).First_Source;
722 In_Tree.Languages_Data.Table (Lang_Id).First_Source := Id;
724 In_Tree.Sources.Table (Id) := Src_Data;
726 if Source_To_Replace /= No_Source then
727 Remove_Source (Source_To_Replace, Id, Project, Data, In_Tree);
735 function ALI_File_Name (Source : String) return String is
737 -- If the source name has an extension, then replace it with
740 for Index in reverse Source'First + 1 .. Source'Last loop
741 if Source (Index) = '.' then
742 return Source (Source'First .. Index - 1) & ALI_Suffix;
746 -- If there is no dot, or if it is the first character, just add the
749 return Source & ALI_Suffix;
757 (Project : Project_Id;
758 In_Tree : Project_Tree_Ref;
759 Report_Error : Put_Line_Access;
760 When_No_Sources : Error_Warning;
761 Current_Dir : String)
763 Data : Project_Data := In_Tree.Projects.Table (Project);
764 Extending : Boolean := False;
767 Nmsc.When_No_Sources := When_No_Sources;
768 Error_Report := Report_Error;
770 Recursive_Dirs.Reset;
772 Check_If_Externally_Built (Project, In_Tree, Data);
774 -- Object, exec and source directories
776 Get_Directories (Project, In_Tree, Current_Dir, Data);
778 -- Get the programming languages
780 Check_Programming_Languages (In_Tree, Project, Data);
782 if Data.Qualifier = Dry and then Data.Source_Dirs /= Nil_String then
785 "an
abstract project need to have no language
, no sources
or no
" &
786 "source directories
",
790 -- Check configuration in multi language mode
792 if Must_Check_Configuration then
793 Check_Configuration (Project, In_Tree, Data);
796 -- Library attributes
798 Check_Library_Attributes (Project, In_Tree, Current_Dir, Data);
800 if Current_Verbosity = High then
801 Show_Source_Dirs (Data, In_Tree);
804 Check_Package_Naming (Project, In_Tree, Data);
806 Extending := Data.Extends /= No_Project;
808 Check_Naming_Schemes (Data, Project, In_Tree);
810 if Get_Mode = Ada_Only then
811 Prepare_Ada_Naming_Exceptions
812 (Data.Naming.Bodies, In_Tree, Body_Part);
813 Prepare_Ada_Naming_Exceptions
814 (Data.Naming.Specs, In_Tree, Specification);
819 if Data.Source_Dirs /= Nil_String then
820 Look_For_Sources (Project, In_Tree, Data, Current_Dir);
822 if Get_Mode = Ada_Only then
824 -- Check that all individual naming conventions apply to sources
825 -- of this project file.
828 (Project, In_Tree, Data.Naming.Bodies,
830 Extending => Extending);
832 (Project, In_Tree, Data.Naming.Specs,
834 Extending => Extending);
836 elsif Get_Mode = Multi_Language and then
837 (not Data.Externally_Built) and then
841 Language : Language_Index;
843 Src_Data : Source_Data;
844 Alt_Lang : Alternate_Language_Id;
845 Alt_Lang_Data : Alternate_Language_Data;
846 Continuation : Boolean := False;
849 Language := Data.First_Language_Processing;
850 while Language /= No_Language_Index loop
851 Source := Data.First_Source;
852 Source_Loop : while Source /= No_Source loop
853 Src_Data := In_Tree.Sources.Table (Source);
855 exit Source_Loop when Src_Data.Language = Language;
857 Alt_Lang := Src_Data.Alternate_Languages;
860 while Alt_Lang /= No_Alternate_Language loop
862 In_Tree.Alt_Langs.Table (Alt_Lang);
864 when Alt_Lang_Data.Language = Language;
865 Alt_Lang := Alt_Lang_Data.Next;
866 end loop Alternate_Loop;
868 Source := Src_Data.Next_In_Project;
869 end loop Source_Loop;
871 if Source = No_Source then
875 (In_Tree.Languages_Data.Table
876 (Language).Display_Name),
880 Continuation := True;
883 Language := In_Tree.Languages_Data.Table (Language).Next;
889 if Get_Mode = Multi_Language then
891 -- If a list of sources is specified in attribute Interfaces, set
892 -- In_Interfaces only for the sources specified in the list.
894 Check_Interfaces (Project, In_Tree, Data);
897 -- If it is a library project file, check if it is a standalone library
900 Check_Stand_Alone_Library
901 (Project, In_Tree, Data, Current_Dir, Extending);
904 -- Put the list of Mains, if any, in the project data
906 Get_Mains (Project, In_Tree, Data);
908 -- Update the project data in the Projects table
910 In_Tree.Projects.Table (Project) := Data;
912 Free_Ada_Naming_Exceptions;
919 procedure Check_Ada_Name (Name : String; Unit : out Name_Id) is
920 The_Name : String := Name;
922 Need_Letter : Boolean := True;
923 Last_Underscore : Boolean := False;
924 OK : Boolean := The_Name'Length > 0;
927 function Is_Reserved (Name : Name_Id) return Boolean;
928 function Is_Reserved (S : String) return Boolean;
929 -- Check that the given name is not an Ada 95 reserved word. The reason
930 -- for the Ada 95 here is that we do not want to exclude the case of an
931 -- Ada 95 unit called Interface (for example). In Ada 2005, such a unit
932 -- name would be rejected anyway by the compiler. That means there is no
933 -- requirement that the project file parser reject this.
939 function Is_Reserved (S : String) return Boolean is
942 Add_Str_To_Name_Buffer (S);
943 return Is_Reserved (Name_Find);
950 function Is_Reserved (Name : Name_Id) return Boolean is
952 if Get_Name_Table_Byte (Name) /= 0
953 and then Name /= Name_Project
954 and then Name /= Name_Extends
955 and then Name /= Name_External
956 and then Name not in Ada_2005_Reserved_Words
960 if Current_Verbosity = High then
961 Write_Str (The_Name);
962 Write_Line (" is an Ada reserved word
.");
972 -- Start of processing for Check_Ada_Name
977 Name_Len := The_Name'Length;
978 Name_Buffer (1 .. Name_Len) := The_Name;
980 -- Special cases of children of packages A, G, I and S on VMS
983 and then Name_Len > 3
984 and then Name_Buffer (2 .. 3) = "__
"
986 ((Name_Buffer (1) = 'a') or else
987 (Name_Buffer (1) = 'g') or else
988 (Name_Buffer (1) = 'i') or else
989 (Name_Buffer (1) = 's'))
991 Name_Buffer (2) := '.';
992 Name_Buffer (3 .. Name_Len - 1) := Name_Buffer (4 .. Name_Len);
993 Name_Len := Name_Len - 1;
996 Real_Name := Name_Find;
998 if Is_Reserved (Real_Name) then
1002 First := The_Name'First;
1004 for Index in The_Name'Range loop
1007 -- We need a letter (at the beginning, and following a dot),
1008 -- but we don't have one.
1010 if Is_Letter (The_Name (Index)) then
1011 Need_Letter := False;
1016 if Current_Verbosity = High then
1017 Write_Int (Types.Int (Index));
1019 Write_Char (The_Name (Index));
1020 Write_Line ("' is not a letter
.");
1026 elsif Last_Underscore
1027 and then (The_Name (Index) = '_' or else The_Name (Index) = '.')
1029 -- Two underscores are illegal, and a dot cannot follow
1034 if Current_Verbosity = High then
1035 Write_Int (Types.Int (Index));
1037 Write_Char (The_Name (Index));
1038 Write_Line ("' is illegal here
.");
1043 elsif The_Name (Index) = '.' then
1045 -- First, check if the name before the dot is not a reserved word
1046 if Is_Reserved (The_Name (First .. Index - 1)) then
1052 -- We need a letter after a dot
1054 Need_Letter := True;
1056 elsif The_Name (Index) = '_' then
1057 Last_Underscore := True;
1060 -- We need an letter or a digit
1062 Last_Underscore := False;
1064 if not Is_Alphanumeric (The_Name (Index)) then
1067 if Current_Verbosity = High then
1068 Write_Int (Types.Int (Index));
1070 Write_Char (The_Name (Index));
1071 Write_Line ("' is not alphanumeric
.");
1079 -- Cannot end with an underscore or a dot
1081 OK := OK and then not Need_Letter and then not Last_Underscore;
1084 if First /= Name'First and then
1085 Is_Reserved (The_Name (First .. The_Name'Last))
1093 -- Signal a problem with No_Name
1099 --------------------------------------
1100 -- Check_Ada_Naming_Scheme_Validity --
1101 --------------------------------------
1103 procedure Check_Ada_Naming_Scheme_Validity
1104 (Project : Project_Id;
1105 In_Tree : Project_Tree_Ref;
1106 Naming : Naming_Data)
1109 -- Only check if we are not using the Default naming scheme
1111 if Naming /= In_Tree.Private_Part.Default_Naming then
1113 Dot_Replacement : constant String :=
1115 (Naming.Dot_Replacement);
1117 Spec_Suffix : constant String :=
1118 Spec_Suffix_Of (In_Tree, "ada
", Naming);
1120 Body_Suffix : constant String :=
1121 Body_Suffix_Of (In_Tree, "ada
", Naming);
1123 Separate_Suffix : constant String :=
1125 (Naming.Separate_Suffix);
1128 -- Dot_Replacement cannot
1131 -- - start or end with an alphanumeric
1132 -- - be a single '_'
1133 -- - start with an '_' followed by an alphanumeric
1134 -- - contain a '.' except if it is "."
1136 if Dot_Replacement'Length = 0
1137 or else Is_Alphanumeric
1138 (Dot_Replacement (Dot_Replacement'First))
1139 or else Is_Alphanumeric
1140 (Dot_Replacement (Dot_Replacement'Last))
1141 or else (Dot_Replacement (Dot_Replacement'First) = '_'
1143 (Dot_Replacement'Length = 1
1146 (Dot_Replacement (Dot_Replacement'First + 1))))
1147 or else (Dot_Replacement'Length > 1
1149 Index (Source => Dot_Replacement,
1150 Pattern => ".") /= 0)
1154 '"' & Dot_Replacement &
1155 """ is illegal for Dot_Replacement.",
1156 Naming.Dot_Repl_Loc);
1162 if Is_Illegal_Suffix
1163 (Spec_Suffix, Dot_Replacement = ".")
1165 Err_Vars.Error_Msg_File_1 :=
1166 Spec_Suffix_Id_Of (In_Tree, Name_Ada, Naming);
1169 "{ is illegal for Spec_Suffix",
1170 Naming.Ada_Spec_Suffix_Loc);
1173 if Is_Illegal_Suffix
1174 (Body_Suffix, Dot_Replacement = ".")
1176 Err_Vars.Error_Msg_File_1 :=
1177 Body_Suffix_Id_Of (In_Tree, Name_Ada, Naming);
1180 "{ is illegal for Body_Suffix",
1181 Naming.Ada_Body_Suffix_Loc);
1184 if Body_Suffix /= Separate_Suffix then
1185 if Is_Illegal_Suffix
1186 (Separate_Suffix, Dot_Replacement = ".")
1188 Err_Vars.Error_Msg_File_1 := Naming.Separate_Suffix;
1191 "{ is illegal for Separate_Suffix",
1192 Naming.Sep_Suffix_Loc);
1196 -- Spec_Suffix cannot be equal to Body_Suffix Separate_Suffix,
1197 -- since that would cause a clear ambiguity. Note that we do
1198 -- allow a Spec_Suffix to have the same termination as one of
1199 -- these, which causes a potential ambiguity, but we resolve
1200 -- that my matching the longest possible suffix.
1202 if Spec_Suffix = Body_Suffix then
1207 """) cannot be the same as Spec_Suffix.",
1208 Naming.Ada_Body_Suffix_Loc);
1211 if Body_Suffix /= Separate_Suffix
1212 and then Spec_Suffix = Separate_Suffix
1216 "Separate_Suffix (""" &
1218 """) cannot be the same as Spec_Suffix.",
1219 Naming.Sep_Suffix_Loc);
1223 end Check_Ada_Naming_Scheme_Validity;
1225 -------------------------
1226 -- Check_Configuration --
1227 -------------------------
1229 procedure Check_Configuration
1230 (Project : Project_Id;
1231 In_Tree : Project_Tree_Ref;
1232 Data : in out Project_Data)
1234 Dot_Replacement : File_Name_Type := No_File;
1235 Casing : Casing_Type := All_Lower_Case;
1236 Separate_Suffix : File_Name_Type := No_File;
1238 Lang_Index : Language_Index := No_Language_Index;
1239 -- The index of the language data being checked
1241 Prev_Index : Language_Index := No_Language_Index;
1242 -- The index of the previous language
1244 Current_Language : Name_Id := No_Name;
1245 -- The name of the language
1247 Lang_Data : Language_Data;
1248 -- The data of the language being checked
1250 procedure Get_Language_Index_Of (Language : Name_Id);
1251 -- Get the language index of Language, if Language is one of the
1252 -- languages of the project.
1254 procedure Process_Project_Level_Simple_Attributes;
1255 -- Process the simple attributes at the project level
1257 procedure Process_Project_Level_Array_Attributes;
1258 -- Process the associate array attributes at the project level
1260 procedure Process_Packages;
1261 -- Read the packages of the project
1263 ---------------------------
1264 -- Get_Language_Index_Of --
1265 ---------------------------
1267 procedure Get_Language_Index_Of (Language : Name_Id) is
1268 Real_Language : Name_Id;
1271 Get_Name_String (Language);
1272 To_Lower (Name_Buffer (1 .. Name_Len));
1273 Real_Language := Name_Find;
1275 -- Nothing to do if the language is the same as the current language
1277 if Current_Language /= Real_Language then
1278 Lang_Index := Data.First_Language_Processing;
1279 while Lang_Index /= No_Language_Index loop
1280 exit when In_Tree.Languages_Data.Table (Lang_Index).Name =
1283 In_Tree.Languages_Data.Table (Lang_Index).Next;
1286 if Lang_Index = No_Language_Index then
1287 Current_Language := No_Name;
1289 Current_Language := Real_Language;
1292 end Get_Language_Index_Of;
1294 ----------------------
1295 -- Process_Packages --
1296 ----------------------
1298 procedure Process_Packages is
1299 Packages : Package_Id;
1300 Element : Package_Element;
1302 procedure Process_Binder (Arrays : Array_Id);
1303 -- Process the associate array attributes of package Binder
1305 procedure Process_Builder (Attributes : Variable_Id);
1306 -- Process the simple attributes of package Builder
1308 procedure Process_Compiler (Arrays : Array_Id);
1309 -- Process the associate array attributes of package Compiler
1311 procedure Process_Naming (Attributes : Variable_Id);
1312 -- Process the simple attributes of package Naming
1314 procedure Process_Naming (Arrays : Array_Id);
1315 -- Process the associate array attributes of package Naming
1317 procedure Process_Linker (Attributes : Variable_Id);
1318 -- Process the simple attributes of package Linker of a
1319 -- configuration project.
1321 --------------------
1322 -- Process_Binder --
1323 --------------------
1325 procedure Process_Binder (Arrays : Array_Id) is
1326 Current_Array_Id : Array_Id;
1327 Current_Array : Array_Data;
1328 Element_Id : Array_Element_Id;
1329 Element : Array_Element;
1332 -- Process the associative array attribute of package Binder
1334 Current_Array_Id := Arrays;
1335 while Current_Array_Id /= No_Array loop
1336 Current_Array := In_Tree.Arrays.Table (Current_Array_Id);
1338 Element_Id := Current_Array.Value;
1339 while Element_Id /= No_Array_Element loop
1340 Element := In_Tree.Array_Elements.Table (Element_Id);
1342 -- Get the name of the language
1344 Get_Language_Index_Of (Element.Index);
1346 if Lang_Index /= No_Language_Index then
1347 case Current_Array.Name is
1350 -- Attribute Driver (<language>)
1352 In_Tree.Languages_Data.Table
1353 (Lang_Index).Config.Binder_Driver :=
1354 File_Name_Type (Element.Value.Value);
1356 when Name_Required_Switches =>
1358 In_Tree.Languages_Data.Table
1359 (Lang_Index).Config.Binder_Required_Switches,
1360 From_List => Element.Value.Values,
1361 In_Tree => In_Tree);
1365 -- Attribute Prefix (<language>)
1367 In_Tree.Languages_Data.Table
1368 (Lang_Index).Config.Binder_Prefix :=
1369 Element.Value.Value;
1371 when Name_Objects_Path =>
1373 -- Attribute Objects_Path (<language>)
1375 In_Tree.Languages_Data.Table
1376 (Lang_Index).Config.Objects_Path :=
1377 Element.Value.Value;
1379 when Name_Objects_Path_File =>
1381 -- Attribute Objects_Path (<language>)
1383 In_Tree.Languages_Data.Table
1384 (Lang_Index).Config.Objects_Path_File :=
1385 Element.Value.Value;
1392 Element_Id := Element.Next;
1395 Current_Array_Id := Current_Array.Next;
1399 ---------------------
1400 -- Process_Builder --
1401 ---------------------
1403 procedure Process_Builder (Attributes : Variable_Id) is
1404 Attribute_Id : Variable_Id;
1405 Attribute : Variable;
1408 -- Process non associated array attribute from package Builder
1410 Attribute_Id := Attributes;
1411 while Attribute_Id /= No_Variable loop
1413 In_Tree.Variable_Elements.Table (Attribute_Id);
1415 if not Attribute.Value.Default then
1416 if Attribute.Name = Name_Executable_Suffix then
1418 -- Attribute Executable_Suffix: the suffix of the
1421 Data.Config.Executable_Suffix :=
1422 Attribute.Value.Value;
1426 Attribute_Id := Attribute.Next;
1428 end Process_Builder;
1430 ----------------------
1431 -- Process_Compiler --
1432 ----------------------
1434 procedure Process_Compiler (Arrays : Array_Id) is
1435 Current_Array_Id : Array_Id;
1436 Current_Array : Array_Data;
1437 Element_Id : Array_Element_Id;
1438 Element : Array_Element;
1439 List : String_List_Id;
1442 -- Process the associative array attribute of package Compiler
1444 Current_Array_Id := Arrays;
1445 while Current_Array_Id /= No_Array loop
1446 Current_Array := In_Tree.Arrays.Table (Current_Array_Id);
1448 Element_Id := Current_Array.Value;
1449 while Element_Id /= No_Array_Element loop
1450 Element := In_Tree.Array_Elements.Table (Element_Id);
1452 -- Get the name of the language
1454 Get_Language_Index_Of (Element.Index);
1456 if Lang_Index /= No_Language_Index then
1457 case Current_Array.Name is
1458 when Name_Dependency_Switches =>
1460 -- Attribute Dependency_Switches (<language>)
1462 if In_Tree.Languages_Data.Table
1463 (Lang_Index).Config.Dependency_Kind = None
1465 In_Tree.Languages_Data.Table
1466 (Lang_Index).Config.Dependency_Kind :=
1470 List := Element.Value.Values;
1472 if List /= Nil_String then
1474 In_Tree.Languages_Data.Table
1475 (Lang_Index).Config.Dependency_Option,
1477 In_Tree => In_Tree);
1480 when Name_Dependency_Driver =>
1482 -- Attribute Dependency_Driver (<language>)
1484 if In_Tree.Languages_Data.Table
1485 (Lang_Index).Config.Dependency_Kind = None
1487 In_Tree.Languages_Data.Table
1488 (Lang_Index).Config.Dependency_Kind :=
1492 List := Element.Value.Values;
1494 if List /= Nil_String then
1496 In_Tree.Languages_Data.Table
1497 (Lang_Index).Config.Compute_Dependency,
1499 In_Tree => In_Tree);
1502 when Name_Include_Switches =>
1504 -- Attribute Include_Switches (<language>)
1506 List := Element.Value.Values;
1508 if List = Nil_String then
1512 "include option cannot be null",
1513 Element.Value.Location);
1517 In_Tree.Languages_Data.Table
1518 (Lang_Index).Config.Include_Option,
1520 In_Tree => In_Tree);
1522 when Name_Include_Path =>
1524 -- Attribute Include_Path (<language>)
1526 In_Tree.Languages_Data.Table
1527 (Lang_Index).Config.Include_Path :=
1528 Element.Value.Value;
1530 when Name_Include_Path_File =>
1532 -- Attribute Include_Path_File (<language>)
1534 In_Tree.Languages_Data.Table
1535 (Lang_Index).Config.Include_Path_File :=
1536 Element.Value.Value;
1540 -- Attribute Driver (<language>)
1542 Get_Name_String (Element.Value.Value);
1544 In_Tree.Languages_Data.Table
1545 (Lang_Index).Config.Compiler_Driver :=
1546 File_Name_Type (Element.Value.Value);
1548 when Name_Required_Switches =>
1550 In_Tree.Languages_Data.Table
1551 (Lang_Index).Config.
1552 Compiler_Required_Switches,
1553 From_List => Element.Value.Values,
1554 In_Tree => In_Tree);
1556 when Name_Pic_Option =>
1558 -- Attribute Compiler_Pic_Option (<language>)
1560 List := Element.Value.Values;
1562 if List = Nil_String then
1566 "compiler PIC option cannot be null",
1567 Element.Value.Location);
1571 In_Tree.Languages_Data.Table
1572 (Lang_Index).Config.Compilation_PIC_Option,
1574 In_Tree => In_Tree);
1576 when Name_Mapping_File_Switches =>
1578 -- Attribute Mapping_File_Switches (<language>)
1580 List := Element.Value.Values;
1582 if List = Nil_String then
1586 "mapping file switches cannot be null",
1587 Element.Value.Location);
1591 In_Tree.Languages_Data.Table
1592 (Lang_Index).Config.Mapping_File_Switches,
1594 In_Tree => In_Tree);
1596 when Name_Mapping_Spec_Suffix =>
1598 -- Attribute Mapping_Spec_Suffix (<language>)
1600 In_Tree.Languages_Data.Table
1601 (Lang_Index).Config.Mapping_Spec_Suffix :=
1602 File_Name_Type (Element.Value.Value);
1604 when Name_Mapping_Body_Suffix =>
1606 -- Attribute Mapping_Body_Suffix (<language>)
1608 In_Tree.Languages_Data.Table
1609 (Lang_Index).Config.Mapping_Body_Suffix :=
1610 File_Name_Type (Element.Value.Value);
1612 when Name_Config_File_Switches =>
1614 -- Attribute Config_File_Switches (<language>)
1616 List := Element.Value.Values;
1618 if List = Nil_String then
1622 "config file switches cannot be null",
1623 Element.Value.Location);
1627 In_Tree.Languages_Data.Table
1628 (Lang_Index).Config.Config_File_Switches,
1630 In_Tree => In_Tree);
1632 when Name_Objects_Path =>
1634 -- Attribute Objects_Path (<language>)
1636 In_Tree.Languages_Data.Table
1637 (Lang_Index).Config.Objects_Path :=
1638 Element.Value.Value;
1640 when Name_Objects_Path_File =>
1642 -- Attribute Objects_Path_File (<language>)
1644 In_Tree.Languages_Data.Table
1645 (Lang_Index).Config.Objects_Path_File :=
1646 Element.Value.Value;
1648 when Name_Config_Body_File_Name =>
1650 -- Attribute Config_Body_File_Name (<language>)
1652 In_Tree.Languages_Data.Table
1653 (Lang_Index).Config.Config_Body :=
1654 Element.Value.Value;
1656 when Name_Config_Body_File_Name_Pattern =>
1658 -- Attribute Config_Body_File_Name_Pattern
1661 In_Tree.Languages_Data.Table
1662 (Lang_Index).Config.Config_Body_Pattern :=
1663 Element.Value.Value;
1665 when Name_Config_Spec_File_Name =>
1667 -- Attribute Config_Spec_File_Name (<language>)
1669 In_Tree.Languages_Data.Table
1670 (Lang_Index).Config.Config_Spec :=
1671 Element.Value.Value;
1673 when Name_Config_Spec_File_Name_Pattern =>
1675 -- Attribute Config_Spec_File_Name_Pattern
1678 In_Tree.Languages_Data.Table
1679 (Lang_Index).Config.Config_Spec_Pattern :=
1680 Element.Value.Value;
1682 when Name_Config_File_Unique =>
1684 -- Attribute Config_File_Unique (<language>)
1687 In_Tree.Languages_Data.Table
1688 (Lang_Index).Config.Config_File_Unique :=
1690 (Get_Name_String (Element.Value.Value));
1692 when Constraint_Error =>
1696 "illegal value for Config_File_Unique",
1697 Element.Value.Location);
1705 Element_Id := Element.Next;
1708 Current_Array_Id := Current_Array.Next;
1710 end Process_Compiler;
1712 --------------------
1713 -- Process_Naming --
1714 --------------------
1716 procedure Process_Naming (Attributes : Variable_Id) is
1717 Attribute_Id : Variable_Id;
1718 Attribute : Variable;
1721 -- Process non associated array attribute from package Naming
1723 Attribute_Id := Attributes;
1724 while Attribute_Id /= No_Variable loop
1726 In_Tree.Variable_Elements.Table (Attribute_Id);
1728 if not Attribute.Value.Default then
1729 if Attribute.Name = Name_Separate_Suffix then
1731 -- Attribute Separate_Suffix
1733 Separate_Suffix := File_Name_Type (Attribute.Value.Value);
1735 elsif Attribute.Name = Name_Casing then
1741 Value (Get_Name_String (Attribute.Value.Value));
1744 when Constraint_Error =>
1748 "invalid value for Casing",
1749 Attribute.Value.Location);
1752 elsif Attribute.Name = Name_Dot_Replacement then
1754 -- Attribute Dot_Replacement
1756 Dot_Replacement := File_Name_Type (Attribute.Value.Value);
1761 Attribute_Id := Attribute.Next;
1765 procedure Process_Naming (Arrays : Array_Id) is
1766 Current_Array_Id : Array_Id;
1767 Current_Array : Array_Data;
1768 Element_Id : Array_Element_Id;
1769 Element : Array_Element;
1771 -- Process the associative array attribute of package Naming
1773 Current_Array_Id := Arrays;
1774 while Current_Array_Id /= No_Array loop
1775 Current_Array := In_Tree.Arrays.Table (Current_Array_Id);
1777 Element_Id := Current_Array.Value;
1778 while Element_Id /= No_Array_Element loop
1779 Element := In_Tree.Array_Elements.Table (Element_Id);
1781 -- Get the name of the language
1783 Get_Language_Index_Of (Element.Index);
1785 if Lang_Index /= No_Language_Index then
1786 case Current_Array.Name is
1787 when Name_Specification_Suffix | Name_Spec_Suffix =>
1789 -- Attribute Spec_Suffix (<language>)
1791 In_Tree.Languages_Data.Table
1792 (Lang_Index).Config.Naming_Data.Spec_Suffix :=
1793 File_Name_Type (Element.Value.Value);
1795 when Name_Implementation_Suffix | Name_Body_Suffix =>
1797 -- Attribute Body_Suffix (<language>)
1799 In_Tree.Languages_Data.Table
1800 (Lang_Index).Config.Naming_Data.Body_Suffix :=
1801 File_Name_Type (Element.Value.Value);
1803 In_Tree.Languages_Data.Table
1804 (Lang_Index).Config.Naming_Data.Separate_Suffix :=
1805 File_Name_Type (Element.Value.Value);
1812 Element_Id := Element.Next;
1815 Current_Array_Id := Current_Array.Next;
1819 --------------------
1820 -- Process_Linker --
1821 --------------------
1823 procedure Process_Linker (Attributes : Variable_Id) is
1824 Attribute_Id : Variable_Id;
1825 Attribute : Variable;
1828 -- Process non associated array attribute from package Linker
1830 Attribute_Id := Attributes;
1831 while Attribute_Id /= No_Variable loop
1833 In_Tree.Variable_Elements.Table (Attribute_Id);
1835 if not Attribute.Value.Default then
1836 if Attribute.Name = Name_Driver then
1838 -- Attribute Linker'Driver: the default linker to use
1840 Data.Config.Linker :=
1841 Path_Name_Type (Attribute.Value.Value);
1843 elsif Attribute.Name = Name_Required_Switches then
1845 -- Attribute Required_Switches: the minimum
1846 -- options to use when invoking the linker
1849 Data.Config.Minimum_Linker_Options,
1850 From_List => Attribute.Value.Values,
1851 In_Tree => In_Tree);
1853 elsif Attribute.Name = Name_Map_File_Option then
1854 Data.Config.Map_File_Option := Attribute.Value.Value;
1858 Attribute_Id := Attribute.Next;
1862 -- Start of processing for Process_Packages
1865 Packages := Data.Decl.Packages;
1866 while Packages /= No_Package loop
1867 Element := In_Tree.Packages.Table (Packages);
1869 case Element.Name is
1872 -- Process attributes of package Binder
1874 Process_Binder (Element.Decl.Arrays);
1876 when Name_Builder =>
1878 -- Process attributes of package Builder
1880 Process_Builder (Element.Decl.Attributes);
1882 when Name_Compiler =>
1884 -- Process attributes of package Compiler
1886 Process_Compiler (Element.Decl.Arrays);
1890 -- Process attributes of package Linker
1892 Process_Linker (Element.Decl.Attributes);
1896 -- Process attributes of package Naming
1898 Process_Naming (Element.Decl.Attributes);
1899 Process_Naming (Element.Decl.Arrays);
1905 Packages := Element.Next;
1907 end Process_Packages;
1909 ---------------------------------------------
1910 -- Process_Project_Level_Simple_Attributes --
1911 ---------------------------------------------
1913 procedure Process_Project_Level_Simple_Attributes is
1914 Attribute_Id : Variable_Id;
1915 Attribute : Variable;
1916 List : String_List_Id;
1919 -- Process non associated array attribute at project level
1921 Attribute_Id := Data.Decl.Attributes;
1922 while Attribute_Id /= No_Variable loop
1924 In_Tree.Variable_Elements.Table (Attribute_Id);
1926 if not Attribute.Value.Default then
1927 if Attribute.Name = Name_Library_Builder then
1929 -- Attribute Library_Builder: the application to invoke
1930 -- to build libraries.
1932 Data.Config.Library_Builder :=
1933 Path_Name_Type (Attribute.Value.Value);
1935 elsif Attribute.Name = Name_Archive_Builder then
1937 -- Attribute Archive_Builder: the archive builder
1938 -- (usually "ar") and its minimum options (usually "cr").
1940 List := Attribute.Value.Values;
1942 if List = Nil_String then
1946 "archive builder cannot be null",
1947 Attribute.Value.Location);
1950 Put (Into_List => Data.Config.Archive_Builder,
1952 In_Tree => In_Tree);
1954 elsif Attribute.Name = Name_Archive_Builder_Append_Option then
1956 -- Attribute Archive_Builder: the archive builder
1957 -- (usually "ar") and its minimum options (usually "cr").
1959 List := Attribute.Value.Values;
1961 if List /= Nil_String then
1963 (Into_List => Data.Config.Archive_Builder_Append_Option,
1965 In_Tree => In_Tree);
1968 elsif Attribute.Name = Name_Archive_Indexer then
1970 -- Attribute Archive_Indexer: the optional archive
1971 -- indexer (usually "ranlib") with its minimum options
1974 List := Attribute.Value.Values;
1976 if List = Nil_String then
1980 "archive indexer cannot be null",
1981 Attribute.Value.Location);
1984 Put (Into_List => Data.Config.Archive_Indexer,
1986 In_Tree => In_Tree);
1988 elsif Attribute.Name = Name_Library_Partial_Linker then
1990 -- Attribute Library_Partial_Linker: the optional linker
1991 -- driver with its minimum options, to partially link
1994 List := Attribute.Value.Values;
1996 if List = Nil_String then
2000 "partial linker cannot be null",
2001 Attribute.Value.Location);
2004 Put (Into_List => Data.Config.Lib_Partial_Linker,
2006 In_Tree => In_Tree);
2008 elsif Attribute.Name = Name_Library_GCC then
2009 Data.Config.Shared_Lib_Driver :=
2010 File_Name_Type (Attribute.Value.Value);
2012 elsif Attribute.Name = Name_Archive_Suffix then
2013 Data.Config.Archive_Suffix :=
2014 File_Name_Type (Attribute.Value.Value);
2016 elsif Attribute.Name = Name_Linker_Executable_Option then
2018 -- Attribute Linker_Executable_Option: optional options
2019 -- to specify an executable name. Defaults to "-o".
2021 List := Attribute.Value.Values;
2023 if List = Nil_String then
2027 "linker executable option cannot be null",
2028 Attribute.Value.Location);
2031 Put (Into_List => Data.Config.Linker_Executable_Option,
2033 In_Tree => In_Tree);
2035 elsif Attribute.Name = Name_Linker_Lib_Dir_Option then
2037 -- Attribute Linker_Lib_Dir_Option: optional options
2038 -- to specify a library search directory. Defaults to
2041 Get_Name_String (Attribute.Value.Value);
2043 if Name_Len = 0 then
2047 "linker library directory option cannot be empty",
2048 Attribute.Value.Location);
2051 Data.Config.Linker_Lib_Dir_Option := Attribute.Value.Value;
2053 elsif Attribute.Name = Name_Linker_Lib_Name_Option then
2055 -- Attribute Linker_Lib_Name_Option: optional options
2056 -- to specify the name of a library to be linked in.
2057 -- Defaults to "-l".
2059 Get_Name_String (Attribute.Value.Value);
2061 if Name_Len = 0 then
2065 "linker library name option cannot be empty",
2066 Attribute.Value.Location);
2069 Data.Config.Linker_Lib_Name_Option := Attribute.Value.Value;
2071 elsif Attribute.Name = Name_Run_Path_Option then
2073 -- Attribute Run_Path_Option: optional options to
2074 -- specify a path for libraries.
2076 List := Attribute.Value.Values;
2078 if List /= Nil_String then
2079 Put (Into_List => Data.Config.Run_Path_Option,
2081 In_Tree => In_Tree);
2084 elsif Attribute.Name = Name_Library_Support then
2086 pragma Unsuppress (All_Checks);
2088 Data.Config.Lib_Support :=
2089 Library_Support'Value (Get_Name_String
2090 (Attribute.Value.Value));
2092 when Constraint_Error =>
2096 "invalid value """ &
2097 Get_Name_String (Attribute.Value.Value) &
2098 """ for Library_Support",
2099 Attribute.Value.Location);
2102 elsif Attribute.Name = Name_Shared_Library_Prefix then
2103 Data.Config.Shared_Lib_Prefix :=
2104 File_Name_Type (Attribute.Value.Value);
2106 elsif Attribute.Name = Name_Shared_Library_Suffix then
2107 Data.Config.Shared_Lib_Suffix :=
2108 File_Name_Type (Attribute.Value.Value);
2110 elsif Attribute.Name = Name_Symbolic_Link_Supported then
2112 pragma Unsuppress (All_Checks);
2114 Data.Config.Symbolic_Link_Supported :=
2115 Boolean'Value (Get_Name_String
2116 (Attribute.Value.Value));
2118 when Constraint_Error =>
2123 & Get_Name_String (Attribute.Value.Value)
2124 & """ for Symbolic_Link_Supported",
2125 Attribute.Value.Location);
2129 Attribute.Name = Name_Library_Major_Minor_Id_Supported
2132 pragma Unsuppress (All_Checks);
2134 Data.Config.Lib_Maj_Min_Id_Supported :=
2135 Boolean'Value (Get_Name_String
2136 (Attribute.Value.Value));
2138 when Constraint_Error =>
2142 "invalid value """ &
2143 Get_Name_String (Attribute.Value.Value) &
2144 """ for Library_Major_Minor_Id_Supported",
2145 Attribute.Value.Location);
2148 elsif Attribute.Name = Name_Library_Auto_Init_Supported then
2150 pragma Unsuppress (All_Checks);
2152 Data.Config.Auto_Init_Supported :=
2153 Boolean'Value (Get_Name_String (Attribute.Value.Value));
2155 when Constraint_Error =>
2160 & Get_Name_String (Attribute.Value.Value)
2161 & """ for Library_Auto_Init_Supported",
2162 Attribute.Value.Location);
2165 elsif Attribute.Name = Name_Shared_Library_Minimum_Switches then
2166 List := Attribute.Value.Values;
2168 if List /= Nil_String then
2169 Put (Into_List => Data.Config.Shared_Lib_Min_Options,
2171 In_Tree => In_Tree);
2174 elsif Attribute.Name = Name_Library_Version_Switches then
2175 List := Attribute.Value.Values;
2177 if List /= Nil_String then
2178 Put (Into_List => Data.Config.Lib_Version_Options,
2180 In_Tree => In_Tree);
2185 Attribute_Id := Attribute.Next;
2187 end Process_Project_Level_Simple_Attributes;
2189 --------------------------------------------
2190 -- Process_Project_Level_Array_Attributes --
2191 --------------------------------------------
2193 procedure Process_Project_Level_Array_Attributes is
2194 Current_Array_Id : Array_Id;
2195 Current_Array : Array_Data;
2196 Element_Id : Array_Element_Id;
2197 Element : Array_Element;
2198 List : String_List_Id;
2201 -- Process the associative array attributes at project level
2203 Current_Array_Id := Data.Decl.Arrays;
2204 while Current_Array_Id /= No_Array loop
2205 Current_Array := In_Tree.Arrays.Table (Current_Array_Id);
2207 Element_Id := Current_Array.Value;
2208 while Element_Id /= No_Array_Element loop
2209 Element := In_Tree.Array_Elements.Table (Element_Id);
2211 -- Get the name of the language
2213 Get_Language_Index_Of (Element.Index);
2215 if Lang_Index /= No_Language_Index then
2216 case Current_Array.Name is
2217 when Name_Inherit_Source_Path =>
2218 List := Element.Value.Values;
2220 if List /= Nil_String then
2223 In_Tree.Languages_Data.Table (Lang_Index).
2224 Config.Include_Compatible_Languages,
2227 Lower_Case => True);
2230 when Name_Toolchain_Description =>
2232 -- Attribute Toolchain_Description (<language>)
2234 In_Tree.Languages_Data.Table
2235 (Lang_Index).Config.Toolchain_Description :=
2236 Element.Value.Value;
2238 when Name_Toolchain_Version =>
2240 -- Attribute Toolchain_Version (<language>)
2242 In_Tree.Languages_Data.Table
2243 (Lang_Index).Config.Toolchain_Version :=
2244 Element.Value.Value;
2246 when Name_Runtime_Library_Dir =>
2248 -- Attribute Runtime_Library_Dir (<language>)
2250 In_Tree.Languages_Data.Table
2251 (Lang_Index).Config.Runtime_Library_Dir :=
2252 Element.Value.Value;
2254 when Name_Object_Generated =>
2256 pragma Unsuppress (All_Checks);
2262 (Get_Name_String (Element.Value.Value));
2264 In_Tree.Languages_Data.Table
2265 (Lang_Index).Config.Object_Generated := Value;
2267 -- If no object is generated, no object may be
2271 In_Tree.Languages_Data.Table
2272 (Lang_Index).Config.Objects_Linked := False;
2276 when Constraint_Error =>
2281 & Get_Name_String (Element.Value.Value)
2282 & """ for Object_Generated",
2283 Element.Value.Location);
2286 when Name_Objects_Linked =>
2288 pragma Unsuppress (All_Checks);
2294 (Get_Name_String (Element.Value.Value));
2296 -- No change if Object_Generated is False, as this
2297 -- forces Objects_Linked to be False too.
2299 if In_Tree.Languages_Data.Table
2300 (Lang_Index).Config.Object_Generated
2302 In_Tree.Languages_Data.Table
2303 (Lang_Index).Config.Objects_Linked :=
2308 when Constraint_Error =>
2313 & Get_Name_String (Element.Value.Value)
2314 & """ for Objects_Linked",
2315 Element.Value.Location);
2322 Element_Id := Element.Next;
2325 Current_Array_Id := Current_Array.Next;
2327 end Process_Project_Level_Array_Attributes;
2330 Process_Project_Level_Simple_Attributes;
2331 Process_Project_Level_Array_Attributes;
2334 -- For unit based languages, set Casing, Dot_Replacement and
2335 -- Separate_Suffix in Naming_Data.
2337 Lang_Index := Data.First_Language_Processing;
2338 while Lang_Index /= No_Language_Index loop
2339 if In_Tree.Languages_Data.Table
2340 (Lang_Index).Name = Name_Ada
2342 In_Tree.Languages_Data.Table
2343 (Lang_Index).Config.Naming_Data.Casing := Casing;
2344 In_Tree.Languages_Data.Table
2345 (Lang_Index).Config.Naming_Data.Dot_Replacement :=
2348 if Separate_Suffix /= No_File then
2349 In_Tree.Languages_Data.Table
2350 (Lang_Index).Config.Naming_Data.Separate_Suffix :=
2357 Lang_Index := In_Tree.Languages_Data.Table (Lang_Index).Next;
2360 -- Give empty names to various prefixes/suffixes, if they have not
2361 -- been specified in the configuration.
2363 if Data.Config.Archive_Suffix = No_File then
2364 Data.Config.Archive_Suffix := Empty_File;
2367 if Data.Config.Shared_Lib_Prefix = No_File then
2368 Data.Config.Shared_Lib_Prefix := Empty_File;
2371 if Data.Config.Shared_Lib_Suffix = No_File then
2372 Data.Config.Shared_Lib_Suffix := Empty_File;
2375 Lang_Index := Data.First_Language_Processing;
2376 while Lang_Index /= No_Language_Index loop
2377 Lang_Data := In_Tree.Languages_Data.Table (Lang_Index);
2379 Current_Language := Lang_Data.Display_Name;
2381 -- For all languages, Compiler_Driver needs to be specified
2383 if Lang_Data.Config.Compiler_Driver = No_File then
2384 Error_Msg_Name_1 := Current_Language;
2388 "?no compiler specified for language %%" &
2389 ", ignoring all its sources",
2392 if Lang_Index = Data.First_Language_Processing then
2393 Data.First_Language_Processing :=
2396 In_Tree.Languages_Data.Table (Prev_Index).Next :=
2400 elsif Lang_Data.Name = Name_Ada then
2401 Prev_Index := Lang_Index;
2403 -- For unit based languages, Dot_Replacement, Spec_Suffix and
2404 -- Body_Suffix need to be specified.
2406 if Lang_Data.Config.Naming_Data.Dot_Replacement = No_File then
2410 "Dot_Replacement not specified for Ada",
2414 if Lang_Data.Config.Naming_Data.Spec_Suffix = No_File then
2418 "Spec_Suffix not specified for Ada",
2422 if Lang_Data.Config.Naming_Data.Body_Suffix = No_File then
2426 "Body_Suffix not specified for Ada",
2431 Prev_Index := Lang_Index;
2433 -- For file based languages, either Spec_Suffix or Body_Suffix
2434 -- need to be specified.
2436 if Lang_Data.Config.Naming_Data.Spec_Suffix = No_File and then
2437 Lang_Data.Config.Naming_Data.Body_Suffix = No_File
2439 Error_Msg_Name_1 := Current_Language;
2443 "no suffixes specified for %%",
2448 Lang_Index := Lang_Data.Next;
2450 end Check_Configuration;
2452 ----------------------
2453 -- Check_For_Source --
2454 ----------------------
2456 procedure Check_For_Source
2457 (File_Name : File_Name_Type;
2458 Path_Name : Path_Name_Type;
2459 Project : Project_Id;
2460 In_Tree : Project_Tree_Ref;
2461 Data : in out Project_Data;
2462 Location : Source_Ptr;
2463 Language : Language_Index;
2465 Naming_Exception : Boolean)
2467 Name : String := Get_Name_String (File_Name);
2468 Real_Location : Source_Ptr := Location;
2471 Canonical_Case_File_Name (Name);
2473 -- A file is a source of a language if Naming_Exception is True (case
2474 -- of naming exceptions) or if its file name ends with the suffix.
2478 (Name'Length > Suffix'Length
2480 Name (Name'Last - Suffix'Length + 1 .. Name'Last) = Suffix)
2482 if Real_Location = No_Location then
2483 Real_Location := Data.Location;
2487 Path_Id : Path_Name_Type;
2488 C_Path_Id : Path_Name_Type;
2489 -- The path name id (in canonical case)
2491 File_Id : File_Name_Type;
2492 -- The file name id (in canonical case)
2494 Obj_Id : File_Name_Type;
2495 -- The object file name
2497 Obj_Path_Id : Path_Name_Type;
2498 -- The object path name
2500 Dep_Id : File_Name_Type;
2501 -- The dependency file name
2503 Dep_Path_Id : Path_Name_Type;
2504 -- The dependency path name
2506 Dot_Pos : Natural := 0;
2507 -- Position of the last dot in Name
2509 Source : Other_Source;
2510 Source_Id : Other_Source_Id := Data.First_Other_Source;
2513 -- Get the file name id
2515 if Osint.File_Names_Case_Sensitive then
2516 File_Id := File_Name;
2518 Name_Len := Name'Length;
2519 Name_Buffer (1 .. Name_Len) := Name;
2520 File_Id := Name_Find;
2523 -- Get the path name id
2525 Path_Id := Path_Name;
2527 if Osint.File_Names_Case_Sensitive then
2528 C_Path_Id := Path_Name;
2531 C_Path : String := Get_Name_String (Path_Name);
2533 Canonical_Case_File_Name (C_Path);
2534 Name_Len := C_Path'Length;
2535 Name_Buffer (1 .. Name_Len) := C_Path;
2536 C_Path_Id := Name_Find;
2540 -- Find the position of the last dot
2542 for J in reverse Name'Range loop
2543 if Name (J) = '.' then
2549 if Dot_Pos <= Name'First then
2550 Dot_Pos := Name'Last + 1;
2553 -- Compute the object file name
2555 Get_Name_String (File_Id);
2556 Name_Len := Dot_Pos - Name'First;
2558 for J in Object_Suffix'Range loop
2559 Name_Len := Name_Len + 1;
2560 Name_Buffer (Name_Len) := Object_Suffix (J);
2563 Obj_Id := Name_Find;
2565 -- Compute the object path name
2567 Get_Name_String (Data.Object_Directory.Display_Name);
2569 if Name_Buffer (Name_Len) /= Directory_Separator
2570 and then Name_Buffer (Name_Len) /= '/'
2572 Name_Len := Name_Len + 1;
2573 Name_Buffer (Name_Len) := Directory_Separator;
2576 Add_Str_To_Name_Buffer (Get_Name_String (Obj_Id));
2577 Obj_Path_Id := Name_Find;
2579 -- Compute the dependency file name
2581 Get_Name_String (File_Id);
2582 Name_Len := Dot_Pos - Name'First + 1;
2583 Name_Buffer (Name_Len) := '.';
2584 Name_Len := Name_Len + 1;
2585 Name_Buffer (Name_Len) := 'd
';
2586 Dep_Id := Name_Find;
2588 -- Compute the dependency path name
2590 Get_Name_String (Data.Object_Directory.Display_Name);
2592 if Name_Buffer (Name_Len) /= Directory_Separator
2593 and then Name_Buffer (Name_Len) /= '/'
2595 Name_Len := Name_Len + 1;
2596 Name_Buffer (Name_Len) := Directory_Separator;
2599 Add_Str_To_Name_Buffer (Get_Name_String (Dep_Id));
2600 Dep_Path_Id := Name_Find;
2602 -- Check if source is already in the list of source for this
2603 -- project: it may have already been specified as a naming
2604 -- exception for the same language or an other language, or
2605 -- they may be two identical file names in different source
2608 while Source_Id /= No_Other_Source loop
2609 Source := In_Tree.Other_Sources.Table (Source_Id);
2611 if Source.File_Name = File_Id then
2612 -- Two sources of different languages cannot have the same
2615 if Source.Language /= Language then
2616 Error_Msg_File_1 := File_Name;
2619 "{ cannot be a source of several languages",
2623 -- No problem if a file has already been specified as
2624 -- a naming exception of this language.
2626 elsif Source.Path_Name = C_Path_Id then
2628 -- Reset the naming exception flag, if this is not a
2629 -- naming exception.
2631 if not Naming_Exception then
2632 In_Tree.Other_Sources.Table
2633 (Source_Id).Naming_Exception := False;
2638 -- There are several files with the same names, but the
2639 -- order of the source directories is known (no /**):
2640 -- only the first one encountered is kept, the other ones
2643 elsif Data.Known_Order_Of_Source_Dirs then
2646 -- But it is an error if the order of the source directories
2650 Error_Msg_File_1 := File_Name;
2653 "{ is found in several source directories",
2658 -- Two sources with different file names cannot have the same
2659 -- object file name.
2661 elsif Source.Object_Name = Obj_Id then
2662 Error_Msg_File_1 := File_Id;
2663 Error_Msg_File_2 := Source.File_Name;
2664 Error_Msg_File_3 := Obj_Id;
2667 "{ and { have the same object file {",
2672 Source_Id := Source.Next;
2675 if Current_Verbosity = High then
2676 Write_Str (" found ");
2677 Display_Language_Name (Language);
2678 Write_Str (" source """);
2679 Write_Str (Get_Name_String (File_Name));
2681 Write_Str (" object path = ");
2682 Write_Line (Get_Name_String (Obj_Path_Id));
2685 -- Create the Other_Source record
2688 (Language => Language,
2689 File_Name => File_Id,
2690 Path_Name => Path_Id,
2691 Source_TS => File_Stamp (Path_Id),
2692 Object_Name => Obj_Id,
2693 Object_Path => Obj_Path_Id,
2694 Object_TS => File_Stamp (Obj_Path_Id),
2696 Dep_Path => Dep_Path_Id,
2697 Dep_TS => File_Stamp (Dep_Path_Id),
2698 Naming_Exception => Naming_Exception,
2699 Next => No_Other_Source);
2701 -- And add it to the Other_Sources table
2703 Other_Source_Table.Increment_Last (In_Tree.Other_Sources);
2704 In_Tree.Other_Sources.Table
2705 (Other_Source_Table.Last (In_Tree.Other_Sources)) := Source;
2707 -- There are sources of languages other than Ada in this project
2709 Data.Other_Sources_Present := True;
2711 -- And there are sources of this language in this project
2713 Set (Language, True, Data, In_Tree);
2715 -- Add this source to the list of sources of languages other than
2716 -- Ada of the project.
2718 if Data.First_Other_Source = No_Other_Source then
2719 Data.First_Other_Source :=
2720 Other_Source_Table.Last (In_Tree.Other_Sources);
2723 In_Tree.Other_Sources.Table (Data.Last_Other_Source).Next :=
2724 Other_Source_Table.Last (In_Tree.Other_Sources);
2727 Data.Last_Other_Source :=
2728 Other_Source_Table.Last (In_Tree.Other_Sources);
2731 end Check_For_Source;
2733 -------------------------------
2734 -- Check_If_Externally_Built --
2735 -------------------------------
2737 procedure Check_If_Externally_Built
2738 (Project : Project_Id;
2739 In_Tree : Project_Tree_Ref;
2740 Data : in out Project_Data)
2742 Externally_Built : constant Variable_Value :=
2744 (Name_Externally_Built,
2745 Data.Decl.Attributes, In_Tree);
2748 if not Externally_Built.Default then
2749 Get_Name_String (Externally_Built.Value);
2750 To_Lower (Name_Buffer (1 .. Name_Len));
2752 if Name_Buffer (1 .. Name_Len) = "true" then
2753 Data.Externally_Built := True;
2755 elsif Name_Buffer (1 .. Name_Len) /= "false" then
2756 Error_Msg (Project, In_Tree,
2757 "Externally_Built may only be true or false",
2758 Externally_Built.Location);
2762 -- A virtual project extending an externally built project is itself
2763 -- externally built.
2765 if Data.Virtual and then Data.Extends /= No_Project then
2766 Data.Externally_Built :=
2767 In_Tree.Projects.Table (Data.Extends).Externally_Built;
2770 if Current_Verbosity = High then
2771 Write_Str ("Project is ");
2773 if not Data.Externally_Built then
2777 Write_Line ("externally built.");
2779 end Check_If_Externally_Built;
2781 ----------------------
2782 -- Check_Interfaces --
2783 ----------------------
2785 procedure Check_Interfaces
2786 (Project : Project_Id;
2787 In_Tree : Project_Tree_Ref;
2788 Data : in out Project_Data)
2790 Interfaces : constant Prj.Variable_Value :=
2792 (Snames.Name_Interfaces,
2793 Data.Decl.Attributes,
2796 List : String_List_Id;
2797 Element : String_Element;
2798 Name : File_Name_Type;
2801 Src_Data : Source_Data;
2803 Project_2 : Project_Id;
2804 Data_2 : Project_Data;
2807 if not Interfaces.Default then
2809 -- Set In_Interfaces to False for all sources. It will be set to True
2810 -- later for the sources in the Interfaces list.
2812 Project_2 := Project;
2815 Source := Data_2.First_Source;
2816 while Source /= No_Source loop
2817 Src_Data := In_Tree.Sources.Table (Source);
2818 Src_Data.In_Interfaces := False;
2819 In_Tree.Sources.Table (Source) := Src_Data;
2820 Source := Src_Data.Next_In_Project;
2823 Project_2 := Data_2.Extends;
2825 exit when Project_2 = No_Project;
2827 Data_2 := In_Tree.Projects.Table (Project_2);
2830 List := Interfaces.Values;
2831 while List /= Nil_String loop
2832 Element := In_Tree.String_Elements.Table (List);
2833 Get_Name_String (Element.Value);
2834 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2837 Project_2 := Project;
2841 Source := Data_2.First_Source;
2842 while Source /= No_Source loop
2843 Src_Data := In_Tree.Sources.Table (Source);
2844 if Src_Data.File = Name then
2845 if not Src_Data.Locally_Removed then
2846 In_Tree.Sources.Table (Source).In_Interfaces := True;
2847 In_Tree.Sources.Table
2848 (Source).Declared_In_Interfaces := True;
2850 if Src_Data.Other_Part /= No_Source then
2851 In_Tree.Sources.Table
2852 (Src_Data.Other_Part).In_Interfaces := True;
2853 In_Tree.Sources.Table
2854 (Src_Data.Other_Part).Declared_In_Interfaces :=
2858 if Current_Verbosity = High then
2859 Write_Str (" interface: ");
2860 Write_Line (Get_Name_String (Src_Data.Path.Name));
2867 Source := Src_Data.Next_In_Project;
2870 Project_2 := Data_2.Extends;
2872 exit Big_Loop when Project_2 = No_Project;
2874 Data_2 := In_Tree.Projects.Table (Project_2);
2877 if Source = No_Source then
2878 Error_Msg_File_1 := File_Name_Type (Element.Value);
2879 Error_Msg_Name_1 := Data.Name;
2884 "{ cannot be an interface of project %% " &
2885 "as it is not one of its sources",
2889 List := Element.Next;
2892 Data.Interfaces_Defined := True;
2894 elsif Data.Extends /= No_Project then
2895 Data.Interfaces_Defined :=
2896 In_Tree.Projects.Table (Data.Extends).Interfaces_Defined;
2898 if Data.Interfaces_Defined then
2899 Source := Data.First_Source;
2900 while Source /= No_Source loop
2901 Src_Data := In_Tree.Sources.Table (Source);
2903 if not Src_Data.Declared_In_Interfaces then
2904 Src_Data.In_Interfaces := False;
2905 In_Tree.Sources.Table (Source) := Src_Data;
2908 Source := Src_Data.Next_In_Project;
2912 end Check_Interfaces;
2914 --------------------------
2915 -- Check_Naming_Schemes --
2916 --------------------------
2918 procedure Check_Naming_Schemes
2919 (Data : in out Project_Data;
2920 Project : Project_Id;
2921 In_Tree : Project_Tree_Ref)
2923 Naming_Id : constant Package_Id :=
2924 Util.Value_Of (Name_Naming, Data.Decl.Packages, In_Tree);
2925 Naming : Package_Element;
2927 procedure Check_Unit_Names (List : Array_Element_Id);
2928 -- Check that a list of unit names contains only valid names
2930 procedure Get_Exceptions (Kind : Source_Kind);
2932 procedure Get_Unit_Exceptions (Kind : Source_Kind);
2934 ----------------------
2935 -- Check_Unit_Names --
2936 ----------------------
2938 procedure Check_Unit_Names (List : Array_Element_Id) is
2939 Current : Array_Element_Id;
2940 Element : Array_Element;
2941 Unit_Name : Name_Id;
2944 -- Loop through elements of the string list
2947 while Current /= No_Array_Element loop
2948 Element := In_Tree.Array_Elements.Table (Current);
2950 -- Put file name in canonical case
2952 if not Osint.File_Names_Case_Sensitive then
2953 Get_Name_String (Element.Value.Value);
2954 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
2955 Element.Value.Value := Name_Find;
2958 -- Check that it contains a valid unit name
2960 Get_Name_String (Element.Index);
2961 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit_Name);
2963 if Unit_Name = No_Name then
2964 Err_Vars.Error_Msg_Name_1 := Element.Index;
2967 "%% is not a valid unit name.",
2968 Element.Value.Location);
2971 if Current_Verbosity = High then
2972 Write_Str (" Unit (""");
2973 Write_Str (Get_Name_String (Unit_Name));
2977 Element.Index := Unit_Name;
2978 In_Tree.Array_Elements.Table (Current) := Element;
2981 Current := Element.Next;
2983 end Check_Unit_Names;
2985 --------------------
2986 -- Get_Exceptions --
2987 --------------------
2989 procedure Get_Exceptions (Kind : Source_Kind) is
2990 Exceptions : Array_Element_Id;
2991 Exception_List : Variable_Value;
2992 Element_Id : String_List_Id;
2993 Element : String_Element;
2994 File_Name : File_Name_Type;
2995 Lang_Id : Language_Index;
2997 Lang_Kind : Language_Kind;
3004 (Name_Implementation_Exceptions,
3005 In_Arrays => Naming.Decl.Arrays,
3006 In_Tree => In_Tree);
3011 (Name_Specification_Exceptions,
3012 In_Arrays => Naming.Decl.Arrays,
3013 In_Tree => In_Tree);
3016 Lang_Id := Data.First_Language_Processing;
3017 while Lang_Id /= No_Language_Index loop
3018 if In_Tree.Languages_Data.Table (Lang_Id).Config.Kind =
3021 Lang := In_Tree.Languages_Data.Table (Lang_Id).Name;
3023 In_Tree.Languages_Data.Table (Lang_Id).Config.Kind;
3025 Exception_List := Value_Of
3027 In_Array => Exceptions,
3028 In_Tree => In_Tree);
3030 if Exception_List /= Nil_Variable_Value then
3031 Element_Id := Exception_List.Values;
3032 while Element_Id /= Nil_String loop
3033 Element := In_Tree.String_Elements.Table (Element_Id);
3035 if Osint.File_Names_Case_Sensitive then
3036 File_Name := File_Name_Type (Element.Value);
3038 Get_Name_String (Element.Value);
3039 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3040 File_Name := Name_Find;
3043 Source := Data.First_Source;
3044 while Source /= No_Source
3046 In_Tree.Sources.Table (Source).File /= File_Name
3049 In_Tree.Sources.Table (Source).Next_In_Project;
3052 if Source = No_Source then
3061 File_Name => File_Name,
3062 Display_File => File_Name_Type (Element.Value),
3063 Naming_Exception => True,
3064 Lang_Kind => Lang_Kind);
3067 -- Check if the file name is already recorded for
3068 -- another language or another kind.
3071 In_Tree.Sources.Table (Source).Language /= Lang_Id
3076 "the same file cannot be a source " &
3080 elsif In_Tree.Sources.Table (Source).Kind /= Kind then
3084 "the same file cannot be a source " &
3089 -- If the file is already recorded for the same
3090 -- language and the same kind, it means that the file
3091 -- name appears several times in the *_Exceptions
3092 -- attribute; so there is nothing to do.
3096 Element_Id := Element.Next;
3101 Lang_Id := In_Tree.Languages_Data.Table (Lang_Id).Next;
3105 -------------------------
3106 -- Get_Unit_Exceptions --
3107 -------------------------
3109 procedure Get_Unit_Exceptions (Kind : Source_Kind) is
3110 Exceptions : Array_Element_Id;
3111 Element : Array_Element;
3114 File_Name : File_Name_Type;
3115 Lang_Id : constant Language_Index :=
3116 Data.Unit_Based_Language_Index;
3117 Lang : constant Name_Id :=
3118 Data.Unit_Based_Language_Name;
3121 Source_To_Replace : Source_Id := No_Source;
3123 Other_Project : Project_Id;
3124 Other_Part : Source_Id := No_Source;
3127 if Lang_Id = No_Language_Index or else Lang = No_Name then
3132 Exceptions := Value_Of
3134 In_Arrays => Naming.Decl.Arrays,
3135 In_Tree => In_Tree);
3137 if Exceptions = No_Array_Element then
3140 (Name_Implementation,
3141 In_Arrays => Naming.Decl.Arrays,
3142 In_Tree => In_Tree);
3149 In_Arrays => Naming.Decl.Arrays,
3150 In_Tree => In_Tree);
3152 if Exceptions = No_Array_Element then
3153 Exceptions := Value_Of
3154 (Name_Specification,
3155 In_Arrays => Naming.Decl.Arrays,
3156 In_Tree => In_Tree);
3161 while Exceptions /= No_Array_Element loop
3162 Element := In_Tree.Array_Elements.Table (Exceptions);
3164 if Osint.File_Names_Case_Sensitive then
3165 File_Name := File_Name_Type (Element.Value.Value);
3167 Get_Name_String (Element.Value.Value);
3168 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3169 File_Name := Name_Find;
3172 Get_Name_String (Element.Index);
3173 To_Lower (Name_Buffer (1 .. Name_Len));
3176 Index := Element.Value.Index;
3178 -- For Ada, check if it is a valid unit name
3180 if Lang = Name_Ada then
3181 Get_Name_String (Element.Index);
3182 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit);
3184 if Unit = No_Name then
3185 Err_Vars.Error_Msg_Name_1 := Element.Index;
3188 "%% is not a valid unit name.",
3189 Element.Value.Location);
3193 if Unit /= No_Name then
3195 -- Check if the source already exists
3197 Source := In_Tree.First_Source;
3198 Source_To_Replace := No_Source;
3200 while Source /= No_Source and then
3201 (In_Tree.Sources.Table (Source).Unit /= Unit or else
3202 In_Tree.Sources.Table (Source).Index /= Index)
3204 Source := In_Tree.Sources.Table (Source).Next_In_Sources;
3207 if Source /= No_Source then
3208 if In_Tree.Sources.Table (Source).Kind /= Kind then
3209 Other_Part := Source;
3213 In_Tree.Sources.Table (Source).Next_In_Sources;
3215 exit when Source = No_Source or else
3216 (In_Tree.Sources.Table (Source).Unit = Unit
3218 In_Tree.Sources.Table (Source).Index = Index);
3222 if Source /= No_Source then
3223 Other_Project := In_Tree.Sources.Table (Source).Project;
3225 if Is_Extending (Project, Other_Project, In_Tree) then
3227 In_Tree.Sources.Table (Source).Other_Part;
3229 -- Record the source to be removed
3231 Source_To_Replace := Source;
3232 Source := No_Source;
3235 Error_Msg_Name_1 := Unit;
3237 In_Tree.Projects.Table (Other_Project).Name;
3241 "%% is already a source of project %%",
3242 Element.Value.Location);
3247 if Source = No_Source then
3256 File_Name => File_Name,
3257 Display_File => File_Name_Type (Element.Value.Value),
3258 Lang_Kind => Unit_Based,
3259 Other_Part => Other_Part,
3262 Naming_Exception => True,
3263 Source_To_Replace => Source_To_Replace);
3267 Exceptions := Element.Next;
3270 end Get_Unit_Exceptions;
3272 -- Start of processing for Check_Naming_Schemes
3275 if Get_Mode = Ada_Only then
3277 -- If there is a package Naming, we will put in Data.Naming what is
3278 -- in this package Naming.
3280 if Naming_Id /= No_Package then
3281 Naming := In_Tree.Packages.Table (Naming_Id);
3283 if Current_Verbosity = High then
3284 Write_Line ("Checking ""Naming"" for Ada.");
3288 Bodies : constant Array_Element_Id :=
3290 (Name_Body, Naming.Decl.Arrays, In_Tree);
3292 Specs : constant Array_Element_Id :=
3294 (Name_Spec, Naming.Decl.Arrays, In_Tree);
3297 if Bodies /= No_Array_Element then
3299 -- We have elements in the array Body_Part
3301 if Current_Verbosity = High then
3302 Write_Line ("Found Bodies.");
3305 Data.Naming.Bodies := Bodies;
3306 Check_Unit_Names (Bodies);
3309 if Current_Verbosity = High then
3310 Write_Line ("No Bodies.");
3314 if Specs /= No_Array_Element then
3316 -- We have elements in the array Specs
3318 if Current_Verbosity = High then
3319 Write_Line ("Found Specs.");
3322 Data.Naming.Specs := Specs;
3323 Check_Unit_Names (Specs);
3326 if Current_Verbosity = High then
3327 Write_Line ("No Specs.");
3332 -- We are now checking if variables Dot_Replacement, Casing,
3333 -- Spec_Suffix, Body_Suffix and/or Separate_Suffix exist.
3335 -- For each variable, if it does not exist, we do nothing,
3336 -- because we already have the default.
3338 -- Check Dot_Replacement
3341 Dot_Replacement : constant Variable_Value :=
3343 (Name_Dot_Replacement,
3344 Naming.Decl.Attributes, In_Tree);
3347 pragma Assert (Dot_Replacement.Kind = Single,
3348 "Dot_Replacement is not a single string");
3350 if not Dot_Replacement.Default then
3351 Get_Name_String (Dot_Replacement.Value);
3353 if Name_Len = 0 then
3356 "Dot_Replacement cannot be empty",
3357 Dot_Replacement.Location);
3360 if Osint.File_Names_Case_Sensitive then
3361 Data.Naming.Dot_Replacement :=
3362 File_Name_Type (Dot_Replacement.Value);
3364 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3365 Data.Naming.Dot_Replacement := Name_Find;
3367 Data.Naming.Dot_Repl_Loc := Dot_Replacement.Location;
3372 if Current_Verbosity = High then
3373 Write_Str (" Dot_Replacement = """);
3374 Write_Str (Get_Name_String (Data.Naming.Dot_Replacement));
3382 Casing_String : constant Variable_Value :=
3385 Naming.Decl.Attributes,
3389 pragma Assert (Casing_String.Kind = Single,
3390 "Casing
is not a single
string");
3392 if not Casing_String.Default then
3394 Casing_Image : constant String :=
3395 Get_Name_String (Casing_String.Value);
3398 Casing_Value : constant Casing_Type :=
3399 Value (Casing_Image);
3401 Data.Naming.Casing := Casing_Value;
3405 when Constraint_Error =>
3406 if Casing_Image'Length = 0 then
3409 "Casing cannot be an empty
string",
3410 Casing_String.Location);
3413 Name_Len := Casing_Image'Length;
3414 Name_Buffer (1 .. Name_Len) := Casing_Image;
3415 Err_Vars.Error_Msg_Name_1 := Name_Find;
3418 "%% is not a correct Casing
",
3419 Casing_String.Location);
3425 if Current_Verbosity = High then
3426 Write_Str (" Casing
= ");
3427 Write_Str (Image (Data.Naming.Casing));
3432 -- Check Spec_Suffix
3435 Ada_Spec_Suffix : constant Variable_Value :=
3439 In_Array => Data.Naming.Spec_Suffix,
3440 In_Tree => In_Tree);
3443 if Ada_Spec_Suffix.Kind = Single
3444 and then Get_Name_String (Ada_Spec_Suffix.Value) /= ""
3446 Get_Name_String (Ada_Spec_Suffix.Value);
3447 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3448 Set_Spec_Suffix (In_Tree, "ada
", Data.Naming, Name_Find);
3449 Data.Naming.Ada_Spec_Suffix_Loc := Ada_Spec_Suffix.Location;
3456 Default_Ada_Spec_Suffix);
3460 if Current_Verbosity = High then
3461 Write_Str (" Spec_Suffix
= """);
3462 Write_Str (Spec_Suffix_Of (In_Tree, "ada
", Data.Naming));
3467 -- Check Body_Suffix
3470 Ada_Body_Suffix : constant Variable_Value :=
3474 In_Array => Data.Naming.Body_Suffix,
3475 In_Tree => In_Tree);
3478 if Ada_Body_Suffix.Kind = Single
3479 and then Get_Name_String (Ada_Body_Suffix.Value) /= ""
3481 Get_Name_String (Ada_Body_Suffix.Value);
3482 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3483 Set_Body_Suffix (In_Tree, "ada", Data.Naming, Name_Find);
3484 Data.Naming.Ada_Body_Suffix_Loc := Ada_Body_Suffix.Location;
3491 Default_Ada_Body_Suffix);
3495 if Current_Verbosity = High then
3496 Write_Str (" Body_Suffix = """);
3497 Write_Str (Body_Suffix_Of (In_Tree, "ada", Data.Naming));
3502 -- Check Separate_Suffix
3505 Ada_Sep_Suffix : constant Variable_Value :=
3507 (Variable_Name => Name_Separate_Suffix,
3508 In_Variables => Naming.Decl.Attributes,
3509 In_Tree => In_Tree);
3512 if Ada_Sep_Suffix.Default then
3513 Data.Naming.Separate_Suffix :=
3514 Body_Suffix_Id_Of (In_Tree, Name_Ada, Data.Naming);
3517 Get_Name_String (Ada_Sep_Suffix.Value);
3519 if Name_Len = 0 then
3522 "Separate_Suffix cannot be empty
",
3523 Ada_Sep_Suffix.Location);
3526 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3527 Data.Naming.Separate_Suffix := Name_Find;
3528 Data.Naming.Sep_Suffix_Loc := Ada_Sep_Suffix.Location;
3533 if Current_Verbosity = High then
3534 Write_Str (" Separate_Suffix
= """);
3535 Write_Str (Get_Name_String (Data.Naming.Separate_Suffix));
3540 -- Check if Data.Naming is valid
3542 Check_Ada_Naming_Scheme_Validity (Project, In_Tree, Data.Naming);
3545 elsif not In_Configuration then
3547 -- Look into package Naming, if there is one
3549 if Naming_Id /= No_Package then
3550 Naming := In_Tree.Packages.Table (Naming_Id);
3552 if Current_Verbosity = High then
3553 Write_Line ("Checking package Naming.");
3556 -- We are now checking if attribute Dot_Replacement, Casing,
3557 -- and/or Separate_Suffix exist.
3559 -- For each attribute, if it does not exist, we do nothing,
3560 -- because we already have the default.
3561 -- Otherwise, for all unit-based languages, we put the declared
3562 -- value in the language config.
3565 Dot_Repl : constant Variable_Value :=
3567 (Name_Dot_Replacement,
3568 Naming.Decl.Attributes, In_Tree);
3569 Dot_Replacement : File_Name_Type := No_File;
3571 Casing_String : constant Variable_Value :=
3574 Naming.Decl.Attributes,
3576 Casing : Casing_Type;
3577 Casing_Defined : Boolean := False;
3579 Sep_Suffix : constant Variable_Value :=
3581 (Variable_Name => Name_Separate_Suffix,
3582 In_Variables => Naming.Decl.Attributes,
3583 In_Tree => In_Tree);
3584 Separate_Suffix : File_Name_Type := No_File;
3586 Lang_Id : Language_Index;
3588 -- Check attribute Dot_Replacement
3590 if not Dot_Repl.Default then
3591 Get_Name_String (Dot_Repl.Value);
3593 if Name_Len = 0 then
3596 "Dot_Replacement cannot be empty",
3600 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3601 Dot_Replacement := Name_Find;
3603 if Current_Verbosity = High then
3604 Write_Str (" Dot_Replacement = """);
3605 Write_Str (Get_Name_String (Dot_Replacement));
3612 -- Check attribute Casing
3614 if not Casing_String.Default then
3616 Casing_Image : constant String :=
3617 Get_Name_String (Casing_String.Value);
3620 Casing_Value : constant Casing_Type :=
3621 Value (Casing_Image);
3623 Casing := Casing_Value;
3624 Casing_Defined := True;
3626 if Current_Verbosity = High then
3627 Write_Str (" Casing
= ");
3628 Write_Str (Image (Casing));
3635 when Constraint_Error =>
3636 if Casing_Image'Length = 0 then
3639 "Casing cannot be an empty
string",
3640 Casing_String.Location);
3643 Name_Len := Casing_Image'Length;
3644 Name_Buffer (1 .. Name_Len) := Casing_Image;
3645 Err_Vars.Error_Msg_Name_1 := Name_Find;
3648 "%% is not a correct Casing
",
3649 Casing_String.Location);
3654 if not Sep_Suffix.Default then
3655 Get_Name_String (Sep_Suffix.Value);
3657 if Name_Len = 0 then
3660 "Separate_Suffix cannot be empty
",
3661 Sep_Suffix.Location);
3664 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
3665 Separate_Suffix := Name_Find;
3667 if Current_Verbosity = High then
3668 Write_Str (" Separate_Suffix
= """);
3669 Write_Str (Get_Name_String (Separate_Suffix));
3676 -- For all unit based languages, if any, set the specified
3677 -- value of Dot_Replacement, Casing and/or Separate_Suffix.
3679 if Dot_Replacement /= No_File
3680 or else Casing_Defined
3681 or else Separate_Suffix /= No_File
3683 Lang_Id := Data.First_Language_Processing;
3684 while Lang_Id /= No_Language_Index loop
3685 if In_Tree.Languages_Data.Table
3686 (Lang_Id).Config.Kind = Unit_Based
3688 if Dot_Replacement /= No_File then
3689 In_Tree.Languages_Data.Table
3690 (Lang_Id).Config.Naming_Data.Dot_Replacement :=
3694 if Casing_Defined then
3695 In_Tree.Languages_Data.Table
3696 (Lang_Id).Config.Naming_Data.Casing := Casing;
3699 if Separate_Suffix /= No_File then
3700 In_Tree.Languages_Data.Table
3701 (Lang_Id).Config.Naming_Data.Separate_Suffix :=
3707 In_Tree.Languages_Data.Table (Lang_Id).Next;
3712 -- Next, get the spec and body suffixes
3715 Suffix : Variable_Value;
3716 Lang_Id : Language_Index;
3720 Lang_Id := Data.First_Language_Processing;
3721 while Lang_Id /= No_Language_Index loop
3722 Lang := In_Tree.Languages_Data.Table (Lang_Id).Name;
3728 Attribute_Or_Array_Name => Name_Spec_Suffix,
3729 In_Package => Naming_Id,
3730 In_Tree => In_Tree);
3732 if Suffix = Nil_Variable_Value then
3735 Attribute_Or_Array_Name => Name_Specification_Suffix,
3736 In_Package => Naming_Id,
3737 In_Tree => In_Tree);
3740 if Suffix /= Nil_Variable_Value then
3741 In_Tree.Languages_Data.Table (Lang_Id).
3742 Config.Naming_Data.Spec_Suffix :=
3743 File_Name_Type (Suffix.Value);
3750 Attribute_Or_Array_Name => Name_Body_Suffix,
3751 In_Package => Naming_Id,
3752 In_Tree => In_Tree);
3754 if Suffix = Nil_Variable_Value then
3757 Attribute_Or_Array_Name => Name_Implementation_Suffix,
3758 In_Package => Naming_Id,
3759 In_Tree => In_Tree);
3762 if Suffix /= Nil_Variable_Value then
3763 In_Tree.Languages_Data.Table (Lang_Id).
3764 Config.Naming_Data.Body_Suffix :=
3765 File_Name_Type (Suffix.Value);
3768 Lang_Id := In_Tree.Languages_Data.Table (Lang_Id).Next;
3772 -- Get the exceptions for file based languages
3774 Get_Exceptions (Spec);
3775 Get_Exceptions (Impl);
3777 -- Get the exceptions for unit based languages
3779 Get_Unit_Exceptions (Spec);
3780 Get_Unit_Exceptions (Impl);
3784 end Check_Naming_Schemes;
3786 ------------------------------
3787 -- Check_Library_Attributes --
3788 ------------------------------
3790 procedure Check_Library_Attributes
3791 (Project : Project_Id;
3792 In_Tree : Project_Tree_Ref;
3793 Current_Dir : String;
3794 Data : in out Project_Data)
3796 Attributes : constant Prj.Variable_Id := Data.Decl.Attributes;
3798 Lib_Dir : constant Prj.Variable_Value :=
3800 (Snames.Name_Library_Dir, Attributes, In_Tree);
3802 Lib_Name : constant Prj.Variable_Value :=
3804 (Snames.Name_Library_Name, Attributes, In_Tree);
3806 Lib_Version : constant Prj.Variable_Value :=
3808 (Snames.Name_Library_Version, Attributes, In_Tree);
3810 Lib_ALI_Dir : constant Prj.Variable_Value :=
3812 (Snames.Name_Library_Ali_Dir, Attributes, In_Tree);
3814 The_Lib_Kind : constant Prj.Variable_Value :=
3816 (Snames.Name_Library_Kind, Attributes, In_Tree);
3818 Imported_Project_List : Project_List := Empty_Project_List;
3820 Continuation : String_Access := No_Continuation_String'Access;
3822 Support_For_Libraries : Library_Support;
3824 Library_Directory_Present : Boolean;
3826 procedure Check_Library (Proj : Project_Id; Extends : Boolean);
3827 -- Check if an imported or extended project if also a library project
3833 procedure Check_Library (Proj : Project_Id; Extends : Boolean) is
3834 Proj_Data : Project_Data;
3839 if Proj /= No_Project then
3840 Proj_Data := In_Tree.Projects.Table (Proj);
3842 if not Proj_Data.Library then
3844 -- The only not library projects that are OK are those that
3845 -- have no sources. However, header files from non-Ada
3846 -- languages are OK, as there is nothing to compile.
3848 Src_Id := Proj_Data.First_Source;
3849 while Src_Id /= No_Source loop
3850 Src := In_Tree.Sources.Table (Src_Id);
3852 exit when Src.Lang_Kind /= File_Based
3853 or else Src.Kind /= Spec;
3855 Src_Id := Src.Next_In_Project;
3858 if Src_Id /= No_Source then
3859 Error_Msg_Name_1 := Data.Name;
3860 Error_Msg_Name_2 := Proj_Data.Name;
3863 if Data.Library_Kind /= Static then
3867 "shared library project %% cannot extend " &
3868 "project %% that is not a library project",
3870 Continuation := Continuation_String'Access;
3873 elsif Data.Library_Kind /= Static then
3877 "shared library project %% cannot import project %% " &
3878 "that is not a shared library project",
3880 Continuation := Continuation_String'Access;
3884 elsif Data.Library_Kind /= Static and then
3885 Proj_Data.Library_Kind = Static
3887 Error_Msg_Name_1 := Data.Name;
3888 Error_Msg_Name_2 := Proj_Data.Name;
3894 "shared library project %% cannot extend static " &
3895 "library project %%",
3902 "shared library project %% cannot import static " &
3903 "library project %%",
3907 Continuation := Continuation_String'Access;
3912 -- Start of processing for Check_Library_Attributes
3915 Library_Directory_Present := Lib_Dir.Value /= Empty_String;
3917 -- Special case of extending project
3919 if Data.Extends /= No_Project then
3921 Extended_Data : constant Project_Data :=
3922 In_Tree.Projects.Table (Data.Extends);
3925 -- If the project extended is a library project, we inherit the
3926 -- library name, if it is not redefined; we check that the library
3927 -- directory is specified.
3929 if Extended_Data.Library then
3930 if Data.Qualifier = Standard then
3933 "a standard project cannot extend a library project",
3937 if Lib_Name.Default then
3938 Data.Library_Name := Extended_Data.Library_Name;
3941 if Lib_Dir.Default then
3942 if not Data.Virtual then
3945 "a project extending a library project must " &
3946 "specify an attribute Library_Dir",
3950 -- For a virtual project extending a library project,
3951 -- inherit library directory.
3953 Data.Library_Dir := Extended_Data.Library_Dir;
3954 Library_Directory_Present := True;
3962 pragma Assert (Lib_Name.Kind = Single);
3964 if Lib_Name.Value = Empty_String then
3965 if Current_Verbosity = High
3966 and then Data.Library_Name = No_Name
3968 Write_Line ("No library name");
3972 -- There is no restriction on the syntax of library names
3974 Data.Library_Name := Lib_Name.Value;
3977 if Data.Library_Name /= No_Name then
3978 if Current_Verbosity = High then
3979 Write_Str ("Library name = """);
3980 Write_Str (Get_Name_String (Data.Library_Name));
3984 pragma Assert (Lib_Dir.Kind = Single);
3986 if not Library_Directory_Present then
3987 if Current_Verbosity = High then
3988 Write_Line ("No library directory");
3992 -- Find path name (unless inherited), check that it is a directory
3994 if Data.Library_Dir = No_Path_Information then
3998 File_Name_Type (Lib_Dir.Value),
3999 Data.Directory.Display_Name,
4000 Data.Library_Dir.Name,
4001 Data.Library_Dir.Display_Name,
4002 Create => "library",
4003 Current_Dir => Current_Dir,
4004 Location => Lib_Dir.Location);
4007 if Data.Library_Dir = No_Path_Information then
4009 -- Get the absolute name of the library directory that
4010 -- does not exist, to report an error.
4013 Dir_Name : constant String :=
4014 Get_Name_String (Lib_Dir.Value);
4017 if Is_Absolute_Path (Dir_Name) then
4018 Err_Vars.Error_Msg_File_1 :=
4019 File_Name_Type (Lib_Dir.Value);
4022 Get_Name_String (Data.Directory.Display_Name);
4024 if Name_Buffer (Name_Len) /= Directory_Separator then
4025 Name_Len := Name_Len + 1;
4026 Name_Buffer (Name_Len) := Directory_Separator;
4030 (Name_Len + 1 .. Name_Len + Dir_Name'Length) :=
4032 Name_Len := Name_Len + Dir_Name'Length;
4033 Err_Vars.Error_Msg_File_1 := Name_Find;
4040 "library directory { does not exist",
4044 -- The library directory cannot be the same as the Object
4047 elsif Data.Library_Dir.Name = Data.Object_Directory.Name then
4050 "library directory cannot be the same " &
4051 "as object directory",
4053 Data.Library_Dir := No_Path_Information;
4057 OK : Boolean := True;
4058 Dirs_Id : String_List_Id;
4059 Dir_Elem : String_Element;
4062 -- The library directory cannot be the same as a source
4063 -- directory of the current project.
4065 Dirs_Id := Data.Source_Dirs;
4066 while Dirs_Id /= Nil_String loop
4067 Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id);
4068 Dirs_Id := Dir_Elem.Next;
4071 Data.Library_Dir.Name = Path_Name_Type (Dir_Elem.Value)
4073 Err_Vars.Error_Msg_File_1 :=
4074 File_Name_Type (Dir_Elem.Value);
4077 "library directory cannot be the same " &
4078 "as source directory {",
4087 -- The library directory cannot be the same as a source
4088 -- directory of another project either.
4091 for Pid in 1 .. Project_Table.Last (In_Tree.Projects) loop
4092 if Pid /= Project then
4093 Dirs_Id := In_Tree.Projects.Table (Pid).Source_Dirs;
4095 Dir_Loop : while Dirs_Id /= Nil_String loop
4097 In_Tree.String_Elements.Table (Dirs_Id);
4098 Dirs_Id := Dir_Elem.Next;
4100 if Data.Library_Dir.Name =
4101 Path_Name_Type (Dir_Elem.Value)
4103 Err_Vars.Error_Msg_File_1 :=
4104 File_Name_Type (Dir_Elem.Value);
4105 Err_Vars.Error_Msg_Name_1 :=
4106 In_Tree.Projects.Table (Pid).Name;
4110 "library directory cannot be the same " &
4111 "as source directory { of project %%",
4118 end loop Project_Loop;
4122 Data.Library_Dir := No_Path_Information;
4124 elsif Current_Verbosity = High then
4126 -- Display the Library directory in high verbosity
4128 Write_Str ("Library directory =""");
4130 (Get_Name_String (Data.Library_Dir.Display_Name));
4140 Data.Library_Dir /= No_Path_Information
4142 Data.Library_Name /= No_Name;
4144 if Data.Extends = No_Project then
4145 case Data.Qualifier is
4147 if Data.Library then
4150 "a standard project cannot be a library project",
4155 if not Data.Library then
4158 "not a library project",
4168 if Data.Library then
4169 if Get_Mode = Multi_Language then
4170 Support_For_Libraries := Data.Config.Lib_Support;
4173 Support_For_Libraries := MLib.Tgt.Support_For_Libraries;
4176 if Support_For_Libraries = Prj.None then
4179 "?libraries are not supported on this platform",
4181 Data.Library := False;
4184 if Lib_ALI_Dir.Value = Empty_String then
4185 if Current_Verbosity = High then
4186 Write_Line ("No library ALI directory specified");
4188 Data.Library_ALI_Dir := Data.Library_Dir;
4191 -- Find path name, check that it is a directory
4196 File_Name_Type (Lib_ALI_Dir.Value),
4197 Data.Directory.Display_Name,
4198 Data.Library_ALI_Dir.Name,
4199 Data.Library_ALI_Dir.Display_Name,
4200 Create => "library ALI",
4201 Current_Dir => Current_Dir,
4202 Location => Lib_ALI_Dir.Location);
4204 if Data.Library_ALI_Dir = No_Path_Information then
4206 -- Get the absolute name of the library ALI directory that
4207 -- does not exist, to report an error.
4210 Dir_Name : constant String :=
4211 Get_Name_String (Lib_ALI_Dir.Value);
4214 if Is_Absolute_Path (Dir_Name) then
4215 Err_Vars.Error_Msg_File_1 :=
4216 File_Name_Type (Lib_Dir.Value);
4219 Get_Name_String (Data.Directory.Display_Name);
4221 if Name_Buffer (Name_Len) /= Directory_Separator then
4222 Name_Len := Name_Len + 1;
4223 Name_Buffer (Name_Len) := Directory_Separator;
4227 (Name_Len + 1 .. Name_Len + Dir_Name'Length) :=
4229 Name_Len := Name_Len + Dir_Name'Length;
4230 Err_Vars.Error_Msg_File_1 := Name_Find;
4237 "library 'A
'L'I directory { does not exist",
4238 Lib_ALI_Dir.Location);
4242 if Data.Library_ALI_Dir /= Data.Library_Dir then
4244 -- The library ALI directory cannot be the same as the
4245 -- Object directory.
4247 if Data.Library_ALI_Dir = Data.Object_Directory then
4250 "library 'A
'L'I directory cannot be the same " &
4251 "as object directory",
4252 Lib_ALI_Dir.Location);
4253 Data.Library_ALI_Dir := No_Path_Information;
4257 OK : Boolean := True;
4258 Dirs_Id : String_List_Id;
4259 Dir_Elem : String_Element;
4262 -- The library ALI directory cannot be the same as
4263 -- a source directory of the current project.
4265 Dirs_Id := Data.Source_Dirs;
4266 while Dirs_Id /= Nil_String loop
4267 Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id);
4268 Dirs_Id := Dir_Elem.Next;
4270 if Data.Library_ALI_Dir.Name =
4271 Path_Name_Type (Dir_Elem.Value)
4273 Err_Vars.Error_Msg_File_1 :=
4274 File_Name_Type (Dir_Elem.Value);
4277 "library 'A
'L'I directory cannot be " &
4278 "the same as source directory {",
4279 Lib_ALI_Dir.Location);
4287 -- The library ALI directory cannot be the same as
4288 -- a source directory of another project either.
4292 Pid in 1 .. Project_Table.Last (In_Tree.Projects)
4294 if Pid /= Project then
4296 In_Tree.Projects.Table (Pid).Source_Dirs;
4299 while Dirs_Id /= Nil_String loop
4301 In_Tree.String_Elements.Table (Dirs_Id);
4302 Dirs_Id := Dir_Elem.Next;
4304 if Data.Library_ALI_Dir.Name =
4305 Path_Name_Type (Dir_Elem.Value)
4307 Err_Vars.Error_Msg_File_1 :=
4308 File_Name_Type (Dir_Elem.Value);
4309 Err_Vars.Error_Msg_Name_1 :=
4310 In_Tree.Projects.Table (Pid).Name;
4314 "library 'A
'L'I directory cannot " &
4315 "be the same as source directory " &
4317 Lib_ALI_Dir.Location);
4319 exit ALI_Project_Loop;
4321 end loop ALI_Dir_Loop;
4323 end loop ALI_Project_Loop;
4327 Data.Library_ALI_Dir := No_Path_Information;
4329 elsif Current_Verbosity = High then
4331 -- Display the Library ALI directory in high
4334 Write_Str ("Library ALI directory =""");
4337 (Data.Library_ALI_Dir.Display_Name));
4345 pragma Assert (Lib_Version.Kind = Single);
4347 if Lib_Version.Value = Empty_String then
4348 if Current_Verbosity = High then
4349 Write_Line ("No library version specified");
4353 Data.Lib_Internal_Name := Lib_Version.Value;
4356 pragma Assert (The_Lib_Kind.Kind = Single);
4358 if The_Lib_Kind.Value = Empty_String then
4359 if Current_Verbosity = High then
4360 Write_Line ("No library kind specified");
4364 Get_Name_String (The_Lib_Kind.Value);
4367 Kind_Name : constant String :=
4368 To_Lower (Name_Buffer (1 .. Name_Len));
4370 OK : Boolean := True;
4373 if Kind_Name = "static" then
4374 Data.Library_Kind := Static;
4376 elsif Kind_Name = "dynamic" then
4377 Data.Library_Kind := Dynamic;
4379 elsif Kind_Name = "relocatable" then
4380 Data.Library_Kind := Relocatable;
4385 "illegal value for Library_Kind",
4386 The_Lib_Kind.Location);
4390 if Current_Verbosity = High and then OK then
4391 Write_Str ("Library kind = ");
4392 Write_Line (Kind_Name);
4395 if Data.Library_Kind /= Static and then
4396 Support_For_Libraries = Prj.Static_Only
4400 "only static libraries are supported " &
4402 The_Lib_Kind.Location);
4403 Data.Library := False;
4408 if Data.Library then
4409 if Current_Verbosity = High then
4410 Write_Line ("This is a library project file");
4413 if Get_Mode = Multi_Language then
4414 Check_Library (Data.Extends, Extends => True);
4416 Imported_Project_List := Data.Imported_Projects;
4417 while Imported_Project_List /= Empty_Project_List loop
4419 (In_Tree.Project_Lists.Table
4420 (Imported_Project_List).Project,
4422 Imported_Project_List :=
4423 In_Tree.Project_Lists.Table
4424 (Imported_Project_List).Next;
4432 if Data.Extends /= No_Project then
4433 In_Tree.Projects.Table (Data.Extends).Library := False;
4435 end Check_Library_Attributes;
4437 --------------------------
4438 -- Check_Package_Naming --
4439 --------------------------
4441 procedure Check_Package_Naming
4442 (Project : Project_Id;
4443 In_Tree : Project_Tree_Ref;
4444 Data : in out Project_Data)
4446 Naming_Id : constant Package_Id :=
4447 Util.Value_Of (Name_Naming, Data.Decl.Packages, In_Tree);
4449 Naming : Package_Element;
4452 -- If there is a package Naming, we will put in Data.Naming
4453 -- what is in this package Naming.
4455 if Naming_Id /= No_Package then
4456 Naming := In_Tree.Packages.Table (Naming_Id);
4458 if Current_Verbosity = High then
4459 Write_Line ("Checking ""Naming"".");
4462 -- Check Spec_Suffix
4465 Spec_Suffixs : Array_Element_Id :=
4471 Suffix : Array_Element_Id;
4472 Element : Array_Element;
4473 Suffix2 : Array_Element_Id;
4476 -- If some suffixes have been specified, we make sure that
4477 -- for each language for which a default suffix has been
4478 -- specified, there is a suffix specified, either the one
4479 -- in the project file or if there were none, the default.
4481 if Spec_Suffixs /= No_Array_Element then
4482 Suffix := Data.Naming.Spec_Suffix;
4484 while Suffix /= No_Array_Element loop
4486 In_Tree.Array_Elements.Table (Suffix);
4487 Suffix2 := Spec_Suffixs;
4489 while Suffix2 /= No_Array_Element loop
4490 exit when In_Tree.Array_Elements.Table
4491 (Suffix2).Index = Element.Index;
4492 Suffix2 := In_Tree.Array_Elements.Table
4496 -- There is a registered default suffix, but no
4497 -- suffix specified in the project file.
4498 -- Add the default to the array.
4500 if Suffix2 = No_Array_Element then
4501 Array_Element_Table.Increment_Last
4502 (In_Tree.Array_Elements);
4503 In_Tree.Array_Elements.Table
4504 (Array_Element_Table.Last
4505 (In_Tree.Array_Elements)) :=
4506 (Index => Element.Index,
4507 Src_Index => Element.Src_Index,
4508 Index_Case_Sensitive => False,
4509 Value => Element.Value,
4510 Next => Spec_Suffixs);
4511 Spec_Suffixs := Array_Element_Table.Last
4512 (In_Tree.Array_Elements);
4515 Suffix := Element.Next;
4518 -- Put the resulting array as the specification suffixes
4520 Data.Naming.Spec_Suffix := Spec_Suffixs;
4525 Current : Array_Element_Id;
4526 Element : Array_Element;
4529 Current := Data.Naming.Spec_Suffix;
4530 while Current /= No_Array_Element loop
4531 Element := In_Tree.Array_Elements.Table (Current);
4532 Get_Name_String (Element.Value.Value);
4534 if Name_Len = 0 then
4537 "Spec_Suffix cannot be empty",
4538 Element.Value.Location);
4541 In_Tree.Array_Elements.Table (Current) := Element;
4542 Current := Element.Next;
4546 -- Check Body_Suffix
4549 Impl_Suffixs : Array_Element_Id :=
4555 Suffix : Array_Element_Id;
4556 Element : Array_Element;
4557 Suffix2 : Array_Element_Id;
4560 -- If some suffixes have been specified, we make sure that
4561 -- for each language for which a default suffix has been
4562 -- specified, there is a suffix specified, either the one
4563 -- in the project file or if there were none, the default.
4565 if Impl_Suffixs /= No_Array_Element then
4566 Suffix := Data.Naming.Body_Suffix;
4567 while Suffix /= No_Array_Element loop
4569 In_Tree.Array_Elements.Table (Suffix);
4571 Suffix2 := Impl_Suffixs;
4572 while Suffix2 /= No_Array_Element loop
4573 exit when In_Tree.Array_Elements.Table
4574 (Suffix2).Index = Element.Index;
4575 Suffix2 := In_Tree.Array_Elements.Table
4579 -- There is a registered default suffix, but no suffix was
4580 -- specified in the project file. Add default to the array.
4582 if Suffix2 = No_Array_Element then
4583 Array_Element_Table.Increment_Last
4584 (In_Tree.Array_Elements);
4585 In_Tree.Array_Elements.Table
4586 (Array_Element_Table.Last
4587 (In_Tree.Array_Elements)) :=
4588 (Index => Element.Index,
4589 Src_Index => Element.Src_Index,
4590 Index_Case_Sensitive => False,
4591 Value => Element.Value,
4592 Next => Impl_Suffixs);
4593 Impl_Suffixs := Array_Element_Table.Last
4594 (In_Tree.Array_Elements);
4597 Suffix := Element.Next;
4600 -- Put the resulting array as the implementation suffixes
4602 Data.Naming.Body_Suffix := Impl_Suffixs;
4607 Current : Array_Element_Id;
4608 Element : Array_Element;
4611 Current := Data.Naming.Body_Suffix;
4612 while Current /= No_Array_Element loop
4613 Element := In_Tree.Array_Elements.Table (Current);
4614 Get_Name_String (Element.Value.Value);
4616 if Name_Len = 0 then
4619 "Body_Suffix cannot be empty",
4620 Element.Value.Location);
4623 In_Tree.Array_Elements.Table (Current) := Element;
4624 Current := Element.Next;
4628 -- Get the exceptions, if any
4630 Data.Naming.Specification_Exceptions :=
4632 (Name_Specification_Exceptions,
4633 In_Arrays => Naming.Decl.Arrays,
4634 In_Tree => In_Tree);
4636 Data.Naming.Implementation_Exceptions :=
4638 (Name_Implementation_Exceptions,
4639 In_Arrays => Naming.Decl.Arrays,
4640 In_Tree => In_Tree);
4642 end Check_Package_Naming;
4644 ---------------------------------
4645 -- Check_Programming_Languages --
4646 ---------------------------------
4648 procedure Check_Programming_Languages
4649 (In_Tree : Project_Tree_Ref;
4650 Project : Project_Id;
4651 Data : in out Project_Data)
4653 Languages : Variable_Value := Nil_Variable_Value;
4654 Def_Lang : Variable_Value := Nil_Variable_Value;
4655 Def_Lang_Id : Name_Id;
4658 Data.First_Language_Processing := No_Language_Index;
4660 Prj.Util.Value_Of (Name_Languages, Data.Decl.Attributes, In_Tree);
4663 (Name_Default_Language, Data.Decl.Attributes, In_Tree);
4664 Data.Ada_Sources_Present := Data.Source_Dirs /= Nil_String;
4665 Data.Other_Sources_Present := Data.Source_Dirs /= Nil_String;
4667 if Data.Source_Dirs /= Nil_String then
4669 -- Check if languages are specified in this project
4671 if Languages.Default then
4673 -- Attribute Languages is not specified. So, it defaults to
4674 -- a project of the default language only.
4676 Name_List_Table.Increment_Last (In_Tree.Name_Lists);
4677 Data.Languages := Name_List_Table.Last (In_Tree.Name_Lists);
4679 -- In Ada_Only mode, the default language is Ada
4681 if Get_Mode = Ada_Only then
4682 In_Tree.Name_Lists.Table (Data.Languages) :=
4683 (Name => Name_Ada, Next => No_Name_List);
4685 -- Attribute Languages is not specified. So, it defaults to
4686 -- a project of language Ada only.
4688 Data.Langs (Ada_Language_Index) := True;
4690 -- No sources of languages other than Ada
4692 Data.Other_Sources_Present := False;
4695 -- Fail if there is no default language defined
4697 if Def_Lang.Default then
4698 if not Default_Language_Is_Ada then
4702 "no languages defined for this project",
4704 Def_Lang_Id := No_Name;
4706 Def_Lang_Id := Name_Ada;
4710 Get_Name_String (Def_Lang.Value);
4711 To_Lower (Name_Buffer (1 .. Name_Len));
4712 Def_Lang_Id := Name_Find;
4715 if Def_Lang_Id /= No_Name then
4716 In_Tree.Name_Lists.Table (Data.Languages) :=
4717 (Name => Def_Lang_Id, Next => No_Name_List);
4719 Language_Data_Table.Increment_Last (In_Tree.Languages_Data);
4721 Data.First_Language_Processing :=
4722 Language_Data_Table.Last (In_Tree.Languages_Data);
4723 In_Tree.Languages_Data.Table
4724 (Data.First_Language_Processing) := No_Language_Data;
4725 In_Tree.Languages_Data.Table
4726 (Data.First_Language_Processing).Name := Def_Lang_Id;
4727 Get_Name_String (Def_Lang_Id);
4728 Name_Buffer (1) := GNAT.Case_Util.To_Upper (Name_Buffer (1));
4729 In_Tree.Languages_Data.Table
4730 (Data.First_Language_Processing).Display_Name := Name_Find;
4732 if Def_Lang_Id = Name_Ada then
4733 In_Tree.Languages_Data.Table
4734 (Data.First_Language_Processing).Config.Kind
4736 In_Tree.Languages_Data.Table
4737 (Data.First_Language_Processing).Config.Dependency_Kind
4739 Data.Unit_Based_Language_Name := Name_Ada;
4740 Data.Unit_Based_Language_Index :=
4741 Data.First_Language_Processing;
4743 In_Tree.Languages_Data.Table
4744 (Data.First_Language_Processing).Config.Kind
4752 Current : String_List_Id := Languages.Values;
4753 Element : String_Element;
4754 Lang_Name : Name_Id;
4755 Index : Language_Index;
4756 Lang_Data : Language_Data;
4757 NL_Id : Name_List_Index := No_Name_List;
4760 if Get_Mode = Ada_Only then
4762 -- Assume that there is no language specified yet
4764 Data.Other_Sources_Present := False;
4765 Data.Ada_Sources_Present := False;
4768 -- If there are no languages declared, there are no sources
4770 if Current = Nil_String then
4771 Data.Source_Dirs := Nil_String;
4773 if Data.Qualifier = Standard then
4777 "a standard project cannot have no language declared",
4778 Languages.Location);
4782 -- Look through all the languages specified in attribute
4785 while Current /= Nil_String loop
4787 In_Tree.String_Elements.Table (Current);
4788 Get_Name_String (Element.Value);
4789 To_Lower (Name_Buffer (1 .. Name_Len));
4790 Lang_Name := Name_Find;
4792 NL_Id := Data.Languages;
4793 while NL_Id /= No_Name_List loop
4795 Lang_Name = In_Tree.Name_Lists.Table (NL_Id).Name;
4796 NL_Id := In_Tree.Name_Lists.Table (NL_Id).Next;
4799 if NL_Id = No_Name_List then
4800 Name_List_Table.Increment_Last (In_Tree.Name_Lists);
4802 if Data.Languages = No_Name_List then
4804 Name_List_Table.Last (In_Tree.Name_Lists);
4807 NL_Id := Data.Languages;
4808 while In_Tree.Name_Lists.Table (NL_Id).Next /=
4811 NL_Id := In_Tree.Name_Lists.Table (NL_Id).Next;
4814 In_Tree.Name_Lists.Table (NL_Id).Next :=
4815 Name_List_Table.Last (In_Tree.Name_Lists);
4818 NL_Id := Name_List_Table.Last (In_Tree.Name_Lists);
4819 In_Tree.Name_Lists.Table (NL_Id) :=
4820 (Lang_Name, No_Name_List);
4822 if Get_Mode = Ada_Only then
4823 Index := Language_Indexes.Get (Lang_Name);
4825 if Index = No_Language_Index then
4826 Add_Language_Name (Lang_Name);
4827 Index := Last_Language_Index;
4830 Set (Index, True, Data, In_Tree);
4831 Set (Language_Processing =>
4832 Default_Language_Processing_Data,
4833 For_Language => Index,
4835 In_Tree => In_Tree);
4837 if Index = Ada_Language_Index then
4838 Data.Ada_Sources_Present := True;
4841 Data.Other_Sources_Present := True;
4845 Language_Data_Table.Increment_Last
4846 (In_Tree.Languages_Data);
4848 Language_Data_Table.Last (In_Tree.Languages_Data);
4849 Lang_Data.Name := Lang_Name;
4850 Lang_Data.Display_Name := Element.Value;
4851 Lang_Data.Next := Data.First_Language_Processing;
4853 if Lang_Name = Name_Ada then
4854 Lang_Data.Config.Kind := Unit_Based;
4855 Lang_Data.Config.Dependency_Kind := ALI_File;
4856 Data.Unit_Based_Language_Name := Name_Ada;
4857 Data.Unit_Based_Language_Index := Index;
4860 Lang_Data.Config.Kind := File_Based;
4861 Lang_Data.Config.Dependency_Kind := None;
4864 In_Tree.Languages_Data.Table (Index) := Lang_Data;
4865 Data.First_Language_Processing := Index;
4869 Current := Element.Next;
4875 end Check_Programming_Languages;
4881 function Check_Project
4883 Root_Project : Project_Id;
4884 In_Tree : Project_Tree_Ref;
4885 Extending : Boolean) return Boolean
4888 if P = Root_Project then
4891 elsif Extending then
4893 Data : Project_Data := In_Tree.Projects.Table (Root_Project);
4896 while Data.Extends /= No_Project loop
4897 if P = Data.Extends then
4901 Data := In_Tree.Projects.Table (Data.Extends);
4909 -------------------------------
4910 -- Check_Stand_Alone_Library --
4911 -------------------------------
4913 procedure Check_Stand_Alone_Library
4914 (Project : Project_Id;
4915 In_Tree : Project_Tree_Ref;
4916 Data : in out Project_Data;
4917 Current_Dir : String;
4918 Extending : Boolean)
4920 Lib_Interfaces : constant Prj.Variable_Value :=
4922 (Snames.Name_Library_Interface,
4923 Data.Decl.Attributes,
4926 Lib_Auto_Init : constant Prj.Variable_Value :=
4928 (Snames.Name_Library_Auto_Init,
4929 Data.Decl.Attributes,
4932 Lib_Src_Dir : constant Prj.Variable_Value :=
4934 (Snames.Name_Library_Src_Dir,
4935 Data.Decl.Attributes,
4938 Lib_Symbol_File : constant Prj.Variable_Value :=
4940 (Snames.Name_Library_Symbol_File,
4941 Data.Decl.Attributes,
4944 Lib_Symbol_Policy : constant Prj.Variable_Value :=
4946 (Snames.Name_Library_Symbol_Policy,
4947 Data.Decl.Attributes,
4950 Lib_Ref_Symbol_File : constant Prj.Variable_Value :=
4952 (Snames.Name_Library_Reference_Symbol_File,
4953 Data.Decl.Attributes,
4956 Auto_Init_Supported : Boolean;
4957 OK : Boolean := True;
4959 Next_Proj : Project_Id;
4962 if Get_Mode = Multi_Language then
4963 Auto_Init_Supported := Data.Config.Auto_Init_Supported;
4965 Auto_Init_Supported :=
4966 MLib.Tgt.Standalone_Library_Auto_Init_Is_Supported;
4969 pragma Assert (Lib_Interfaces.Kind = List);
4971 -- It is a stand-alone library project file if attribute
4972 -- Library_Interface is defined.
4974 if not Lib_Interfaces.Default then
4975 SAL_Library : declare
4976 Interfaces : String_List_Id := Lib_Interfaces.Values;
4977 Interface_ALIs : String_List_Id := Nil_String;
4979 The_Unit_Id : Unit_Index;
4980 The_Unit_Data : Unit_Data;
4982 procedure Add_ALI_For (Source : File_Name_Type);
4983 -- Add an ALI file name to the list of Interface ALIs
4989 procedure Add_ALI_For (Source : File_Name_Type) is
4991 Get_Name_String (Source);
4994 ALI : constant String :=
4995 ALI_File_Name (Name_Buffer (1 .. Name_Len));
4996 ALI_Name_Id : Name_Id;
4999 Name_Len := ALI'Length;
5000 Name_Buffer (1 .. Name_Len) := ALI;
5001 ALI_Name_Id := Name_Find;
5003 String_Element_Table.Increment_Last
5004 (In_Tree.String_Elements);
5005 In_Tree.String_Elements.Table
5006 (String_Element_Table.Last
5007 (In_Tree.String_Elements)) :=
5008 (Value => ALI_Name_Id,
5010 Display_Value => ALI_Name_Id,
5012 In_Tree.String_Elements.Table
5013 (Interfaces).Location,
5015 Next => Interface_ALIs);
5016 Interface_ALIs := String_Element_Table.Last
5017 (In_Tree.String_Elements);
5021 -- Start of processing for SAL_Library
5024 Data.Standalone_Library := True;
5026 -- Library_Interface cannot be an empty list
5028 if Interfaces = Nil_String then
5031 "Library_Interface cannot be an empty list",
5032 Lib_Interfaces.Location);
5035 -- Process each unit name specified in the attribute
5036 -- Library_Interface.
5038 while Interfaces /= Nil_String loop
5040 (In_Tree.String_Elements.Table (Interfaces).Value);
5041 To_Lower (Name_Buffer (1 .. Name_Len));
5043 if Name_Len = 0 then
5046 "an interface cannot be an empty string",
5047 In_Tree.String_Elements.Table (Interfaces).Location);
5051 Error_Msg_Name_1 := Unit;
5053 if Get_Mode = Ada_Only then
5055 Units_Htable.Get (In_Tree.Units_HT, Unit);
5057 if The_Unit_Id = No_Unit_Index then
5061 In_Tree.String_Elements.Table
5062 (Interfaces).Location);
5065 -- Check that the unit is part of the project
5068 In_Tree.Units.Table (The_Unit_Id);
5070 if The_Unit_Data.File_Names (Body_Part).Name /= No_File
5071 and then The_Unit_Data.File_Names
5072 (Body_Part).Path.Name /= Slash
5075 (The_Unit_Data.File_Names (Body_Part).Project,
5076 Project, In_Tree, Extending)
5078 -- There is a body for this unit.
5079 -- If there is no spec, we need to check
5080 -- that it is not a subunit.
5082 if The_Unit_Data.File_Names
5083 (Specification).Name = No_File
5086 Src_Ind : Source_File_Index;
5089 Src_Ind := Sinput.P.Load_Project_File
5091 (The_Unit_Data.File_Names
5092 (Body_Part).Path.Name));
5094 if Sinput.P.Source_File_Is_Subunit
5099 "%% is a subunit; " &
5100 "it cannot be an interface",
5102 String_Elements.Table
5103 (Interfaces).Location);
5108 -- The unit is not a subunit, so we add
5109 -- to the Interface ALIs the ALI file
5110 -- corresponding to the body.
5113 (The_Unit_Data.File_Names (Body_Part).Name);
5118 "%% is not an unit of this project",
5119 In_Tree.String_Elements.Table
5120 (Interfaces).Location);
5123 elsif The_Unit_Data.File_Names
5124 (Specification).Name /= No_File
5125 and then The_Unit_Data.File_Names
5126 (Specification).Path.Name /= Slash
5127 and then Check_Project
5128 (The_Unit_Data.File_Names
5129 (Specification).Project,
5130 Project, In_Tree, Extending)
5133 -- The unit is part of the project, it has
5134 -- a spec, but no body. We add to the Interface
5135 -- ALIs the ALI file corresponding to the spec.
5138 (The_Unit_Data.File_Names (Specification).Name);
5143 "%% is not an unit of this project",
5144 In_Tree.String_Elements.Table
5145 (Interfaces).Location);
5150 -- Multi_Language mode
5152 Next_Proj := Data.Extends;
5153 Source := Data.First_Source;
5156 while Source /= No_Source and then
5157 In_Tree.Sources.Table (Source).Unit /= Unit
5160 In_Tree.Sources.Table (Source).Next_In_Project;
5163 exit when Source /= No_Source or else
5164 Next_Proj = No_Project;
5167 In_Tree.Projects.Table (Next_Proj).First_Source;
5169 In_Tree.Projects.Table (Next_Proj).Extends;
5172 if Source /= No_Source then
5173 if In_Tree.Sources.Table (Source).Kind = Sep then
5174 Source := No_Source;
5176 elsif In_Tree.Sources.Table (Source).Kind = Spec
5178 In_Tree.Sources.Table (Source).Other_Part /=
5181 Source := In_Tree.Sources.Table (Source).Other_Part;
5185 if Source /= No_Source then
5186 if In_Tree.Sources.Table (Source).Project /= Project
5190 In_Tree.Sources.Table (Source).Project,
5193 Source := No_Source;
5197 if Source = No_Source then
5200 "%% is not an unit of this project",
5201 In_Tree.String_Elements.Table
5202 (Interfaces).Location);
5205 if In_Tree.Sources.Table (Source).Kind = Spec and then
5206 In_Tree.Sources.Table (Source).Other_Part /=
5209 Source := In_Tree.Sources.Table (Source).Other_Part;
5212 String_Element_Table.Increment_Last
5213 (In_Tree.String_Elements);
5214 In_Tree.String_Elements.Table
5215 (String_Element_Table.Last
5216 (In_Tree.String_Elements)) :=
5218 Name_Id (In_Tree.Sources.Table (Source).Dep_Name),
5221 Name_Id (In_Tree.Sources.Table (Source).Dep_Name),
5223 In_Tree.String_Elements.Table
5224 (Interfaces).Location,
5226 Next => Interface_ALIs);
5227 Interface_ALIs := String_Element_Table.Last
5228 (In_Tree.String_Elements);
5236 In_Tree.String_Elements.Table (Interfaces).Next;
5239 -- Put the list of Interface ALIs in the project data
5241 Data.Lib_Interface_ALIs := Interface_ALIs;
5243 -- Check value of attribute Library_Auto_Init and set
5244 -- Lib_Auto_Init accordingly.
5246 if Lib_Auto_Init.Default then
5248 -- If no attribute Library_Auto_Init is declared, then set auto
5249 -- init only if it is supported.
5251 Data.Lib_Auto_Init := Auto_Init_Supported;
5254 Get_Name_String (Lib_Auto_Init.Value);
5255 To_Lower (Name_Buffer (1 .. Name_Len));
5257 if Name_Buffer (1 .. Name_Len) = "false" then
5258 Data.Lib_Auto_Init := False;
5260 elsif Name_Buffer (1 .. Name_Len) = "true" then
5261 if Auto_Init_Supported then
5262 Data.Lib_Auto_Init := True;
5265 -- Library_Auto_Init cannot be "true" if auto init is not
5270 "library auto init not supported " &
5272 Lib_Auto_Init.Location);
5278 "invalid value for attribute Library_Auto_Init",
5279 Lib_Auto_Init.Location);
5284 -- If attribute Library_Src_Dir is defined and not the empty string,
5285 -- check if the directory exist and is not the object directory or
5286 -- one of the source directories. This is the directory where copies
5287 -- of the interface sources will be copied. Note that this directory
5288 -- may be the library directory.
5290 if Lib_Src_Dir.Value /= Empty_String then
5292 Dir_Id : constant File_Name_Type :=
5293 File_Name_Type (Lib_Src_Dir.Value);
5300 Data.Directory.Display_Name,
5301 Data.Library_Src_Dir.Name,
5302 Data.Library_Src_Dir.Display_Name,
5303 Create => "library source copy",
5304 Current_Dir => Current_Dir,
5305 Location => Lib_Src_Dir.Location);
5307 -- If directory does not exist, report an error
5309 if Data.Library_Src_Dir = No_Path_Information then
5311 -- Get the absolute name of the library directory that does
5312 -- not exist, to report an error.
5315 Dir_Name : constant String :=
5316 Get_Name_String (Dir_Id);
5319 if Is_Absolute_Path (Dir_Name) then
5320 Err_Vars.Error_Msg_File_1 := Dir_Id;
5323 Get_Name_String (Data.Directory.Name);
5325 if Name_Buffer (Name_Len) /=
5328 Name_Len := Name_Len + 1;
5329 Name_Buffer (Name_Len) :=
5330 Directory_Separator;
5335 Name_Len + Dir_Name'Length) :=
5337 Name_Len := Name_Len + Dir_Name'Length;
5338 Err_Vars.Error_Msg_Name_1 := Name_Find;
5343 Error_Msg_File_1 := Dir_Id;
5346 "Directory { does not exist",
5347 Lib_Src_Dir.Location);
5350 -- Report error if it is the same as the object directory
5352 elsif Data.Library_Src_Dir = Data.Object_Directory then
5355 "directory to copy interfaces cannot be " &
5356 "the object directory",
5357 Lib_Src_Dir.Location);
5358 Data.Library_Src_Dir := No_Path_Information;
5362 Src_Dirs : String_List_Id;
5363 Src_Dir : String_Element;
5366 -- Interface copy directory cannot be one of the source
5367 -- directory of the current project.
5369 Src_Dirs := Data.Source_Dirs;
5370 while Src_Dirs /= Nil_String loop
5371 Src_Dir := In_Tree.String_Elements.Table (Src_Dirs);
5373 -- Report error if it is one of the source directories
5375 if Data.Library_Src_Dir.Name =
5376 Path_Name_Type (Src_Dir.Value)
5380 "directory to copy interfaces cannot " &
5381 "be one of the source directories",
5382 Lib_Src_Dir.Location);
5383 Data.Library_Src_Dir := No_Path_Information;
5387 Src_Dirs := Src_Dir.Next;
5390 if Data.Library_Src_Dir /= No_Path_Information then
5392 -- It cannot be a source directory of any other
5395 Project_Loop : for Pid in 1 ..
5396 Project_Table.Last (In_Tree.Projects)
5399 In_Tree.Projects.Table (Pid).Source_Dirs;
5400 Dir_Loop : while Src_Dirs /= Nil_String loop
5402 In_Tree.String_Elements.Table (Src_Dirs);
5404 -- Report error if it is one of the source
5407 if Data.Library_Src_Dir.Name =
5408 Path_Name_Type (Src_Dir.Value)
5411 File_Name_Type (Src_Dir.Value);
5413 In_Tree.Projects.Table (Pid).Name;
5416 "directory to copy interfaces cannot " &
5417 "be the same as source directory { of " &
5419 Lib_Src_Dir.Location);
5420 Data.Library_Src_Dir := No_Path_Information;
5424 Src_Dirs := Src_Dir.Next;
5426 end loop Project_Loop;
5430 -- In high verbosity, if there is a valid Library_Src_Dir,
5431 -- display its path name.
5433 if Data.Library_Src_Dir /= No_Path_Information
5434 and then Current_Verbosity = High
5436 Write_Str ("Directory to copy interfaces =""");
5437 Write_Str (Get_Name_String (Data.Library_Src_Dir.Name));
5444 -- Check the symbol related attributes
5446 -- First, the symbol policy
5448 if not Lib_Symbol_Policy.Default then
5450 Value : constant String :=
5452 (Get_Name_String (Lib_Symbol_Policy.Value));
5455 -- Symbol policy must hove one of a limited number of values
5457 if Value = "autonomous" or else Value = "default" then
5458 Data.Symbol_Data.Symbol_Policy := Autonomous;
5460 elsif Value = "compliant" then
5461 Data.Symbol_Data.Symbol_Policy := Compliant;
5463 elsif Value = "controlled" then
5464 Data.Symbol_Data.Symbol_Policy := Controlled;
5466 elsif Value = "restricted" then
5467 Data.Symbol_Data.Symbol_Policy := Restricted;
5469 elsif Value = "direct" then
5470 Data.Symbol_Data.Symbol_Policy := Direct;
5475 "illegal value for Library_Symbol_Policy",
5476 Lib_Symbol_Policy.Location);
5481 -- If attribute Library_Symbol_File is not specified, symbol policy
5482 -- cannot be Restricted.
5484 if Lib_Symbol_File.Default then
5485 if Data.Symbol_Data.Symbol_Policy = Restricted then
5488 "Library_Symbol_File needs to be defined when " &
5489 "symbol policy is Restricted",
5490 Lib_Symbol_Policy.Location);
5494 -- Library_Symbol_File is defined
5496 Data.Symbol_Data.Symbol_File :=
5497 Path_Name_Type (Lib_Symbol_File.Value);
5499 Get_Name_String (Lib_Symbol_File.Value);
5501 if Name_Len = 0 then
5504 "symbol file name cannot be an empty string",
5505 Lib_Symbol_File.Location);
5508 OK := not Is_Absolute_Path (Name_Buffer (1 .. Name_Len));
5511 for J in 1 .. Name_Len loop
5512 if Name_Buffer (J) = '/'
5513 or else Name_Buffer (J) = Directory_Separator
5522 Error_Msg_File_1 := File_Name_Type (Lib_Symbol_File.Value);
5525 "symbol file name { is illegal. " &
5526 "Name cannot include directory info.",
5527 Lib_Symbol_File.Location);
5532 -- If attribute Library_Reference_Symbol_File is not defined,
5533 -- symbol policy cannot be Compliant or Controlled.
5535 if Lib_Ref_Symbol_File.Default then
5536 if Data.Symbol_Data.Symbol_Policy = Compliant
5537 or else Data.Symbol_Data.Symbol_Policy = Controlled
5541 "a reference symbol file need to be defined",
5542 Lib_Symbol_Policy.Location);
5546 -- Library_Reference_Symbol_File is defined, check file exists
5548 Data.Symbol_Data.Reference :=
5549 Path_Name_Type (Lib_Ref_Symbol_File.Value);
5551 Get_Name_String (Lib_Ref_Symbol_File.Value);
5553 if Name_Len = 0 then
5556 "reference symbol file name cannot be an empty string",
5557 Lib_Symbol_File.Location);
5560 if not Is_Absolute_Path (Name_Buffer (1 .. Name_Len)) then
5562 Add_Str_To_Name_Buffer
5563 (Get_Name_String (Data.Directory.Name));
5564 Add_Char_To_Name_Buffer (Directory_Separator);
5565 Add_Str_To_Name_Buffer
5566 (Get_Name_String (Lib_Ref_Symbol_File.Value));
5567 Data.Symbol_Data.Reference := Name_Find;
5570 if not Is_Regular_File
5571 (Get_Name_String (Data.Symbol_Data.Reference))
5574 File_Name_Type (Lib_Ref_Symbol_File.Value);
5576 -- For controlled and direct symbol policies, it is an error
5577 -- if the reference symbol file does not exist. For other
5578 -- symbol policies, this is just a warning
5581 Data.Symbol_Data.Symbol_Policy /= Controlled
5582 and then Data.Symbol_Data.Symbol_Policy /= Direct;
5586 "<library reference symbol file { does not exist",
5587 Lib_Ref_Symbol_File.Location);
5589 -- In addition in the non-controlled case, if symbol policy
5590 -- is Compliant, it is changed to Autonomous, because there
5591 -- is no reference to check against, and we don't want to
5592 -- fail in this case.
5594 if Data.Symbol_Data.Symbol_Policy /= Controlled then
5595 if Data.Symbol_Data.Symbol_Policy = Compliant then
5596 Data.Symbol_Data.Symbol_Policy := Autonomous;
5601 -- If both the reference symbol file and the symbol file are
5602 -- defined, then check that they are not the same file.
5604 if Data.Symbol_Data.Symbol_File /= No_Path then
5605 Get_Name_String (Data.Symbol_Data.Symbol_File);
5607 if Name_Len > 0 then
5609 Symb_Path : constant String :=
5612 (Data.Object_Directory.Name) &
5613 Directory_Separator &
5614 Name_Buffer (1 .. Name_Len),
5615 Directory => Current_Dir,
5617 Opt.Follow_Links_For_Files);
5618 Ref_Path : constant String :=
5621 (Data.Symbol_Data.Reference),
5622 Directory => Current_Dir,
5624 Opt.Follow_Links_For_Files);
5626 if Symb_Path = Ref_Path then
5629 "library reference symbol file and library" &
5630 " symbol file cannot be the same file",
5631 Lib_Ref_Symbol_File.Location);
5639 end Check_Stand_Alone_Library;
5641 ----------------------------
5642 -- Compute_Directory_Last --
5643 ----------------------------
5645 function Compute_Directory_Last (Dir : String) return Natural is
5648 and then (Dir (Dir'Last - 1) = Directory_Separator
5649 or else Dir (Dir'Last - 1) = '/')
5651 return Dir'Last - 1;
5655 end Compute_Directory_Last;
5662 (Project : Project_Id;
5663 In_Tree : Project_Tree_Ref;
5665 Flag_Location : Source_Ptr)
5667 Real_Location : Source_Ptr := Flag_Location;
5668 Error_Buffer : String (1 .. 5_000);
5669 Error_Last : Natural := 0;
5670 Name_Number : Natural := 0;
5671 File_Number : Natural := 0;
5672 First : Positive := Msg'First;
5675 procedure Add (C : Character);
5676 -- Add a character to the buffer
5678 procedure Add (S : String);
5679 -- Add a string to the buffer
5682 -- Add a name to the buffer
5685 -- Add a file name to the buffer
5691 procedure Add (C : Character) is
5693 Error_Last := Error_Last + 1;
5694 Error_Buffer (Error_Last) := C;
5697 procedure Add (S : String) is
5699 Error_Buffer (Error_Last + 1 .. Error_Last + S'Length) := S;
5700 Error_Last := Error_Last + S'Length;
5707 procedure Add_File is
5708 File : File_Name_Type;
5712 File_Number := File_Number + 1;
5716 File := Err_Vars.Error_Msg_File_1;
5718 File := Err_Vars.Error_Msg_File_2;
5720 File := Err_Vars.Error_Msg_File_3;
5725 Get_Name_String (File);
5726 Add (Name_Buffer (1 .. Name_Len));
5734 procedure Add_Name is
5739 Name_Number := Name_Number + 1;
5743 Name := Err_Vars.Error_Msg_Name_1;
5745 Name := Err_Vars.Error_Msg_Name_2;
5747 Name := Err_Vars.Error_Msg_Name_3;
5752 Get_Name_String (Name);
5753 Add (Name_Buffer (1 .. Name_Len));
5757 -- Start of processing for Error_Msg
5760 -- If location of error is unknown, use the location of the project
5762 if Real_Location = No_Location then
5763 Real_Location := In_Tree.Projects.Table (Project).Location;
5766 if Error_Report = null then
5767 Prj.Err.Error_Msg (Msg, Real_Location);
5771 -- Ignore continuation character
5773 if Msg (First) = '\
' then
5777 -- Warning character is always the first one in this package
5778 -- this is an undocumented kludge???
5780 if Msg (First) = '?
' then
5784 elsif Msg (First) = '<' then
5787 if Err_Vars.Error_Msg_Warn then
5793 while Index <= Msg'Last loop
5794 if Msg (Index) = '{' then
5797 elsif Msg (Index) = '%' then
5798 if Index < Msg'Last and then Msg (Index + 1) = '%' then
5810 Error_Report (Error_Buffer (1 .. Error_Last), Project, In_Tree);
5813 ----------------------
5814 -- Find_Ada_Sources --
5815 ----------------------
5817 procedure Find_Ada_Sources
5818 (Project : Project_Id;
5819 In_Tree : Project_Tree_Ref;
5820 Data : in out Project_Data;
5821 Current_Dir : String)
5823 Source_Dir : String_List_Id := Data.Source_Dirs;
5824 Element : String_Element;
5826 Current_Source : String_List_Id := Nil_String;
5827 Source_Recorded : Boolean := False;
5830 if Current_Verbosity = High then
5831 Write_Line ("Looking for sources:");
5834 -- For each subdirectory
5836 while Source_Dir /= Nil_String loop
5838 Source_Recorded := False;
5839 Element := In_Tree.String_Elements.Table (Source_Dir);
5840 if Element.Value /= No_Name then
5841 Get_Name_String (Element.Display_Value);
5844 Source_Directory : constant String :=
5845 Name_Buffer (1 .. Name_Len) & Directory_Separator;
5846 Dir_Last : constant Natural :=
5847 Compute_Directory_Last (Source_Directory);
5850 if Current_Verbosity = High then
5851 Write_Str ("Source_Dir = ");
5852 Write_Line (Source_Directory);
5855 -- We look at every entry in the source directory
5858 Source_Directory (Source_Directory'First .. Dir_Last));
5861 Read (Dir, Name_Buffer, Name_Len);
5863 if Current_Verbosity = High then
5864 Write_Str (" Checking ");
5865 Write_Line (Name_Buffer (1 .. Name_Len));
5868 exit when Name_Len = 0;
5871 File_Name : constant File_Name_Type := Name_Find;
5873 -- ??? We could probably optimize the following call:
5874 -- we need to resolve links only once for the
5875 -- directory itself, and then do a single call to
5876 -- readlink() for each file. Unfortunately that would
5877 -- require a change in Normalize_Pathname so that it
5878 -- has the option of not resolving links for its
5879 -- Directory parameter, only for Name.
5881 Path : constant String :=
5883 (Name => Name_Buffer (1 .. Name_Len),
5886 (Source_Directory'First .. Dir_Last),
5888 Opt.Follow_Links_For_Files,
5889 Case_Sensitive => True);
5891 Path_Name : Path_Name_Type;
5894 Name_Len := Path'Length;
5895 Name_Buffer (1 .. Name_Len) := Path;
5896 Path_Name := Name_Find;
5898 -- We attempt to register it as a source. However,
5899 -- there is no error if the file does not contain a
5900 -- valid source. But there is an error if we have a
5901 -- duplicate unit name.
5904 (File_Name => File_Name,
5905 Path_Name => Path_Name,
5909 Location => No_Location,
5910 Current_Source => Current_Source,
5911 Source_Recorded => Source_Recorded,
5912 Current_Dir => Current_Dir);
5921 when Directory_Error =>
5925 if Source_Recorded then
5926 In_Tree.String_Elements.Table (Source_Dir).Flag :=
5930 Source_Dir := Element.Next;
5933 if Current_Verbosity = High then
5934 Write_Line ("end Looking for sources.");
5937 end Find_Ada_Sources;
5943 procedure Find_Sources
5944 (Project : Project_Id;
5945 In_Tree : Project_Tree_Ref;
5946 Data : in out Project_Data;
5947 For_Language : Language_Index;
5948 Current_Dir : String)
5950 Source_Dir : String_List_Id;
5951 Element : String_Element;
5953 Current_Source : String_List_Id := Nil_String;
5954 Source_Recorded : Boolean := False;
5957 if Current_Verbosity = High then
5958 Write_Line ("Looking for sources:");
5961 -- Loop through subdirectories
5963 Source_Dir := Data.Source_Dirs;
5964 while Source_Dir /= Nil_String loop
5966 Source_Recorded := False;
5967 Element := In_Tree.String_Elements.Table (Source_Dir);
5969 if Element.Value /= No_Name then
5970 Get_Name_String (Element.Display_Value);
5973 Source_Directory : constant String :=
5974 Name_Buffer (1 .. Name_Len) &
5975 Directory_Separator;
5977 Dir_Last : constant Natural :=
5978 Compute_Directory_Last (Source_Directory);
5981 if Current_Verbosity = High then
5982 Write_Str ("Source_Dir = ");
5983 Write_Line (Source_Directory);
5986 -- We look to every entry in the source directory
5988 Open (Dir, Source_Directory
5989 (Source_Directory'First .. Dir_Last));
5992 Read (Dir, Name_Buffer, Name_Len);
5994 if Current_Verbosity = High then
5995 Write_Str (" Checking ");
5996 Write_Line (Name_Buffer (1 .. Name_Len));
5999 exit when Name_Len = 0;
6002 File_Name : constant File_Name_Type := Name_Find;
6003 Path : constant String :=
6005 (Name => Name_Buffer (1 .. Name_Len),
6006 Directory => Source_Directory
6007 (Source_Directory'First .. Dir_Last),
6008 Resolve_Links => Opt.Follow_Links_For_Files,
6009 Case_Sensitive => True);
6010 Path_Name : Path_Name_Type;
6013 Name_Len := Path'Length;
6014 Name_Buffer (1 .. Name_Len) := Path;
6015 Path_Name := Name_Find;
6017 if For_Language = Ada_Language_Index then
6019 -- We attempt to register it as a source. However,
6020 -- there is no error if the file does not contain
6021 -- a valid source. But there is an error if we have
6022 -- a duplicate unit name.
6025 (File_Name => File_Name,
6026 Path_Name => Path_Name,
6030 Location => No_Location,
6031 Current_Source => Current_Source,
6032 Source_Recorded => Source_Recorded,
6033 Current_Dir => Current_Dir);
6037 (File_Name => File_Name,
6038 Path_Name => Path_Name,
6042 Location => No_Location,
6043 Language => For_Language,
6045 Body_Suffix_Of (For_Language, Data, In_Tree),
6046 Naming_Exception => False);
6056 when Directory_Error =>
6060 if Source_Recorded then
6061 In_Tree.String_Elements.Table (Source_Dir).Flag :=
6065 Source_Dir := Element.Next;
6068 if Current_Verbosity = High then
6069 Write_Line ("end Looking for sources.");
6072 if For_Language = Ada_Language_Index then
6074 -- If we have looked for sources and found none, then it is an error,
6075 -- except if it is an extending project. If a non extending project
6076 -- is not supposed to contain any source files, then never call
6079 if Current_Source /= Nil_String then
6080 Data.Ada_Sources_Present := True;
6082 elsif Data.Extends = No_Project then
6083 Report_No_Sources (Project, "Ada", In_Tree, Data.Location);
6088 --------------------------------
6089 -- Free_Ada_Naming_Exceptions --
6090 --------------------------------
6092 procedure Free_Ada_Naming_Exceptions is
6094 Ada_Naming_Exception_Table.Set_Last (0);
6095 Ada_Naming_Exceptions.Reset;
6096 Reverse_Ada_Naming_Exceptions.Reset;
6097 end Free_Ada_Naming_Exceptions;
6099 ---------------------
6100 -- Get_Directories --
6101 ---------------------
6103 procedure Get_Directories
6104 (Project : Project_Id;
6105 In_Tree : Project_Tree_Ref;
6106 Current_Dir : String;
6107 Data : in out Project_Data)
6109 Object_Dir : constant Variable_Value :=
6111 (Name_Object_Dir, Data.Decl.Attributes, In_Tree);
6113 Exec_Dir : constant Variable_Value :=
6115 (Name_Exec_Dir, Data.Decl.Attributes, In_Tree);
6117 Source_Dirs : constant Variable_Value :=
6119 (Name_Source_Dirs, Data.Decl.Attributes, In_Tree);
6121 Excluded_Source_Dirs : constant Variable_Value :=
6123 (Name_Excluded_Source_Dirs,
6124 Data.Decl.Attributes,
6127 Source_Files : constant Variable_Value :=
6129 (Name_Source_Files, Data.Decl.Attributes, In_Tree);
6131 Last_Source_Dir : String_List_Id := Nil_String;
6133 procedure Find_Source_Dirs
6134 (From : File_Name_Type;
6135 Location : Source_Ptr;
6136 Removed : Boolean := False);
6137 -- Find one or several source directories, and add (or remove, if
6138 -- Removed is True) them to list of source directories of the project.
6140 ----------------------
6141 -- Find_Source_Dirs --
6142 ----------------------
6144 procedure Find_Source_Dirs
6145 (From : File_Name_Type;
6146 Location : Source_Ptr;
6147 Removed : Boolean := False)
6149 Directory : constant String := Get_Name_String (From);
6150 Element : String_Element;
6152 procedure Recursive_Find_Dirs (Path : Name_Id);
6153 -- Find all the subdirectories (recursively) of Path and add them
6154 -- to the list of source directories of the project.
6156 -------------------------
6157 -- Recursive_Find_Dirs --
6158 -------------------------
6160 procedure Recursive_Find_Dirs (Path : Name_Id) is
6162 Name : String (1 .. 250);
6164 List : String_List_Id;
6165 Prev : String_List_Id;
6166 Element : String_Element;
6167 Found : Boolean := False;
6169 Non_Canonical_Path : Name_Id := No_Name;
6170 Canonical_Path : Name_Id := No_Name;
6172 The_Path : constant String :=
6174 (Get_Name_String (Path),
6175 Directory => Current_Dir,
6176 Resolve_Links => Opt.Follow_Links_For_Dirs) &
6177 Directory_Separator;
6179 The_Path_Last : constant Natural :=
6180 Compute_Directory_Last (The_Path);
6183 Name_Len := The_Path_Last - The_Path'First + 1;
6184 Name_Buffer (1 .. Name_Len) :=
6185 The_Path (The_Path'First .. The_Path_Last);
6186 Non_Canonical_Path := Name_Find;
6188 if Osint.File_Names_Case_Sensitive then
6189 Canonical_Path := Non_Canonical_Path;
6191 Get_Name_String (Non_Canonical_Path);
6192 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
6193 Canonical_Path := Name_Find;
6196 -- To avoid processing the same directory several times, check
6197 -- if the directory is already in Recursive_Dirs. If it is, then
6198 -- there is nothing to do, just return. If it is not, put it there
6199 -- and continue recursive processing.
6202 if Recursive_Dirs.Get (Canonical_Path) then
6205 Recursive_Dirs.Set (Canonical_Path, True);
6209 -- Check if directory is already in list
6211 List := Data.Source_Dirs;
6213 while List /= Nil_String loop
6214 Element := In_Tree.String_Elements.Table (List);
6216 if Element.Value /= No_Name then
6217 Found := Element.Value = Canonical_Path;
6222 List := Element.Next;
6225 -- If directory is not already in list, put it there
6227 if (not Removed) and (not Found) then
6228 if Current_Verbosity = High then
6230 Write_Line (The_Path (The_Path'First .. The_Path_Last));
6233 String_Element_Table.Increment_Last
6234 (In_Tree.String_Elements);
6236 (Value => Canonical_Path,
6237 Display_Value => Non_Canonical_Path,
6238 Location => No_Location,
6243 -- Case of first source directory
6245 if Last_Source_Dir = Nil_String then
6246 Data.Source_Dirs := String_Element_Table.Last
6247 (In_Tree.String_Elements);
6249 -- Here we already have source directories
6252 -- Link the previous last to the new one
6254 In_Tree.String_Elements.Table
6255 (Last_Source_Dir).Next :=
6256 String_Element_Table.Last
6257 (In_Tree.String_Elements);
6260 -- And register this source directory as the new last
6262 Last_Source_Dir := String_Element_Table.Last
6263 (In_Tree.String_Elements);
6264 In_Tree.String_Elements.Table (Last_Source_Dir) :=
6267 elsif Removed and Found then
6268 if Prev = Nil_String then
6270 In_Tree.String_Elements.Table (List).Next;
6272 In_Tree.String_Elements.Table (Prev).Next :=
6273 In_Tree.String_Elements.Table (List).Next;
6277 -- Now look for subdirectories. We do that even when this
6278 -- directory is already in the list, because some of its
6279 -- subdirectories may not be in the list yet.
6281 Open (Dir, The_Path (The_Path'First .. The_Path_Last));
6284 Read (Dir, Name, Last);
6287 if Name (1 .. Last) /= "."
6288 and then Name (1 .. Last) /= ".."
6290 -- Avoid . and .. directories
6292 if Current_Verbosity = High then
6293 Write_Str (" Checking ");
6294 Write_Line (Name (1 .. Last));
6298 Path_Name : constant String :=
6300 (Name => Name (1 .. Last),
6302 The_Path (The_Path'First .. The_Path_Last),
6303 Resolve_Links => Opt.Follow_Links_For_Dirs,
6304 Case_Sensitive => True);
6307 if Is_Directory (Path_Name) then
6308 -- We have found a new subdirectory, call self
6310 Name_Len := Path_Name'Length;
6311 Name_Buffer (1 .. Name_Len) := Path_Name;
6312 Recursive_Find_Dirs (Name_Find);
6321 when Directory_Error =>
6323 end Recursive_Find_Dirs;
6325 -- Start of processing for Find_Source_Dirs
6328 if Current_Verbosity = High and then not Removed then
6329 Write_Str ("Find_Source_Dirs (""");
6330 Write_Str (Directory);
6334 -- First, check if we are looking for a directory tree, indicated
6335 -- by "/**" at the end.
6337 if Directory'Length >= 3
6338 and then Directory (Directory'Last - 1 .. Directory'Last) = "**"
6339 and then (Directory (Directory'Last - 2) = '/'
6341 Directory (Directory'Last - 2) = Directory_Separator)
6344 Data.Known_Order_Of_Source_Dirs := False;
6347 Name_Len := Directory'Length - 3;
6349 if Name_Len = 0 then
6351 -- Case of "/**": all directories in file system
6354 Name_Buffer (1) := Directory (Directory'First);
6357 Name_Buffer (1 .. Name_Len) :=
6358 Directory (Directory'First .. Directory'Last - 3);
6361 if Current_Verbosity = High then
6362 Write_Str ("Looking for all subdirectories of """);
6363 Write_Str (Name_Buffer (1 .. Name_Len));
6368 Base_Dir : constant File_Name_Type := Name_Find;
6369 Root_Dir : constant String :=
6371 (Name => Get_Name_String (Base_Dir),
6373 Get_Name_String (Data.Directory.Display_Name),
6374 Resolve_Links => False,
6375 Case_Sensitive => True);
6378 if Root_Dir'Length = 0 then
6379 Err_Vars.Error_Msg_File_1 := Base_Dir;
6381 if Location = No_Location then
6384 "{ is not a valid directory.",
6389 "{ is not a valid directory.",
6394 -- We have an existing directory, we register it and all of
6395 -- its subdirectories.
6397 if Current_Verbosity = High then
6398 Write_Line ("Looking for source directories:");
6401 Name_Len := Root_Dir'Length;
6402 Name_Buffer (1 .. Name_Len) := Root_Dir;
6403 Recursive_Find_Dirs (Name_Find);
6405 if Current_Verbosity = High then
6406 Write_Line ("End of looking for source directories.");
6411 -- We have a single directory
6415 Path_Name : Path_Name_Type;
6416 Display_Path_Name : Path_Name_Type;
6417 List : String_List_Id;
6418 Prev : String_List_Id;
6422 (Project => Project,
6425 Parent => Data.Directory.Display_Name,
6427 Display => Display_Path_Name,
6428 Current_Dir => Current_Dir);
6430 if Path_Name = No_Path then
6431 Err_Vars.Error_Msg_File_1 := From;
6433 if Location = No_Location then
6436 "{ is not a valid directory",
6441 "{ is not a valid directory",
6447 Path : constant String :=
6448 Get_Name_String (Path_Name) &
6449 Directory_Separator;
6450 Last_Path : constant Natural :=
6451 Compute_Directory_Last (Path);
6453 Display_Path : constant String :=
6455 (Display_Path_Name) &
6456 Directory_Separator;
6457 Last_Display_Path : constant Natural :=
6458 Compute_Directory_Last
6460 Display_Path_Id : Name_Id;
6464 Add_Str_To_Name_Buffer (Path (Path'First .. Last_Path));
6465 Path_Id := Name_Find;
6467 Add_Str_To_Name_Buffer
6469 (Display_Path'First .. Last_Display_Path));
6470 Display_Path_Id := Name_Find;
6474 -- As it is an existing directory, we add it to the
6475 -- list of directories.
6477 String_Element_Table.Increment_Last
6478 (In_Tree.String_Elements);
6482 Display_Value => Display_Path_Id,
6483 Location => No_Location,
6485 Next => Nil_String);
6487 if Last_Source_Dir = Nil_String then
6489 -- This is the first source directory
6491 Data.Source_Dirs := String_Element_Table.Last
6492 (In_Tree.String_Elements);
6495 -- We already have source directories, link the
6496 -- previous last to the new one.
6498 In_Tree.String_Elements.Table
6499 (Last_Source_Dir).Next :=
6500 String_Element_Table.Last
6501 (In_Tree.String_Elements);
6504 -- And register this source directory as the new last
6506 Last_Source_Dir := String_Element_Table.Last
6507 (In_Tree.String_Elements);
6508 In_Tree.String_Elements.Table
6509 (Last_Source_Dir) := Element;
6512 -- Remove source dir, if present
6514 List := Data.Source_Dirs;
6517 -- Look for source dir in current list
6519 while List /= Nil_String loop
6520 Element := In_Tree.String_Elements.Table (List);
6521 exit when Element.Value = Path_Id;
6523 List := Element.Next;
6526 if List /= Nil_String then
6527 -- Source dir was found, remove it from the list
6529 if Prev = Nil_String then
6531 In_Tree.String_Elements.Table (List).Next;
6534 In_Tree.String_Elements.Table (Prev).Next :=
6535 In_Tree.String_Elements.Table (List).Next;
6543 end Find_Source_Dirs;
6545 -- Start of processing for Get_Directories
6548 if Current_Verbosity = High then
6549 Write_Line ("Starting to look for directories");
6552 -- Check the object directory
6554 pragma Assert (Object_Dir.Kind = Single,
6555 "Object_Dir is not a single string");
6557 -- We set the object directory to its default
6559 Data.Object_Directory := Data.Directory;
6561 if Object_Dir.Value /= Empty_String then
6562 Get_Name_String (Object_Dir.Value);
6564 if Name_Len = 0 then
6567 "Object_Dir cannot be empty",
6568 Object_Dir.Location);
6571 -- We check that the specified object directory does exist
6576 File_Name_Type (Object_Dir.Value),
6577 Data.Directory.Display_Name,
6578 Data.Object_Directory.Name,
6579 Data.Object_Directory.Display_Name,
6581 Location => Object_Dir.Location,
6582 Current_Dir => Current_Dir);
6584 if Data.Object_Directory = No_Path_Information then
6586 -- The object directory does not exist, report an error if the
6587 -- project is not externally built.
6589 if not Data.Externally_Built then
6590 Err_Vars.Error_Msg_File_1 :=
6591 File_Name_Type (Object_Dir.Value);
6594 "the object directory { cannot be found",
6598 -- Do not keep a nil Object_Directory. Set it to the specified
6599 -- (relative or absolute) path. This is for the benefit of
6600 -- tools that recover from errors; for example, these tools
6601 -- could create the non existent directory.
6603 Data.Object_Directory.Display_Name :=
6604 Path_Name_Type (Object_Dir.Value);
6606 if Osint.File_Names_Case_Sensitive then
6607 Data.Object_Directory.Name :=
6608 Path_Name_Type (Object_Dir.Value);
6610 Get_Name_String (Object_Dir.Value);
6611 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
6612 Data.Object_Directory.Name := Name_Find;
6617 elsif Subdirs /= null then
6619 Name_Buffer (1) := '.';
6624 Data.Directory.Name,
6625 Data.Object_Directory.Name,
6626 Data.Object_Directory.Display_Name,
6628 Location => Object_Dir.Location,
6629 Current_Dir => Current_Dir);
6632 if Current_Verbosity = High then
6633 if Data.Object_Directory = No_Path_Information then
6634 Write_Line ("No object directory");
6636 Write_Str ("Object directory: """);
6637 Write_Str (Get_Name_String (Data.Object_Directory.Display_Name));
6642 -- Check the exec directory
6644 pragma Assert (Exec_Dir.Kind = Single,
6645 "Exec_Dir is not a single string");
6647 -- We set the object directory to its default
6649 Data.Exec_Directory := Data.Object_Directory;
6651 if Exec_Dir.Value /= Empty_String then
6652 Get_Name_String (Exec_Dir.Value);
6654 if Name_Len = 0 then
6657 "Exec_Dir cannot be empty",
6661 -- We check that the specified exec directory does exist
6666 File_Name_Type (Exec_Dir.Value),
6667 Data.Directory.Name,
6668 Data.Exec_Directory.Name,
6669 Data.Exec_Directory.Display_Name,
6671 Location => Exec_Dir.Location,
6672 Current_Dir => Current_Dir);
6674 if Data.Exec_Directory = No_Path_Information then
6675 Err_Vars.Error_Msg_File_1 := File_Name_Type (Exec_Dir.Value);
6678 "the exec directory { cannot be found",
6684 if Current_Verbosity = High then
6685 if Data.Exec_Directory = No_Path_Information then
6686 Write_Line ("No exec directory");
6688 Write_Str ("Exec directory: """);
6689 Write_Str (Get_Name_String (Data.Exec_Directory.Display_Name));
6694 -- Look for the source directories
6696 if Current_Verbosity = High then
6697 Write_Line ("Starting to look for source directories");
6700 pragma Assert (Source_Dirs.Kind = List, "Source_Dirs is not a list");
6702 if (not Source_Files.Default) and then
6703 Source_Files.Values = Nil_String
6705 Data.Source_Dirs := Nil_String;
6707 if Data.Qualifier = Standard then
6711 "a standard project cannot have no sources",
6712 Source_Files.Location);
6715 if Data.Extends = No_Project
6716 and then Data.Object_Directory = Data.Directory
6718 Data.Object_Directory := No_Path_Information;
6721 elsif Source_Dirs.Default then
6723 -- No Source_Dirs specified: the single source directory is the one
6724 -- containing the project file
6726 String_Element_Table.Increment_Last
6727 (In_Tree.String_Elements);
6728 Data.Source_Dirs := String_Element_Table.Last
6729 (In_Tree.String_Elements);
6730 In_Tree.String_Elements.Table (Data.Source_Dirs) :=
6731 (Value => Name_Id (Data.Directory.Name),
6732 Display_Value => Name_Id (Data.Directory.Display_Name),
6733 Location => No_Location,
6738 if Current_Verbosity = High then
6739 Write_Line ("Single source directory:");
6741 Write_Str (Get_Name_String (Data.Directory.Display_Name));
6745 elsif Source_Dirs.Values = Nil_String then
6746 if Data.Qualifier = Standard then
6750 "a standard project cannot have no source directories",
6751 Source_Dirs.Location);
6754 -- If Source_Dirs is an empty string list, this means that this
6755 -- project contains no source. For projects that don't extend other
6756 -- projects, this also means that there is no need for an object
6757 -- directory, if not specified.
6759 if Data.Extends = No_Project
6760 and then Data.Object_Directory = Data.Directory
6762 Data.Object_Directory := No_Path_Information;
6765 Data.Source_Dirs := Nil_String;
6769 Source_Dir : String_List_Id;
6770 Element : String_Element;
6773 -- Process the source directories for each element of the list
6775 Source_Dir := Source_Dirs.Values;
6776 while Source_Dir /= Nil_String loop
6778 In_Tree.String_Elements.Table (Source_Dir);
6780 (File_Name_Type (Element.Value), Element.Location);
6781 Source_Dir := Element.Next;
6786 if not Excluded_Source_Dirs.Default
6787 and then Excluded_Source_Dirs.Values /= Nil_String
6790 Source_Dir : String_List_Id;
6791 Element : String_Element;
6794 -- Process the source directories for each element of the list
6796 Source_Dir := Excluded_Source_Dirs.Values;
6797 while Source_Dir /= Nil_String loop
6799 In_Tree.String_Elements.Table (Source_Dir);
6801 (File_Name_Type (Element.Value),
6804 Source_Dir := Element.Next;
6809 if Current_Verbosity = High then
6810 Write_Line ("Putting source directories in canonical cases");
6814 Current : String_List_Id := Data.Source_Dirs;
6815 Element : String_Element;
6818 while Current /= Nil_String loop
6819 Element := In_Tree.String_Elements.Table (Current);
6820 if Element.Value /= No_Name then
6821 if not Osint.File_Names_Case_Sensitive then
6822 Get_Name_String (Element.Value);
6823 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
6824 Element.Value := Name_Find;
6827 In_Tree.String_Elements.Table (Current) := Element;
6830 Current := Element.Next;
6834 end Get_Directories;
6841 (Project : Project_Id;
6842 In_Tree : Project_Tree_Ref;
6843 Data : in out Project_Data)
6845 Mains : constant Variable_Value :=
6846 Prj.Util.Value_Of (Name_Main, Data.Decl.Attributes, In_Tree);
6849 Data.Mains := Mains.Values;
6851 -- If no Mains were specified, and if we are an extending project,
6852 -- inherit the Mains from the project we are extending.
6854 if Mains.Default then
6855 if not Data.Library and then Data.Extends /= No_Project then
6857 In_Tree.Projects.Table (Data.Extends).Mains;
6860 -- In a library project file, Main cannot be specified
6862 elsif Data.Library then
6865 "a library project file cannot have Main specified",
6870 ---------------------------
6871 -- Get_Sources_From_File --
6872 ---------------------------
6874 procedure Get_Sources_From_File
6876 Location : Source_Ptr;
6877 Project : Project_Id;
6878 In_Tree : Project_Tree_Ref)
6880 File : Prj.Util.Text_File;
6881 Line : String (1 .. 250);
6883 Source_Name : File_Name_Type;
6884 Name_Loc : Name_Location;
6887 if Get_Mode = Ada_Only then
6891 if Current_Verbosity = High then
6892 Write_Str ("Opening """);
6899 Prj.Util.Open (File, Path);
6901 if not Prj.Util.Is_Valid (File) then
6902 Error_Msg (Project, In_Tree, "file does not exist", Location);
6904 -- Read the lines one by one
6906 while not Prj.Util.End_Of_File (File) loop
6907 Prj.Util.Get_Line (File, Line, Last);
6909 -- A non empty, non comment line should contain a file name
6912 and then (Last = 1 or else Line (1 .. 2) /= "--")
6915 Name_Buffer (1 .. Name_Len) := Line (1 .. Last);
6916 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
6917 Source_Name := Name_Find;
6919 -- Check that there is no directory information
6921 for J in 1 .. Last loop
6922 if Line (J) = '/' or else Line (J) = Directory_Separator then
6923 Error_Msg_File_1 := Source_Name;
6927 "file name cannot include directory information ({)",
6933 Name_Loc := Source_Names.Get (Source_Name);
6935 if Name_Loc = No_Name_Location then
6937 (Name => Source_Name,
6938 Location => Location,
6939 Source => No_Source,
6944 Source_Names.Set (Source_Name, Name_Loc);
6948 Prj.Util.Close (File);
6951 end Get_Sources_From_File;
6958 (In_Tree : Project_Tree_Ref;
6959 Canonical_File_Name : File_Name_Type;
6960 Naming : Naming_Data;
6961 Exception_Id : out Ada_Naming_Exception_Id;
6962 Unit_Name : out Name_Id;
6963 Unit_Kind : out Spec_Or_Body;
6964 Needs_Pragma : out Boolean)
6966 Info_Id : Ada_Naming_Exception_Id :=
6967 Ada_Naming_Exceptions.Get (Canonical_File_Name);
6968 VMS_Name : File_Name_Type;
6971 if Info_Id = No_Ada_Naming_Exception then
6972 if Hostparm.OpenVMS then
6973 VMS_Name := Canonical_File_Name;
6974 Get_Name_String (VMS_Name);
6976 if Name_Buffer (Name_Len) = '.' then
6977 Name_Len := Name_Len - 1;
6978 VMS_Name := Name_Find;
6981 Info_Id := Ada_Naming_Exceptions.Get (VMS_Name);
6986 if Info_Id /= No_Ada_Naming_Exception then
6987 Exception_Id := Info_Id;
6988 Unit_Name := No_Name;
6989 Unit_Kind := Specification;
6990 Needs_Pragma := True;
6994 Needs_Pragma := False;
6995 Exception_Id := No_Ada_Naming_Exception;
6997 Get_Name_String (Canonical_File_Name);
6999 -- How about some comments and a name for this declare block ???
7000 -- In fact the whole code below needs more comments ???
7003 File : String := Name_Buffer (1 .. Name_Len);
7004 First : constant Positive := File'First;
7005 Last : Natural := File'Last;
7006 Standard_GNAT : Boolean;
7007 Spec : constant File_Name_Type :=
7008 Spec_Suffix_Id_Of (In_Tree, Name_Ada, Naming);
7009 Body_Suff : constant File_Name_Type :=
7010 Body_Suffix_Id_Of (In_Tree, Name_Ada, Naming);
7013 Standard_GNAT := Spec = Default_Ada_Spec_Suffix
7014 and then Body_Suff = Default_Ada_Body_Suffix;
7017 Spec_Suffix : constant String := Get_Name_String (Spec);
7018 Body_Suffix : constant String := Get_Name_String (Body_Suff);
7019 Sep_Suffix : constant String :=
7020 Get_Name_String (Naming.Separate_Suffix);
7022 May_Be_Spec : Boolean;
7023 May_Be_Body : Boolean;
7024 May_Be_Sep : Boolean;
7028 File'Length > Spec_Suffix'Length
7030 File (Last - Spec_Suffix'Length + 1 .. Last) = Spec_Suffix;
7033 File'Length > Body_Suffix'Length
7035 File (Last - Body_Suffix'Length + 1 .. Last) = Body_Suffix;
7038 File'Length > Sep_Suffix'Length
7040 File (Last - Sep_Suffix'Length + 1 .. Last) = Sep_Suffix;
7042 -- If two May_Be_ booleans are True, always choose the longer one
7045 if May_Be_Body and then
7046 Spec_Suffix'Length < Body_Suffix'Length
7048 Unit_Kind := Body_Part;
7050 if May_Be_Sep and then
7051 Body_Suffix'Length < Sep_Suffix'Length
7053 Last := Last - Sep_Suffix'Length;
7054 May_Be_Body := False;
7057 Last := Last - Body_Suffix'Length;
7058 May_Be_Sep := False;
7061 elsif May_Be_Sep and then
7062 Spec_Suffix'Length < Sep_Suffix'Length
7064 Unit_Kind := Body_Part;
7065 Last := Last - Sep_Suffix'Length;
7068 Unit_Kind := Specification;
7069 Last := Last - Spec_Suffix'Length;
7072 elsif May_Be_Body then
7073 Unit_Kind := Body_Part;
7075 if May_Be_Sep and then
7076 Body_Suffix'Length < Sep_Suffix'Length
7078 Last := Last - Sep_Suffix'Length;
7079 May_Be_Body := False;
7081 Last := Last - Body_Suffix'Length;
7082 May_Be_Sep := False;
7085 elsif May_Be_Sep then
7086 Unit_Kind := Body_Part;
7087 Last := Last - Sep_Suffix'Length;
7095 -- This is not a source file
7097 Unit_Name := No_Name;
7098 Unit_Kind := Specification;
7100 if Current_Verbosity = High then
7101 Write_Line (" Not a valid file name.");
7106 elsif Current_Verbosity = High then
7108 when Specification =>
7109 Write_Str (" Specification: ");
7110 Write_Line (File (First .. Last + Spec_Suffix'Length));
7114 Write_Str (" Body: ");
7115 Write_Line (File (First .. Last + Body_Suffix'Length));
7118 Write_Str (" Separate: ");
7119 Write_Line (File (First .. Last + Sep_Suffix'Length));
7125 Get_Name_String (Naming.Dot_Replacement);
7127 Standard_GNAT and then Name_Buffer (1 .. Name_Len) = "-";
7129 if Name_Buffer (1 .. Name_Len) /= "." then
7131 -- If Dot_Replacement is not a single dot, then there should not
7132 -- be any dot in the name.
7134 for Index in First .. Last loop
7135 if File (Index) = '.' then
7136 if Current_Verbosity = High then
7138 (" Not a valid file name (some dot not replaced).");
7141 Unit_Name := No_Name;
7147 -- Replace the substring Dot_Replacement with dots
7150 Index : Positive := First;
7153 while Index <= Last - Name_Len + 1 loop
7155 if File (Index .. Index + Name_Len - 1) =
7156 Name_Buffer (1 .. Name_Len)
7158 File (Index) := '.';
7160 if Name_Len > 1 and then Index < Last then
7161 File (Index + 1 .. Last - Name_Len + 1) :=
7162 File (Index + Name_Len .. Last);
7165 Last := Last - Name_Len + 1;
7173 -- Check if the casing is right
7176 Src : String := File (First .. Last);
7177 Src_Last : Positive := Last;
7180 case Naming.Casing is
7181 when All_Lower_Case =>
7184 Mapping => Lower_Case_Map);
7186 when All_Upper_Case =>
7189 Mapping => Upper_Case_Map);
7191 when Mixed_Case | Unknown =>
7195 if Src /= File (First .. Last) then
7196 if Current_Verbosity = High then
7197 Write_Line (" Not a valid file name (casing).");
7200 Unit_Name := No_Name;
7204 -- We put the name in lower case
7208 Mapping => Lower_Case_Map);
7210 -- In the standard GNAT naming scheme, check for special cases:
7211 -- children or separates of A, G, I or S, and run time sources.
7213 if Standard_GNAT and then Src'Length >= 3 then
7215 S1 : constant Character := Src (Src'First);
7216 S2 : constant Character := Src (Src'First + 1);
7217 S3 : constant Character := Src (Src'First + 2);
7225 -- Children or separates of packages A, G, I or S. These
7226 -- names are x__ ... or x~... (where x is a, g, i, or s).
7227 -- Both versions (x__... and x~...) are allowed in all
7228 -- platforms, because it is not possible to know the
7229 -- platform before processing of the project files.
7231 if S2 = '_
' and then S3 = '_
' then
7232 Src (Src'First + 1) := '.';
7233 Src_Last := Src_Last - 1;
7234 Src (Src'First + 2 .. Src_Last) :=
7235 Src (Src'First + 3 .. Src_Last + 1);
7238 Src (Src'First + 1) := '.';
7240 -- If it is potentially a run time source, disable
7241 -- filling of the mapping file to avoid warnings.
7244 Set_Mapping_File_Initial_State_To_Empty;
7250 if Current_Verbosity = High then
7252 Write_Line (Src (Src'First .. Src_Last));
7255 -- Now, we check if this name is a valid unit name
7258 (Name => Src (Src'First .. Src_Last), Unit => Unit_Name);
7268 function Hash (Unit : Unit_Info) return Header_Num is
7270 return Header_Num (Unit.Unit mod 2048);
7273 -----------------------
7274 -- Is_Illegal_Suffix --
7275 -----------------------
7277 function Is_Illegal_Suffix
7279 Dot_Replacement_Is_A_Single_Dot : Boolean) return Boolean
7282 if Suffix'Length = 0 or else Index (Suffix, ".") = 0 then
7286 -- If dot replacement is a single dot, and first character of suffix is
7289 if Dot_Replacement_Is_A_Single_Dot
7290 and then Suffix (Suffix'First) = '.'
7292 for Index in Suffix'First + 1 .. Suffix'Last loop
7294 -- If there is another dot
7296 if Suffix (Index) = '.' then
7298 -- It is illegal to have a letter following the initial dot
7300 return Is_Letter (Suffix (Suffix'First + 1));
7308 end Is_Illegal_Suffix;
7310 ----------------------
7311 -- Locate_Directory --
7312 ----------------------
7314 procedure Locate_Directory
7315 (Project : Project_Id;
7316 In_Tree : Project_Tree_Ref;
7317 Name : File_Name_Type;
7318 Parent : Path_Name_Type;
7319 Dir : out Path_Name_Type;
7320 Display : out Path_Name_Type;
7321 Create : String := "";
7322 Current_Dir : String;
7323 Location : Source_Ptr := No_Location)
7325 The_Parent : constant String :=
7326 Get_Name_String (Parent) & Directory_Separator;
7328 The_Parent_Last : constant Natural :=
7329 Compute_Directory_Last (The_Parent);
7331 Full_Name : File_Name_Type;
7333 The_Name : File_Name_Type;
7336 Get_Name_String (Name);
7338 -- Add Subdirs.all if it is a directory that may be created and
7339 -- Subdirs is not null;
7341 if Create /= "" and then Subdirs /= null then
7342 if Name_Buffer (Name_Len) /= Directory_Separator then
7343 Add_Char_To_Name_Buffer (Directory_Separator);
7346 Add_Str_To_Name_Buffer (Subdirs.all);
7349 -- Convert '/' to directory separator (for Windows)
7351 for J in 1 .. Name_Len loop
7352 if Name_Buffer (J) = '/' then
7353 Name_Buffer (J) := Directory_Separator;
7357 The_Name := Name_Find;
7359 if Current_Verbosity = High then
7360 Write_Str ("Locate_Directory (""");
7361 Write_Str (Get_Name_String (The_Name));
7362 Write_Str (""", """);
7363 Write_Str (The_Parent);
7370 if Is_Absolute_Path (Get_Name_String (The_Name)) then
7371 Full_Name := The_Name;
7375 Add_Str_To_Name_Buffer
7376 (The_Parent (The_Parent'First .. The_Parent_Last));
7377 Add_Str_To_Name_Buffer (Get_Name_String (The_Name));
7378 Full_Name := Name_Find;
7382 Full_Path_Name : constant String := Get_Name_String (Full_Name);
7385 if (Setup_Projects or else Subdirs /= null)
7386 and then Create'Length > 0
7387 and then not Is_Directory (Full_Path_Name)
7390 Create_Path (Full_Path_Name);
7392 if not Quiet_Output then
7394 Write_Str (" directory """);
7395 Write_Str (Full_Path_Name);
7396 Write_Line (""" created");
7403 "could not create " & Create &
7404 " directory " & Full_Path_Name,
7409 if Is_Directory (Full_Path_Name) then
7411 Normed : constant String :=
7414 Directory => Current_Dir,
7415 Resolve_Links => False,
7416 Case_Sensitive => True);
7418 Canonical_Path : constant String :=
7421 Directory => Current_Dir,
7423 Opt.Follow_Links_For_Dirs,
7424 Case_Sensitive => False);
7427 Name_Len := Normed'Length;
7428 Name_Buffer (1 .. Name_Len) := Normed;
7429 Display := Name_Find;
7431 Name_Len := Canonical_Path'Length;
7432 Name_Buffer (1 .. Name_Len) := Canonical_Path;
7437 end Locate_Directory;
7439 ---------------------------
7440 -- Find_Excluded_Sources --
7441 ---------------------------
7443 procedure Find_Excluded_Sources
7444 (Project : Project_Id;
7445 In_Tree : Project_Tree_Ref;
7446 Data : Project_Data)
7448 Excluded_Sources : Variable_Value;
7450 Excluded_Source_List_File : Variable_Value;
7452 Current : String_List_Id;
7454 Element : String_Element;
7456 Location : Source_Ptr;
7458 Name : File_Name_Type;
7460 File : Prj.Util.Text_File;
7461 Line : String (1 .. 300);
7464 Locally_Removed : Boolean := False;
7466 Excluded_Source_List_File :=
7468 (Name_Excluded_Source_List_File, Data.Decl.Attributes, In_Tree);
7472 (Name_Excluded_Source_Files, Data.Decl.Attributes, In_Tree);
7474 -- If Excluded_Source_Files is not declared, check
7475 -- Locally_Removed_Files.
7477 if Excluded_Sources.Default then
7478 Locally_Removed := True;
7481 (Name_Locally_Removed_Files, Data.Decl.Attributes, In_Tree);
7484 Excluded_Sources_Htable.Reset;
7486 -- If there are excluded sources, put them in the table
7488 if not Excluded_Sources.Default then
7489 if not Excluded_Source_List_File.Default then
7490 if Locally_Removed then
7493 "?both attributes Locally_Removed_Files and " &
7494 "Excluded_Source_List_File are present",
7495 Excluded_Source_List_File.Location);
7499 "?both attributes Excluded_Source_Files and " &
7500 "Excluded_Source_List_File are present",
7501 Excluded_Source_List_File.Location);
7505 Current := Excluded_Sources.Values;
7506 while Current /= Nil_String loop
7507 Element := In_Tree.String_Elements.Table (Current);
7509 if Osint.File_Names_Case_Sensitive then
7510 Name := File_Name_Type (Element.Value);
7512 Get_Name_String (Element.Value);
7513 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7517 -- If the element has no location, then use the location
7518 -- of Excluded_Sources to report possible errors.
7520 if Element.Location = No_Location then
7521 Location := Excluded_Sources.Location;
7523 Location := Element.Location;
7526 Excluded_Sources_Htable.Set (Name, (Name, False, Location));
7527 Current := Element.Next;
7530 elsif not Excluded_Source_List_File.Default then
7531 Location := Excluded_Source_List_File.Location;
7534 Source_File_Path_Name : constant String :=
7537 (Excluded_Source_List_File.Value),
7538 Data.Directory.Name);
7541 if Source_File_Path_Name'Length = 0 then
7542 Err_Vars.Error_Msg_File_1 :=
7543 File_Name_Type (Excluded_Source_List_File.Value);
7546 "file with excluded sources { does not exist",
7547 Excluded_Source_List_File.Location);
7552 Prj.Util.Open (File, Source_File_Path_Name);
7554 if not Prj.Util.Is_Valid (File) then
7556 (Project, In_Tree, "file does not exist", Location);
7558 -- Read the lines one by one
7560 while not Prj.Util.End_Of_File (File) loop
7561 Prj.Util.Get_Line (File, Line, Last);
7563 -- A non empty, non comment line should contain a file
7567 and then (Last = 1 or else Line (1 .. 2) /= "--")
7570 Name_Buffer (1 .. Name_Len) := Line (1 .. Last);
7571 Canonical_Case_File_Name
7572 (Name_Buffer (1 .. Name_Len));
7575 -- Check that there is no directory information
7577 for J in 1 .. Last loop
7579 or else Line (J) = Directory_Separator
7581 Error_Msg_File_1 := Name;
7585 "file name cannot include " &
7586 "directory information ({)",
7592 Excluded_Sources_Htable.Set
7593 (Name, (Name, False, Location));
7597 Prj.Util.Close (File);
7602 end Find_Excluded_Sources;
7604 ---------------------------
7605 -- Find_Explicit_Sources --
7606 ---------------------------
7608 procedure Find_Explicit_Sources
7609 (Lang : Language_Index;
7610 Current_Dir : String;
7611 Project : Project_Id;
7612 In_Tree : Project_Tree_Ref;
7613 Data : in out Project_Data)
7615 Sources : constant Variable_Value :=
7618 Data.Decl.Attributes,
7620 Source_List_File : constant Variable_Value :=
7622 (Name_Source_List_File,
7623 Data.Decl.Attributes,
7625 Name_Loc : Name_Location;
7628 pragma Assert (Sources.Kind = List, "Source_Files is not a list");
7630 (Source_List_File.Kind = Single,
7631 "Source_List_File is not a single string");
7633 -- If the user has specified a Sources attribute
7635 if not Sources.Default then
7636 if not Source_List_File.Default then
7639 "?both attributes source_files and " &
7640 "source_list_file are present",
7641 Source_List_File.Location);
7644 -- Sources is a list of file names
7647 Current : String_List_Id := Sources.Values;
7648 Element : String_Element;
7649 Location : Source_Ptr;
7650 Name : File_Name_Type;
7653 if Get_Mode = Ada_Only then
7654 Data.Ada_Sources_Present := Current /= Nil_String;
7657 -- If we are processing other languages in the case of gprmake,
7658 -- we should not reset the list of sources, which was already
7659 -- initialized for the Ada files.
7661 if Get_Mode /= Ada_Only or else Lang /= Ada_Language_Index then
7662 if Current = Nil_String then
7665 Data.Source_Dirs := Nil_String;
7666 when Multi_Language =>
7667 Data.First_Language_Processing := No_Language_Index;
7670 -- This project contains no source. For projects that
7671 -- don't extend other projects, this also means that
7672 -- there is no need for an object directory, if not
7675 if Data.Extends = No_Project
7676 and then Data.Object_Directory = Data.Directory
7678 Data.Object_Directory := No_Path_Information;
7683 while Current /= Nil_String loop
7684 Element := In_Tree.String_Elements.Table (Current);
7685 Get_Name_String (Element.Value);
7687 if Osint.File_Names_Case_Sensitive then
7688 Name := File_Name_Type (Element.Value);
7690 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
7694 -- If the element has no location, then use the
7695 -- location of Sources to report possible errors.
7697 if Element.Location = No_Location then
7698 Location := Sources.Location;
7700 Location := Element.Location;
7703 -- Check that there is no directory information
7705 for J in 1 .. Name_Len loop
7706 if Name_Buffer (J) = '/'
7707 or else Name_Buffer (J) = Directory_Separator
7709 Error_Msg_File_1 := Name;
7713 "file name cannot include directory " &
7720 -- In Multi_Language mode, check whether the file is
7721 -- already there: the same file name may be in the list; if
7722 -- the source is missing, the error will be on the first
7723 -- mention of the source file name.
7727 Name_Loc := No_Name_Location;
7728 when Multi_Language =>
7729 Name_Loc := Source_Names.Get (Name);
7732 if Name_Loc = No_Name_Location then
7735 Location => Location,
7736 Source => No_Source,
7739 Source_Names.Set (Name, Name_Loc);
7742 Current := Element.Next;
7745 if Get_Mode = Ada_Only then
7746 if Lang = Ada_Language_Index then
7747 Get_Path_Names_And_Record_Ada_Sources
7748 (Project, In_Tree, Data, Current_Dir);
7750 Record_Other_Sources
7751 (Project => Project,
7755 Naming_Exceptions => False);
7760 -- If we have no Source_Files attribute, check the Source_List_File
7763 elsif not Source_List_File.Default then
7765 -- Source_List_File is the name of the file
7766 -- that contains the source file names
7769 Source_File_Path_Name : constant String :=
7771 (File_Name_Type (Source_List_File.Value), Data.Directory.Name);
7774 if Source_File_Path_Name'Length = 0 then
7775 Err_Vars.Error_Msg_File_1 :=
7776 File_Name_Type (Source_List_File.Value);
7779 "file with sources { does not exist",
7780 Source_List_File.Location);
7783 Get_Sources_From_File
7784 (Source_File_Path_Name, Source_List_File.Location,
7787 if Get_Mode = Ada_Only then
7788 -- Look in the source directories to find those sources
7790 if Lang = Ada_Language_Index then
7791 Get_Path_Names_And_Record_Ada_Sources
7792 (Project, In_Tree, Data, Current_Dir);
7795 Record_Other_Sources
7796 (Project => Project,
7800 Naming_Exceptions => False);
7807 -- Neither Source_Files nor Source_List_File has been
7808 -- specified. Find all the files that satisfy the naming
7809 -- scheme in all the source directories.
7813 if Lang = Ada_Language_Index then
7814 Find_Ada_Sources (Project, In_Tree, Data, Current_Dir);
7816 -- Find all the files that satisfy the naming scheme in
7817 -- all the source directories. All the naming exceptions
7818 -- that effectively exist are also part of the source
7819 -- of this language.
7821 Find_Sources (Project, In_Tree, Data, Lang, Current_Dir);
7824 when Multi_Language =>
7829 if Get_Mode = Multi_Language then
7831 (Project, In_Tree, Data,
7833 Sources.Default and then Source_List_File.Default);
7835 -- Check if all exceptions have been found.
7836 -- For Ada, it is an error if an exception is not found.
7837 -- For other language, the source is simply removed.
7841 Src_Data : Source_Data;
7844 Source := Data.First_Source;
7845 while Source /= No_Source loop
7846 Src_Data := In_Tree.Sources.Table (Source);
7848 if Src_Data.Naming_Exception
7849 and then Src_Data.Path = No_Path_Information
7851 if Src_Data.Unit /= No_Name then
7852 Error_Msg_Name_1 := Name_Id (Src_Data.Display_File);
7853 Error_Msg_Name_2 := Name_Id (Src_Data.Unit);
7856 "source file %% for unit %% not found",
7860 Remove_Source (Source, No_Source, Project, Data, In_Tree);
7863 Source := Src_Data.Next_In_Project;
7867 -- Check that all sources in Source_Files or the file
7868 -- Source_List_File has been found.
7871 Name_Loc : Name_Location;
7874 Name_Loc := Source_Names.Get_First;
7875 while Name_Loc /= No_Name_Location loop
7876 if (not Name_Loc.Except) and then (not Name_Loc.Found) then
7877 Error_Msg_Name_1 := Name_Id (Name_Loc.Name);
7881 "file %% not found",
7885 Name_Loc := Source_Names.Get_Next;
7890 if Get_Mode = Ada_Only
7891 and then Lang = Ada_Language_Index
7892 and then Data.Extends = No_Project
7894 -- We should have found at least one source, if not report an error
7896 if Data.Ada_Sources = Nil_String then
7898 (Project, "Ada", In_Tree, Source_List_File.Location);
7902 end Find_Explicit_Sources;
7904 -------------------------------------------
7905 -- Get_Path_Names_And_Record_Ada_Sources --
7906 -------------------------------------------
7908 procedure Get_Path_Names_And_Record_Ada_Sources
7909 (Project : Project_Id;
7910 In_Tree : Project_Tree_Ref;
7911 Data : in out Project_Data;
7912 Current_Dir : String)
7914 Source_Dir : String_List_Id;
7915 Element : String_Element;
7916 Path : Path_Name_Type;
7918 Name : File_Name_Type;
7919 Canonical_Name : File_Name_Type;
7920 Name_Str : String (1 .. 1_024);
7921 Last : Natural := 0;
7923 Current_Source : String_List_Id := Nil_String;
7924 First_Error : Boolean := True;
7925 Source_Recorded : Boolean := False;
7928 -- We look in all source directories for the file names in the hash
7929 -- table Source_Names.
7931 Source_Dir := Data.Source_Dirs;
7932 while Source_Dir /= Nil_String loop
7933 Source_Recorded := False;
7934 Element := In_Tree.String_Elements.Table (Source_Dir);
7937 Dir_Path : constant String :=
7938 Get_Name_String (Element.Display_Value);
7940 if Current_Verbosity = High then
7941 Write_Str ("checking directory """);
7942 Write_Str (Dir_Path);
7946 Open (Dir, Dir_Path);
7949 Read (Dir, Name_Str, Last);
7953 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
7956 if Osint.File_Names_Case_Sensitive then
7957 Canonical_Name := Name;
7959 Canonical_Case_File_Name (Name_Str (1 .. Last));
7960 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
7961 Canonical_Name := Name_Find;
7964 NL := Source_Names.Get (Canonical_Name);
7966 if NL /= No_Name_Location and then not NL.Found then
7968 Source_Names.Set (Canonical_Name, NL);
7969 Name_Len := Dir_Path'Length;
7970 Name_Buffer (1 .. Name_Len) := Dir_Path;
7972 if Name_Buffer (Name_Len) /= Directory_Separator then
7973 Add_Char_To_Name_Buffer (Directory_Separator);
7976 Add_Str_To_Name_Buffer (Name_Str (1 .. Last));
7979 if Current_Verbosity = High then
7980 Write_Str (" found ");
7981 Write_Line (Get_Name_String (Name));
7984 -- Register the source if it is an Ada compilation unit
7992 Location => NL.Location,
7993 Current_Source => Current_Source,
7994 Source_Recorded => Source_Recorded,
7995 Current_Dir => Current_Dir);
8002 if Source_Recorded then
8003 In_Tree.String_Elements.Table (Source_Dir).Flag :=
8007 Source_Dir := Element.Next;
8010 -- It is an error if a source file name in a source list or
8011 -- in a source list file is not found.
8013 NL := Source_Names.Get_First;
8014 while NL /= No_Name_Location loop
8015 if not NL.Found then
8016 Err_Vars.Error_Msg_File_1 := NL.Name;
8021 "source file { cannot be found",
8023 First_Error := False;
8028 "\source file { cannot be found",
8033 NL := Source_Names.Get_Next;
8035 end Get_Path_Names_And_Record_Ada_Sources;
8037 --------------------------
8038 -- Check_Naming_Schemes --
8039 --------------------------
8041 procedure Check_Naming_Schemes
8042 (In_Tree : Project_Tree_Ref;
8043 Data : in out Project_Data;
8045 File_Name : File_Name_Type;
8046 Alternate_Languages : out Alternate_Language_Id;
8047 Language : out Language_Index;
8048 Language_Name : out Name_Id;
8049 Display_Language_Name : out Name_Id;
8051 Lang_Kind : out Language_Kind;
8052 Kind : out Source_Kind)
8054 Last : Positive := Filename'Last;
8055 Config : Language_Config;
8056 Lang : Name_List_Index := Data.Languages;
8057 Header_File : Boolean := False;
8058 First_Language : Language_Index;
8061 Last_Spec : Natural;
8062 Last_Body : Natural;
8067 Alternate_Languages := No_Alternate_Language;
8069 while Lang /= No_Name_List loop
8070 Language_Name := In_Tree.Name_Lists.Table (Lang).Name;
8071 Language := Data.First_Language_Processing;
8073 if Current_Verbosity = High then
8075 (" Testing language "
8076 & Get_Name_String (Language_Name)
8077 & " Header_File=" & Header_File'Img);
8080 while Language /= No_Language_Index loop
8081 if In_Tree.Languages_Data.Table (Language).Name =
8084 Display_Language_Name :=
8085 In_Tree.Languages_Data.Table (Language).Display_Name;
8086 Config := In_Tree.Languages_Data.Table (Language).Config;
8087 Lang_Kind := Config.Kind;
8089 if Config.Kind = File_Based then
8091 -- For file based languages, there is no Unit. Just
8092 -- check if the file name has the implementation or,
8093 -- if it is specified, the template suffix of the
8099 and then Config.Naming_Data.Body_Suffix /= No_File
8102 Impl_Suffix : constant String :=
8103 Get_Name_String (Config.Naming_Data.Body_Suffix);
8106 if Filename'Length > Impl_Suffix'Length
8109 (Last - Impl_Suffix'Length + 1 .. Last) =
8114 if Current_Verbosity = High then
8115 Write_Str (" source of language ");
8117 (Get_Name_String (Display_Language_Name));
8125 if Config.Naming_Data.Spec_Suffix /= No_File then
8127 Spec_Suffix : constant String :=
8129 (Config.Naming_Data.Spec_Suffix);
8132 if Filename'Length > Spec_Suffix'Length
8135 (Last - Spec_Suffix'Length + 1 .. Last) =
8140 if Current_Verbosity = High then
8141 Write_Str (" header file of language ");
8143 (Get_Name_String (Display_Language_Name));
8147 Alternate_Language_Table.Increment_Last
8148 (In_Tree.Alt_Langs);
8149 In_Tree.Alt_Langs.Table
8150 (Alternate_Language_Table.Last
8151 (In_Tree.Alt_Langs)) :=
8152 (Language => Language,
8153 Next => Alternate_Languages);
8154 Alternate_Languages :=
8155 Alternate_Language_Table.Last
8156 (In_Tree.Alt_Langs);
8158 Header_File := True;
8159 First_Language := Language;
8165 elsif not Header_File then
8166 -- Unit based language
8168 OK := Config.Naming_Data.Dot_Replacement /= No_File;
8173 -- ??? Are we doing this once per file in the project ?
8174 -- It should be done only once per project.
8176 case Config.Naming_Data.Casing is
8177 when All_Lower_Case =>
8178 for J in Filename'Range loop
8179 if Is_Letter (Filename (J)) then
8180 if not Is_Lower (Filename (J)) then
8187 when All_Upper_Case =>
8188 for J in Filename'Range loop
8189 if Is_Letter (Filename (J)) then
8190 if not Is_Upper (Filename (J)) then
8203 Last_Spec := Natural'Last;
8204 Last_Body := Natural'Last;
8205 Last_Sep := Natural'Last;
8207 if Config.Naming_Data.Separate_Suffix /= No_File
8209 Config.Naming_Data.Separate_Suffix /=
8210 Config.Naming_Data.Body_Suffix
8213 Suffix : constant String :=
8215 (Config.Naming_Data.Separate_Suffix);
8217 if Filename'Length > Suffix'Length
8220 (Last - Suffix'Length + 1 .. Last) =
8223 Last_Sep := Last - Suffix'Length;
8228 if Config.Naming_Data.Body_Suffix /= No_File then
8230 Suffix : constant String :=
8232 (Config.Naming_Data.Body_Suffix);
8234 if Filename'Length > Suffix'Length
8237 (Last - Suffix'Length + 1 .. Last) =
8240 Last_Body := Last - Suffix'Length;
8245 if Config.Naming_Data.Spec_Suffix /= No_File then
8247 Suffix : constant String :=
8249 (Config.Naming_Data.Spec_Suffix);
8251 if Filename'Length > Suffix'Length
8254 (Last - Suffix'Length + 1 .. Last) =
8257 Last_Spec := Last - Suffix'Length;
8263 Last_Min : constant Natural :=
8264 Natural'Min (Natural'Min (Last_Spec,
8269 OK := Last_Min < Last;
8274 if Last_Min = Last_Spec then
8277 elsif Last_Min = Last_Body then
8289 -- Replace dot replacements with dots
8294 J : Positive := Filename'First;
8296 Dot_Replacement : constant String :=
8298 (Config.Naming_Data.
8301 Max : constant Positive :=
8302 Last - Dot_Replacement'Length + 1;
8306 Name_Len := Name_Len + 1;
8308 if J <= Max and then
8310 (J .. J + Dot_Replacement'Length - 1) =
8313 Name_Buffer (Name_Len) := '.';
8314 J := J + Dot_Replacement'Length;
8317 if Filename (J) = '.' then
8322 Name_Buffer (Name_Len) :=
8323 GNAT.Case_Util.To_Lower (Filename (J));
8334 -- The name buffer should contain the name of the
8335 -- the unit, if it is one.
8337 -- Check that this is a valid unit name
8339 Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit);
8341 if Unit /= No_Name then
8343 if Current_Verbosity = High then
8345 Write_Str (" spec of ");
8347 Write_Str (" body of ");
8350 Write_Str (Get_Name_String (Unit));
8351 Write_Str (" (language ");
8353 (Get_Name_String (Display_Language_Name));
8357 -- Comments required, declare block should
8361 Unit_Except : constant Unit_Exception :=
8362 Unit_Exceptions.Get (Unit);
8364 procedure Masked_Unit (Spec : Boolean);
8365 -- Indicate that there is an exception for
8366 -- the same unit, so the file is not a
8367 -- source for the unit.
8373 procedure Masked_Unit (Spec : Boolean) is
8375 if Current_Verbosity = High then
8377 Write_Str (Filename);
8378 Write_Str (""" contains the ");
8387 (" of a unit that is found in """);
8392 (Unit_Except.Spec));
8396 (Unit_Except.Impl));
8399 Write_Line (""" (ignored)");
8402 Language := No_Language_Index;
8407 if Unit_Except.Spec /= No_File
8408 and then Unit_Except.Spec /= File_Name
8410 Masked_Unit (Spec => True);
8414 if Unit_Except.Impl /= No_File
8415 and then Unit_Except.Impl /= File_Name
8417 Masked_Unit (Spec => False);
8428 Language := In_Tree.Languages_Data.Table (Language).Next;
8431 Lang := In_Tree.Name_Lists.Table (Lang).Next;
8434 -- Comment needed here ???
8437 Language := First_Language;
8440 Language := No_Language_Index;
8442 if Current_Verbosity = High then
8443 Write_Line (" not a source of any language");
8446 end Check_Naming_Schemes;
8452 procedure Check_File
8453 (Project : Project_Id;
8454 In_Tree : Project_Tree_Ref;
8455 Data : in out Project_Data;
8457 File_Name : File_Name_Type;
8458 Display_File_Name : File_Name_Type;
8459 Source_Directory : String;
8460 For_All_Sources : Boolean)
8462 Display_Path : constant String :=
8465 Directory => Source_Directory,
8466 Resolve_Links => Opt.Follow_Links_For_Files,
8467 Case_Sensitive => True);
8469 Name_Loc : Name_Location := Source_Names.Get (File_Name);
8470 Path_Id : Path_Name_Type;
8471 Display_Path_Id : Path_Name_Type;
8472 Check_Name : Boolean := False;
8473 Alternate_Languages : Alternate_Language_Id := No_Alternate_Language;
8474 Language : Language_Index;
8476 Other_Part : Source_Id;
8478 Src_Ind : Source_File_Index;
8479 Src_Data : Source_Data;
8481 Source_To_Replace : Source_Id := No_Source;
8482 Language_Name : Name_Id;
8483 Display_Language_Name : Name_Id;
8484 Lang_Kind : Language_Kind;
8485 Kind : Source_Kind := Spec;
8488 Name_Len := Display_Path'Length;
8489 Name_Buffer (1 .. Name_Len) := Display_Path;
8490 Display_Path_Id := Name_Find;
8492 if Osint.File_Names_Case_Sensitive then
8493 Path_Id := Display_Path_Id;
8495 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
8496 Path_Id := Name_Find;
8499 if Name_Loc = No_Name_Location then
8500 Check_Name := For_All_Sources;
8503 if Name_Loc.Found then
8505 -- Check if it is OK to have the same file name in several
8506 -- source directories.
8508 if not Data.Known_Order_Of_Source_Dirs then
8509 Error_Msg_File_1 := File_Name;
8512 "{ is found in several source directories",
8517 Name_Loc.Found := True;
8519 Source_Names.Set (File_Name, Name_Loc);
8521 if Name_Loc.Source = No_Source then
8525 In_Tree.Sources.Table (Name_Loc.Source).Path :=
8526 (Path_Id, Display_Path_Id);
8528 Source_Paths_Htable.Set
8529 (In_Tree.Source_Paths_HT,
8533 -- Check if this is a subunit
8535 if In_Tree.Sources.Table (Name_Loc.Source).Unit /= No_Name
8537 In_Tree.Sources.Table (Name_Loc.Source).Kind = Impl
8539 Src_Ind := Sinput.P.Load_Project_File
8540 (Get_Name_String (Path_Id));
8542 if Sinput.P.Source_File_Is_Subunit (Src_Ind) then
8543 In_Tree.Sources.Table (Name_Loc.Source).Kind := Sep;
8551 Other_Part := No_Source;
8553 Check_Naming_Schemes
8554 (In_Tree => In_Tree,
8556 Filename => Get_Name_String (File_Name),
8557 File_Name => File_Name,
8558 Alternate_Languages => Alternate_Languages,
8559 Language => Language,
8560 Language_Name => Language_Name,
8561 Display_Language_Name => Display_Language_Name,
8563 Lang_Kind => Lang_Kind,
8566 if Language = No_Language_Index then
8568 -- A file name in a list must be a source of a language
8570 if Name_Loc.Found then
8571 Error_Msg_File_1 := File_Name;
8575 "language unknown for {",
8580 -- Check if the same file name or unit is used in the prj tree
8582 Source := In_Tree.First_Source;
8584 while Source /= No_Source loop
8585 Src_Data := In_Tree.Sources.Table (Source);
8588 and then Src_Data.Unit = Unit
8590 ((Src_Data.Kind = Spec and then Kind = Impl)
8592 (Src_Data.Kind = Impl and then Kind = Spec))
8594 Other_Part := Source;
8596 elsif (Unit /= No_Name
8597 and then Src_Data.Unit = Unit
8599 (Src_Data.Kind = Kind
8601 (Src_Data.Kind = Sep and then Kind = Impl)
8603 (Src_Data.Kind = Impl and then Kind = Sep)))
8604 or else (Unit = No_Name and then Src_Data.File = File_Name)
8606 -- Duplication of file/unit in same project is only
8607 -- allowed if order of source directories is known.
8609 if Project = Src_Data.Project then
8610 if Data.Known_Order_Of_Source_Dirs then
8613 elsif Unit /= No_Name then
8614 Error_Msg_Name_1 := Unit;
8616 (Project, In_Tree, "duplicate unit %%", No_Location);
8620 Error_Msg_File_1 := File_Name;
8622 (Project, In_Tree, "duplicate source file name {",
8627 -- Do not allow the same unit name in different
8628 -- projects, except if one is extending the other.
8630 -- For a file based language, the same file name
8631 -- replaces a file in a project being extended, but
8632 -- it is allowed to have the same file name in
8633 -- unrelated projects.
8636 (Project, Src_Data.Project, In_Tree)
8638 Source_To_Replace := Source;
8640 elsif Unit /= No_Name then
8641 Error_Msg_Name_1 := Unit;
8644 "unit %% cannot belong to several projects",
8647 Error_Msg_Name_1 := In_Tree.Projects.Table (Project).Name;
8648 Error_Msg_Name_2 := Name_Id (Display_Path_Id);
8650 (Project, In_Tree, "\ project %%, %%", No_Location);
8653 In_Tree.Projects.Table (Src_Data.Project).Name;
8654 Error_Msg_Name_2 := Name_Id (Src_Data.Path.Display_Name);
8656 (Project, In_Tree, "\ project %%, %%", No_Location);
8662 Source := Src_Data.Next_In_Sources;
8671 Lang => Language_Name,
8672 Lang_Id => Language,
8673 Lang_Kind => Lang_Kind,
8675 Alternate_Languages => Alternate_Languages,
8676 File_Name => File_Name,
8677 Display_File => Display_File_Name,
8678 Other_Part => Other_Part,
8681 Display_Path => Display_Path_Id,
8682 Source_To_Replace => Source_To_Replace);
8688 ------------------------
8689 -- Search_Directories --
8690 ------------------------
8692 procedure Search_Directories
8693 (Project : Project_Id;
8694 In_Tree : Project_Tree_Ref;
8695 Data : in out Project_Data;
8696 For_All_Sources : Boolean)
8698 Source_Dir : String_List_Id;
8699 Element : String_Element;
8701 Name : String (1 .. 1_000);
8703 File_Name : File_Name_Type;
8704 Display_File_Name : File_Name_Type;
8707 if Current_Verbosity = High then
8708 Write_Line ("Looking for sources:");
8711 -- Loop through subdirectories
8713 Source_Dir := Data.Source_Dirs;
8714 while Source_Dir /= Nil_String loop
8716 Element := In_Tree.String_Elements.Table (Source_Dir);
8717 if Element.Value /= No_Name then
8718 Get_Name_String (Element.Display_Value);
8721 Source_Directory : constant String :=
8722 Name_Buffer (1 .. Name_Len) &
8723 Directory_Separator;
8725 Dir_Last : constant Natural :=
8726 Compute_Directory_Last
8730 if Current_Verbosity = High then
8731 Write_Str ("Source_Dir = ");
8732 Write_Line (Source_Directory);
8735 -- We look to every entry in the source directory
8737 Open (Dir, Source_Directory);
8740 Read (Dir, Name, Last);
8744 -- ??? Duplicate system call here, we just did a
8745 -- a similar one. Maybe Ada.Directories would be more
8749 (Source_Directory & Name (1 .. Last))
8751 if Current_Verbosity = High then
8752 Write_Str (" Checking ");
8753 Write_Line (Name (1 .. Last));
8757 Name_Buffer (1 .. Name_Len) := Name (1 .. Last);
8758 Display_File_Name := Name_Find;
8760 if Osint.File_Names_Case_Sensitive then
8761 File_Name := Display_File_Name;
8763 Canonical_Case_File_Name
8764 (Name_Buffer (1 .. Name_Len));
8765 File_Name := Name_Find;
8770 Excluded_Sources_Htable.Get (File_Name);
8773 if FF /= No_File_Found then
8774 if not FF.Found then
8776 Excluded_Sources_Htable.Set
8779 if Current_Verbosity = High then
8780 Write_Str (" excluded source """);
8781 Write_Str (Get_Name_String (File_Name));
8788 (Project => Project,
8791 Name => Name (1 .. Last),
8792 File_Name => File_Name,
8793 Display_File_Name => Display_File_Name,
8794 Source_Directory => Source_Directory
8795 (Source_Directory'First .. Dir_Last),
8796 For_All_Sources => For_All_Sources);
8807 when Directory_Error =>
8811 Source_Dir := Element.Next;
8814 if Current_Verbosity = High then
8815 Write_Line ("end Looking for sources.");
8817 end Search_Directories;
8819 ----------------------
8820 -- Look_For_Sources --
8821 ----------------------
8823 procedure Look_For_Sources
8824 (Project : Project_Id;
8825 In_Tree : Project_Tree_Ref;
8826 Data : in out Project_Data;
8827 Current_Dir : String)
8829 procedure Remove_Locally_Removed_Files_From_Units;
8830 -- Mark all locally removed sources as such in the Units table
8832 procedure Process_Other_Sources_In_Ada_Only_Mode;
8833 -- Find sources for language other than Ada when in Ada_Only mode
8835 procedure Process_Sources_In_Multi_Language_Mode;
8836 -- Find all source files when in multi language mode
8838 ---------------------------------------------
8839 -- Remove_Locally_Removed_Files_From_Units --
8840 ---------------------------------------------
8842 procedure Remove_Locally_Removed_Files_From_Units is
8843 Excluded : File_Found;
8846 Extended : Project_Id;
8849 Excluded := Excluded_Sources_Htable.Get_First;
8850 while Excluded /= No_File_Found loop
8854 for Index in Unit_Table.First ..
8855 Unit_Table.Last (In_Tree.Units)
8857 Unit := In_Tree.Units.Table (Index);
8859 for Kind in Spec_Or_Body'Range loop
8860 if Unit.File_Names (Kind).Name = Excluded.File then
8863 -- Check that this is from the current project or
8864 -- that the current project extends.
8866 Extended := Unit.File_Names (Kind).Project;
8868 if Extended = Project
8869 or else Project_Extends (Project, Extended, In_Tree)
8871 Unit.File_Names (Kind).Path.Name := Slash;
8872 Unit.File_Names (Kind).Needs_Pragma := False;
8873 In_Tree.Units.Table (Index) := Unit;
8874 Add_Forbidden_File_Name
8875 (Unit.File_Names (Kind).Name);
8879 "cannot remove a source from " &
8886 end loop For_Each_Unit;
8889 Err_Vars.Error_Msg_File_1 := Excluded.File;
8891 (Project, In_Tree, "unknown file {", Excluded.Location);
8894 Excluded := Excluded_Sources_Htable.Get_Next;
8896 end Remove_Locally_Removed_Files_From_Units;
8898 --------------------------------------------
8899 -- Process_Other_Sources_In_Ada_Only_Mode --
8900 --------------------------------------------
8902 procedure Process_Other_Sources_In_Ada_Only_Mode is
8904 -- Set Source_Present to False. It will be set back to True
8905 -- whenever a source is found.
8907 Data.Other_Sources_Present := False;
8908 for Lang in Ada_Language_Index + 1 .. Last_Language_Index loop
8910 -- For each language (other than Ada) in the project file
8912 if Is_Present (Lang, Data, In_Tree) then
8914 -- Reset the indication that there are sources of this
8915 -- language. It will be set back to True whenever we find
8916 -- a source of the language.
8918 Set (Lang, False, Data, In_Tree);
8920 -- First, get the source suffix for the language
8922 Set (Suffix => Suffix_For (Lang, Data.Naming, In_Tree),
8923 For_Language => Lang,
8925 In_Tree => In_Tree);
8927 -- Then, deal with the naming exceptions, if any
8932 Naming_Exceptions : constant Variable_Value :=
8934 (Index => Language_Names.Table (Lang),
8936 In_Array => Data.Naming.Implementation_Exceptions,
8937 In_Tree => In_Tree);
8938 Element_Id : String_List_Id;
8939 Element : String_Element;
8940 File_Id : File_Name_Type;
8941 Source_Found : Boolean := False;
8944 -- If there are naming exceptions, look through them one
8947 if Naming_Exceptions /= Nil_Variable_Value then
8948 Element_Id := Naming_Exceptions.Values;
8950 while Element_Id /= Nil_String loop
8951 Element := In_Tree.String_Elements.Table (Element_Id);
8953 if Osint.File_Names_Case_Sensitive then
8954 File_Id := File_Name_Type (Element.Value);
8956 Get_Name_String (Element.Value);
8957 Canonical_Case_File_Name
8958 (Name_Buffer (1 .. Name_Len));
8959 File_Id := Name_Find;
8962 -- Put each naming exception in the Source_Names hash
8963 -- table, but if there are repetition, don't bother
8964 -- after the first instance.
8966 if Source_Names.Get (File_Id) = No_Name_Location then
8967 Source_Found := True;
8971 Location => Element.Location,
8972 Source => No_Source,
8977 Element_Id := Element.Next;
8980 -- If there is at least one naming exception, record
8981 -- those that are found in the source directories.
8983 if Source_Found then
8984 Record_Other_Sources
8985 (Project => Project,
8989 Naming_Exceptions => True);
8995 -- Now, check if a list of sources is declared either through
8996 -- a string list (attribute Source_Files) or a text file
8997 -- (attribute Source_List_File). If a source list is declared,
8998 -- we will consider only those naming exceptions that are
9002 Find_Explicit_Sources
9003 (Lang, Current_Dir, Project, In_Tree, Data);
9006 end Process_Other_Sources_In_Ada_Only_Mode;
9008 --------------------------------------------
9009 -- Process_Sources_In_Multi_Language_Mode --
9010 --------------------------------------------
9012 procedure Process_Sources_In_Multi_Language_Mode is
9014 Src_Data : Source_Data;
9015 Name_Loc : Name_Location;
9020 -- First, put all naming exceptions if any, in the Source_Names table
9022 Unit_Exceptions.Reset;
9024 Source := Data.First_Source;
9025 while Source /= No_Source loop
9026 Src_Data := In_Tree.Sources.Table (Source);
9028 -- A file that is excluded cannot also be an exception file name
9030 if Excluded_Sources_Htable.Get (Src_Data.File) /=
9033 Error_Msg_File_1 := Src_Data.File;
9036 "{ cannot be both excluded and an exception file name",
9040 Name_Loc := (Name => Src_Data.File,
9041 Location => No_Location,
9043 Except => Src_Data.Unit /= No_Name,
9046 if Current_Verbosity = High then
9047 Write_Str ("Putting source #");
9048 Write_Str (Source'Img);
9049 Write_Str (", file ");
9050 Write_Str (Get_Name_String (Src_Data.File));
9051 Write_Line (" in Source_Names");
9054 Source_Names.Set (K => Src_Data.File, E => Name_Loc);
9056 -- If this is an Ada exception, record it in table Unit_Exceptions
9058 if Src_Data.Unit /= No_Name then
9060 Unit_Except : Unit_Exception :=
9061 Unit_Exceptions.Get (Src_Data.Unit);
9064 Unit_Except.Name := Src_Data.Unit;
9066 if Src_Data.Kind = Spec then
9067 Unit_Except.Spec := Src_Data.File;
9069 Unit_Except.Impl := Src_Data.File;
9072 Unit_Exceptions.Set (Src_Data.Unit, Unit_Except);
9076 Source := Src_Data.Next_In_Project;
9079 Find_Explicit_Sources
9080 (Ada_Language_Index, Current_Dir, Project, In_Tree, Data);
9082 -- Mark as such the sources that are declared as excluded
9084 FF := Excluded_Sources_Htable.Get_First;
9085 while FF /= No_File_Found loop
9087 Source := In_Tree.First_Source;
9089 while Source /= No_Source loop
9090 Src_Data := In_Tree.Sources.Table (Source);
9092 if Src_Data.File = FF.File then
9094 -- Check that this is from this project or a project that
9095 -- the current project extends.
9097 if Src_Data.Project = Project or else
9098 Is_Extending (Project, Src_Data.Project, In_Tree)
9100 Src_Data.Locally_Removed := True;
9101 Src_Data.In_Interfaces := False;
9102 In_Tree.Sources.Table (Source) := Src_Data;
9103 Add_Forbidden_File_Name (FF.File);
9109 Source := Src_Data.Next_In_Sources;
9112 if not FF.Found and not OK then
9113 Err_Vars.Error_Msg_File_1 := FF.File;
9114 Error_Msg (Project, In_Tree, "unknown file {", FF.Location);
9117 FF := Excluded_Sources_Htable.Get_Next;
9120 -- Check that two sources of this project do not have the same object
9123 Check_Object_File_Names : declare
9125 Src_Data : Source_Data;
9126 Source_Name : File_Name_Type;
9128 procedure Check_Object;
9129 -- Check if object file name of the current source is already in
9130 -- hash table Object_File_Names. If it is, report an error. If it
9131 -- is not, put it there with the file name of the current source.
9137 procedure Check_Object is
9139 Source_Name := Object_File_Names.Get (Src_Data.Object);
9141 if Source_Name /= No_File then
9142 Error_Msg_File_1 := Src_Data.File;
9143 Error_Msg_File_2 := Source_Name;
9147 "{ and { have the same object file name",
9151 Object_File_Names.Set (Src_Data.Object, Src_Data.File);
9155 -- Start of processing for Check_Object_File_Names
9158 Object_File_Names.Reset;
9159 Src_Id := In_Tree.First_Source;
9160 while Src_Id /= No_Source loop
9161 Src_Data := In_Tree.Sources.Table (Src_Id);
9163 if Src_Data.Compiled and then Src_Data.Object_Exists
9164 and then Project_Extends (Project, Src_Data.Project, In_Tree)
9166 if Src_Data.Unit = No_Name then
9167 if Src_Data.Kind = Impl then
9172 case Src_Data.Kind is
9174 if Src_Data.Other_Part = No_Source then
9182 if Src_Data.Other_Part /= No_Source then
9186 -- Check if it is a subunit
9189 Src_Ind : constant Source_File_Index :=
9190 Sinput.P.Load_Project_File
9192 (Src_Data.Path.Name));
9195 if Sinput.P.Source_File_Is_Subunit
9198 In_Tree.Sources.Table (Src_Id).Kind := Sep;
9208 Src_Id := Src_Data.Next_In_Sources;
9210 end Check_Object_File_Names;
9211 end Process_Sources_In_Multi_Language_Mode;
9213 -- Start of processing for Look_For_Sources
9217 Find_Excluded_Sources (Project, In_Tree, Data);
9221 if Is_A_Language (In_Tree, Data, Name_Ada) then
9222 Find_Explicit_Sources
9223 (Ada_Language_Index, Current_Dir, Project, In_Tree, Data);
9224 Remove_Locally_Removed_Files_From_Units;
9227 if Data.Other_Sources_Present then
9228 Process_Other_Sources_In_Ada_Only_Mode;
9231 when Multi_Language =>
9232 if Data.First_Language_Processing /= No_Language_Index then
9233 Process_Sources_In_Multi_Language_Mode;
9236 end Look_For_Sources;
9242 function Path_Name_Of
9243 (File_Name : File_Name_Type;
9244 Directory : Path_Name_Type) return String
9246 Result : String_Access;
9247 The_Directory : constant String := Get_Name_String (Directory);
9250 Get_Name_String (File_Name);
9253 (File_Name => Name_Buffer (1 .. Name_Len),
9254 Path => The_Directory);
9256 if Result = null then
9259 Canonical_Case_File_Name (Result.all);
9264 -------------------------------
9265 -- Prepare_Ada_Naming_Exceptions --
9266 -------------------------------
9268 procedure Prepare_Ada_Naming_Exceptions
9269 (List : Array_Element_Id;
9270 In_Tree : Project_Tree_Ref;
9271 Kind : Spec_Or_Body)
9273 Current : Array_Element_Id;
9274 Element : Array_Element;
9278 -- Traverse the list
9281 while Current /= No_Array_Element loop
9282 Element := In_Tree.Array_Elements.Table (Current);
9284 if Element.Index /= No_Name then
9287 Unit => Element.Index,
9288 Next => No_Ada_Naming_Exception);
9289 Reverse_Ada_Naming_Exceptions.Set
9290 (Unit, (Element.Value.Value, Element.Value.Index));
9292 Ada_Naming_Exceptions.Get (File_Name_Type (Element.Value.Value));
9293 Ada_Naming_Exception_Table.Increment_Last;
9294 Ada_Naming_Exception_Table.Table
9295 (Ada_Naming_Exception_Table.Last) := Unit;
9296 Ada_Naming_Exceptions.Set
9297 (File_Name_Type (Element.Value.Value),
9298 Ada_Naming_Exception_Table.Last);
9301 Current := Element.Next;
9303 end Prepare_Ada_Naming_Exceptions;
9305 ---------------------
9306 -- Project_Extends --
9307 ---------------------
9309 function Project_Extends
9310 (Extending : Project_Id;
9311 Extended : Project_Id;
9312 In_Tree : Project_Tree_Ref) return Boolean
9314 Current : Project_Id := Extending;
9318 if Current = No_Project then
9321 elsif Current = Extended then
9325 Current := In_Tree.Projects.Table (Current).Extends;
9327 end Project_Extends;
9329 -----------------------
9330 -- Record_Ada_Source --
9331 -----------------------
9333 procedure Record_Ada_Source
9334 (File_Name : File_Name_Type;
9335 Path_Name : Path_Name_Type;
9336 Project : Project_Id;
9337 In_Tree : Project_Tree_Ref;
9338 Data : in out Project_Data;
9339 Location : Source_Ptr;
9340 Current_Source : in out String_List_Id;
9341 Source_Recorded : in out Boolean;
9342 Current_Dir : String)
9344 Canonical_File_Name : File_Name_Type;
9345 Canonical_Path_Name : Path_Name_Type;
9347 Exception_Id : Ada_Naming_Exception_Id;
9348 Unit_Name : Name_Id;
9349 Unit_Kind : Spec_Or_Body;
9350 Unit_Ind : Int := 0;
9352 Name_Index : Name_And_Index;
9353 Needs_Pragma : Boolean;
9355 The_Location : Source_Ptr := Location;
9356 Previous_Source : constant String_List_Id := Current_Source;
9357 Except_Name : Name_And_Index := No_Name_And_Index;
9359 Unit_Prj : Unit_Project;
9361 File_Name_Recorded : Boolean := False;
9364 if Osint.File_Names_Case_Sensitive then
9365 Canonical_File_Name := File_Name;
9366 Canonical_Path_Name := Path_Name;
9368 Get_Name_String (File_Name);
9369 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
9370 Canonical_File_Name := Name_Find;
9373 Canonical_Path : constant String :=
9375 (Get_Name_String (Path_Name),
9376 Directory => Current_Dir,
9377 Resolve_Links => Opt.Follow_Links_For_Files,
9378 Case_Sensitive => False);
9381 Add_Str_To_Name_Buffer (Canonical_Path);
9382 Canonical_Path_Name := Name_Find;
9386 -- Find out the unit name, the unit kind and if it needs
9387 -- a specific SFN pragma.
9390 (In_Tree => In_Tree,
9391 Canonical_File_Name => Canonical_File_Name,
9392 Naming => Data.Naming,
9393 Exception_Id => Exception_Id,
9394 Unit_Name => Unit_Name,
9395 Unit_Kind => Unit_Kind,
9396 Needs_Pragma => Needs_Pragma);
9398 if Exception_Id = No_Ada_Naming_Exception
9399 and then Unit_Name = No_Name
9401 if Current_Verbosity = High then
9403 Write_Str (Get_Name_String (Canonical_File_Name));
9404 Write_Line (""" is not a valid source file name (ignored).");
9408 -- Check to see if the source has been hidden by an exception,
9409 -- but only if it is not an exception.
9411 if not Needs_Pragma then
9413 Reverse_Ada_Naming_Exceptions.Get
9414 ((Unit_Kind, Unit_Name, No_Ada_Naming_Exception));
9416 if Except_Name /= No_Name_And_Index then
9417 if Current_Verbosity = High then
9419 Write_Str (Get_Name_String (Canonical_File_Name));
9420 Write_Str (""" contains a unit that is found in """);
9421 Write_Str (Get_Name_String (Except_Name.Name));
9422 Write_Line (""" (ignored).");
9425 -- The file is not included in the source of the project since
9426 -- it is hidden by the exception. So, nothing else to do.
9433 if Exception_Id /= No_Ada_Naming_Exception then
9434 Info := Ada_Naming_Exception_Table.Table (Exception_Id);
9435 Exception_Id := Info.Next;
9436 Info.Next := No_Ada_Naming_Exception;
9437 Name_Index := Reverse_Ada_Naming_Exceptions.Get (Info);
9439 Unit_Name := Info.Unit;
9440 Unit_Ind := Name_Index.Index;
9441 Unit_Kind := Info.Kind;
9444 -- Put the file name in the list of sources of the project
9446 String_Element_Table.Increment_Last (In_Tree.String_Elements);
9447 In_Tree.String_Elements.Table
9448 (String_Element_Table.Last (In_Tree.String_Elements)) :=
9449 (Value => Name_Id (Canonical_File_Name),
9450 Display_Value => Name_Id (File_Name),
9451 Location => No_Location,
9456 if Current_Source = Nil_String then
9458 String_Element_Table.Last (In_Tree.String_Elements);
9459 Data.Sources := Data.Ada_Sources;
9461 In_Tree.String_Elements.Table (Current_Source).Next :=
9462 String_Element_Table.Last (In_Tree.String_Elements);
9466 String_Element_Table.Last (In_Tree.String_Elements);
9468 -- Put the unit in unit list
9471 The_Unit : Unit_Index :=
9472 Units_Htable.Get (In_Tree.Units_HT, Unit_Name);
9474 The_Unit_Data : Unit_Data;
9477 if Current_Verbosity = High then
9478 Write_Str ("Putting ");
9479 Write_Str (Get_Name_String (Unit_Name));
9480 Write_Line (" in the unit list.");
9483 -- The unit is already in the list, but may be it is
9484 -- only the other unit kind (spec or body), or what is
9485 -- in the unit list is a unit of a project we are extending.
9487 if The_Unit /= No_Unit_Index then
9488 The_Unit_Data := In_Tree.Units.Table (The_Unit);
9490 if (The_Unit_Data.File_Names (Unit_Kind).Name =
9493 The_Unit_Data.File_Names
9494 (Unit_Kind).Path.Name = Slash)
9495 or else The_Unit_Data.File_Names (Unit_Kind).Name = No_File
9496 or else Project_Extends
9498 The_Unit_Data.File_Names (Unit_Kind).Project,
9502 The_Unit_Data.File_Names (Unit_Kind).Path.Name = Slash
9504 Remove_Forbidden_File_Name
9505 (The_Unit_Data.File_Names (Unit_Kind).Name);
9508 -- Record the file name in the hash table Files_Htable
9510 Unit_Prj := (Unit => The_Unit, Project => Project);
9513 Canonical_File_Name,
9516 The_Unit_Data.File_Names (Unit_Kind) :=
9517 (Name => Canonical_File_Name,
9519 Display_Name => File_Name,
9520 Path => (Canonical_Path_Name, Path_Name),
9522 Needs_Pragma => Needs_Pragma);
9523 In_Tree.Units.Table (The_Unit) := The_Unit_Data;
9524 Source_Recorded := True;
9526 elsif The_Unit_Data.File_Names (Unit_Kind).Project = Project
9527 and then (Data.Known_Order_Of_Source_Dirs
9529 The_Unit_Data.File_Names
9530 (Unit_Kind).Path.Name = Canonical_Path_Name)
9532 if Previous_Source = Nil_String then
9533 Data.Ada_Sources := Nil_String;
9534 Data.Sources := Nil_String;
9536 In_Tree.String_Elements.Table (Previous_Source).Next :=
9538 String_Element_Table.Decrement_Last
9539 (In_Tree.String_Elements);
9542 Current_Source := Previous_Source;
9545 -- It is an error to have two units with the same name
9546 -- and the same kind (spec or body).
9548 if The_Location = No_Location then
9550 In_Tree.Projects.Table (Project).Location;
9553 Err_Vars.Error_Msg_Name_1 := Unit_Name;
9555 (Project, In_Tree, "duplicate unit %%", The_Location);
9557 Err_Vars.Error_Msg_Name_1 :=
9558 In_Tree.Projects.Table
9559 (The_Unit_Data.File_Names (Unit_Kind).Project).Name;
9560 Err_Vars.Error_Msg_File_1 :=
9562 (The_Unit_Data.File_Names (Unit_Kind).Path.Name);
9565 "\ project file %%, {", The_Location);
9567 Err_Vars.Error_Msg_Name_1 :=
9568 In_Tree.Projects.Table (Project).Name;
9569 Err_Vars.Error_Msg_File_1 :=
9570 File_Name_Type (Canonical_Path_Name);
9573 "\ project file %%, {", The_Location);
9576 -- It is a new unit, create a new record
9579 -- First, check if there is no other unit with this file
9580 -- name in another project. If it is, report error but note
9581 -- we do that only for the first unit in the source file.
9584 Files_Htable.Get (In_Tree.Files_HT, Canonical_File_Name);
9586 if not File_Name_Recorded and then
9587 Unit_Prj /= No_Unit_Project
9589 Error_Msg_File_1 := File_Name;
9591 In_Tree.Projects.Table (Unit_Prj.Project).Name;
9594 "{ is already a source of project %%",
9598 Unit_Table.Increment_Last (In_Tree.Units);
9599 The_Unit := Unit_Table.Last (In_Tree.Units);
9601 (In_Tree.Units_HT, Unit_Name, The_Unit);
9602 Unit_Prj := (Unit => The_Unit, Project => Project);
9605 Canonical_File_Name,
9607 The_Unit_Data.Name := Unit_Name;
9608 The_Unit_Data.File_Names (Unit_Kind) :=
9609 (Name => Canonical_File_Name,
9611 Display_Name => File_Name,
9612 Path => (Canonical_Path_Name, Path_Name),
9614 Needs_Pragma => Needs_Pragma);
9615 In_Tree.Units.Table (The_Unit) := The_Unit_Data;
9616 Source_Recorded := True;
9621 exit when Exception_Id = No_Ada_Naming_Exception;
9622 File_Name_Recorded := True;
9625 end Record_Ada_Source;
9627 --------------------------
9628 -- Record_Other_Sources --
9629 --------------------------
9631 procedure Record_Other_Sources
9632 (Project : Project_Id;
9633 In_Tree : Project_Tree_Ref;
9634 Data : in out Project_Data;
9635 Language : Language_Index;
9636 Naming_Exceptions : Boolean)
9638 Source_Dir : String_List_Id;
9639 Element : String_Element;
9640 Path : Path_Name_Type;
9642 Canonical_Name : File_Name_Type;
9643 Name_Str : String (1 .. 1_024);
9644 Last : Natural := 0;
9646 First_Error : Boolean := True;
9647 Suffix : constant String :=
9648 Body_Suffix_Of (Language, Data, In_Tree);
9651 Source_Dir := Data.Source_Dirs;
9652 while Source_Dir /= Nil_String loop
9653 Element := In_Tree.String_Elements.Table (Source_Dir);
9656 Dir_Path : constant String :=
9657 Get_Name_String (Element.Display_Value);
9659 if Current_Verbosity = High then
9660 Write_Str ("checking directory """);
9661 Write_Str (Dir_Path);
9662 Write_Str (""" for ");
9664 if Naming_Exceptions then
9665 Write_Str ("naming exceptions");
9667 Write_Str ("sources");
9670 Write_Str (" of Language ");
9671 Display_Language_Name (Language);
9674 Open (Dir, Dir_Path);
9677 Read (Dir, Name_Str, Last);
9681 (Dir_Path & Directory_Separator & Name_Str (1 .. Last))
9684 Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last);
9685 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
9686 Canonical_Name := Name_Find;
9687 NL := Source_Names.Get (Canonical_Name);
9689 if NL /= No_Name_Location then
9691 if not Data.Known_Order_Of_Source_Dirs then
9692 Error_Msg_File_1 := Canonical_Name;
9695 "{ is found in several source directories",
9701 Source_Names.Set (Canonical_Name, NL);
9702 Name_Len := Dir_Path'Length;
9703 Name_Buffer (1 .. Name_Len) := Dir_Path;
9704 Add_Char_To_Name_Buffer (Directory_Separator);
9705 Add_Str_To_Name_Buffer (Name_Str (1 .. Last));
9709 (File_Name => Canonical_Name,
9714 Location => NL.Location,
9715 Language => Language,
9717 Naming_Exception => Naming_Exceptions);
9726 Source_Dir := Element.Next;
9729 if not Naming_Exceptions then
9730 NL := Source_Names.Get_First;
9732 -- It is an error if a source file name in a source list or
9733 -- in a source list file is not found.
9735 while NL /= No_Name_Location loop
9736 if not NL.Found then
9737 Err_Vars.Error_Msg_File_1 := NL.Name;
9741 (Project, In_Tree, "source file { cannot be found",
9743 First_Error := False;
9747 (Project, In_Tree, "\source file { cannot be found",
9752 NL := Source_Names.Get_Next;
9755 -- Any naming exception of this language that is not in a list
9756 -- of sources must be removed.
9759 Source_Id : Other_Source_Id;
9760 Prev_Id : Other_Source_Id;
9761 Source : Other_Source;
9764 Prev_Id := No_Other_Source;
9765 Source_Id := Data.First_Other_Source;
9766 while Source_Id /= No_Other_Source loop
9767 Source := In_Tree.Other_Sources.Table (Source_Id);
9769 if Source.Language = Language
9770 and then Source.Naming_Exception
9772 if Current_Verbosity = High then
9773 Write_Str ("Naming exception """);
9774 Write_Str (Get_Name_String (Source.File_Name));
9775 Write_Str (""" is not in the list of sources,");
9776 Write_Line (" so it is removed.");
9779 if Prev_Id = No_Other_Source then
9780 Data.First_Other_Source := Source.Next;
9782 In_Tree.Other_Sources.Table (Prev_Id).Next := Source.Next;
9785 Source_Id := Source.Next;
9787 if Source_Id = No_Other_Source then
9788 Data.Last_Other_Source := Prev_Id;
9792 Prev_Id := Source_Id;
9793 Source_Id := Source.Next;
9798 end Record_Other_Sources;
9804 procedure Remove_Source
9806 Replaced_By : Source_Id;
9807 Project : Project_Id;
9808 Data : in out Project_Data;
9809 In_Tree : Project_Tree_Ref)
9811 Src_Data : constant Source_Data := In_Tree.Sources.Table (Id);
9815 if Current_Verbosity = High then
9816 Write_Str ("Removing source #");
9817 Write_Line (Id'Img);
9820 if Replaced_By /= No_Source then
9821 In_Tree.Sources.Table (Id).Replaced_By := Replaced_By;
9822 In_Tree.Sources.Table (Replaced_By).Declared_In_Interfaces :=
9823 In_Tree.Sources.Table (Id).Declared_In_Interfaces;
9826 -- Remove the source from the global source list
9828 Source := In_Tree.First_Source;
9831 In_Tree.First_Source := Src_Data.Next_In_Sources;
9834 while In_Tree.Sources.Table (Source).Next_In_Sources /= Id loop
9835 Source := In_Tree.Sources.Table (Source).Next_In_Sources;
9838 In_Tree.Sources.Table (Source).Next_In_Sources :=
9839 Src_Data.Next_In_Sources;
9842 -- Remove the source from the project list
9844 if Src_Data.Project = Project then
9845 Source := Data.First_Source;
9848 Data.First_Source := Src_Data.Next_In_Project;
9850 if Src_Data.Next_In_Project = No_Source then
9851 Data.Last_Source := No_Source;
9855 while In_Tree.Sources.Table (Source).Next_In_Project /= Id loop
9856 Source := In_Tree.Sources.Table (Source).Next_In_Project;
9859 In_Tree.Sources.Table (Source).Next_In_Project :=
9860 Src_Data.Next_In_Project;
9862 if Src_Data.Next_In_Project = No_Source then
9863 In_Tree.Projects.Table (Src_Data.Project).Last_Source := Source;
9868 Source := In_Tree.Projects.Table (Src_Data.Project).First_Source;
9871 In_Tree.Projects.Table (Src_Data.Project).First_Source :=
9872 Src_Data.Next_In_Project;
9874 if Src_Data.Next_In_Project = No_Source then
9875 In_Tree.Projects.Table (Src_Data.Project).Last_Source :=
9880 while In_Tree.Sources.Table (Source).Next_In_Project /= Id loop
9881 Source := In_Tree.Sources.Table (Source).Next_In_Project;
9884 In_Tree.Sources.Table (Source).Next_In_Project :=
9885 Src_Data.Next_In_Project;
9887 if Src_Data.Next_In_Project = No_Source then
9888 In_Tree.Projects.Table (Src_Data.Project).Last_Source := Source;
9893 -- Remove source from the language list
9895 Source := In_Tree.Languages_Data.Table (Src_Data.Language).First_Source;
9898 In_Tree.Languages_Data.Table (Src_Data.Language).First_Source :=
9899 Src_Data.Next_In_Lang;
9902 while In_Tree.Sources.Table (Source).Next_In_Lang /= Id loop
9903 Source := In_Tree.Sources.Table (Source).Next_In_Lang;
9906 In_Tree.Sources.Table (Source).Next_In_Lang :=
9907 Src_Data.Next_In_Lang;
9911 -----------------------
9912 -- Report_No_Sources --
9913 -----------------------
9915 procedure Report_No_Sources
9916 (Project : Project_Id;
9918 In_Tree : Project_Tree_Ref;
9919 Location : Source_Ptr;
9920 Continuation : Boolean := False)
9923 case When_No_Sources is
9927 when Warning | Error =>
9929 Msg : constant String :=
9932 " sources in this project";
9935 Error_Msg_Warn := When_No_Sources = Warning;
9937 if Continuation then
9939 (Project, In_Tree, "\" & Msg, Location);
9943 (Project, In_Tree, Msg, Location);
9947 end Report_No_Sources;
9949 ----------------------
9950 -- Show_Source_Dirs --
9951 ----------------------
9953 procedure Show_Source_Dirs
9954 (Data : Project_Data;
9955 In_Tree : Project_Tree_Ref)
9957 Current : String_List_Id;
9958 Element : String_Element;
9961 Write_Line ("Source_Dirs:");
9963 Current := Data.Source_Dirs;
9964 while Current /= Nil_String loop
9965 Element := In_Tree.String_Elements.Table (Current);
9967 Write_Line (Get_Name_String (Element.Value));
9968 Current := Element.Next;
9971 Write_Line ("end Source_Dirs.");
9972 end Show_Source_Dirs;
9979 (Language : Language_Index;
9980 Naming : Naming_Data;
9981 In_Tree : Project_Tree_Ref) return File_Name_Type
9983 Suffix : constant Variable_Value :=
9985 (Index => Language_Names.Table (Language),
9987 In_Array => Naming.Body_Suffix,
9988 In_Tree => In_Tree);
9991 -- If no suffix for this language in package Naming, use the default
9993 if Suffix = Nil_Variable_Value then
9997 when Ada_Language_Index =>
9998 Add_Str_To_Name_Buffer (".adb");
10000 when C_Language_Index =>
10001 Add_Str_To_Name_Buffer (".c");
10003 when C_Plus_Plus_Language_Index =>
10004 Add_Str_To_Name_Buffer (".cpp");
10010 -- Otherwise use the one specified
10013 Get_Name_String (Suffix.Value);
10016 Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len));
10020 -------------------------
10021 -- Warn_If_Not_Sources --
10022 -------------------------
10024 -- comments needed in this body ???
10026 procedure Warn_If_Not_Sources
10027 (Project : Project_Id;
10028 In_Tree : Project_Tree_Ref;
10029 Conventions : Array_Element_Id;
10031 Extending : Boolean)
10033 Conv : Array_Element_Id;
10035 The_Unit_Id : Unit_Index;
10036 The_Unit_Data : Unit_Data;
10037 Location : Source_Ptr;
10040 Conv := Conventions;
10041 while Conv /= No_Array_Element loop
10042 Unit := In_Tree.Array_Elements.Table (Conv).Index;
10043 Error_Msg_Name_1 := Unit;
10044 Get_Name_String (Unit);
10045 To_Lower (Name_Buffer (1 .. Name_Len));
10047 The_Unit_Id := Units_Htable.Get (In_Tree.Units_HT, Unit);
10048 Location := In_Tree.Array_Elements.Table (Conv).Value.Location;
10050 if The_Unit_Id = No_Unit_Index then
10051 Error_Msg (Project, In_Tree, "?unknown unit %%", Location);
10054 The_Unit_Data := In_Tree.Units.Table (The_Unit_Id);
10055 Error_Msg_Name_2 :=
10056 In_Tree.Array_Elements.Table (Conv).Value.Value;
10059 if not Check_Project
10060 (The_Unit_Data.File_Names (Specification).Project,
10061 Project, In_Tree, Extending)
10065 "?source of spec of unit %% (%%)" &
10066 " cannot be found in this project",
10071 if not Check_Project
10072 (The_Unit_Data.File_Names (Body_Part).Project,
10073 Project, In_Tree, Extending)
10077 "?source of body of unit %% (%%)" &
10078 " cannot be found in this project",
10084 Conv := In_Tree.Array_Elements.Table (Conv).Next;
10086 end Warn_If_Not_Sources;