diff options
Diffstat (limited to 'gcc-4.2.1/gcc/ada/prj-nmsc.adb')
-rw-r--r-- | gcc-4.2.1/gcc/ada/prj-nmsc.adb | 5486 |
1 files changed, 0 insertions, 5486 deletions
diff --git a/gcc-4.2.1/gcc/ada/prj-nmsc.adb b/gcc-4.2.1/gcc/ada/prj-nmsc.adb deleted file mode 100644 index 67d59201d..000000000 --- a/gcc-4.2.1/gcc/ada/prj-nmsc.adb +++ /dev/null @@ -1,5486 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT COMPILER COMPONENTS -- --- -- --- P R J . N M S C -- --- -- --- B o d y -- --- -- --- Copyright (C) 2000-2006, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 2, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- --- for more details. You should have received a copy of the GNU General -- --- Public License distributed with GNAT; see file COPYING. If not, write -- --- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, -- --- Boston, MA 02110-1301, USA. -- --- -- --- GNAT was originally developed by the GNAT team at New York University. -- --- Extensive contributions were provided by Ada Core Technologies Inc. -- --- -- ------------------------------------------------------------------------------- - -with Err_Vars; use Err_Vars; -with Fmap; use Fmap; -with Hostparm; -with MLib.Tgt; use MLib.Tgt; -with Namet; use Namet; -with Osint; use Osint; -with Output; use Output; -with Prj.Env; use Prj.Env; -with Prj.Err; -with Prj.Util; use Prj.Util; -with Sinput.P; -with Snames; use Snames; -with Table; use Table; -with Targparm; use Targparm; - -with Ada.Characters.Handling; use Ada.Characters.Handling; -with Ada.Strings; use Ada.Strings; -with Ada.Strings.Fixed; use Ada.Strings.Fixed; -with Ada.Strings.Maps.Constants; use Ada.Strings.Maps.Constants; - -with GNAT.Case_Util; use GNAT.Case_Util; -with GNAT.Directory_Operations; use GNAT.Directory_Operations; -with GNAT.HTable; - -package body Prj.Nmsc is - - Error_Report : Put_Line_Access := null; - -- Set to point to error reporting procedure - - When_No_Sources : Error_Warning := Error; - -- Indicates what should be done when there is no Ada sources in a non - -- extending Ada project. - - ALI_Suffix : constant String := ".ali"; - -- File suffix for ali files - - Object_Suffix : constant String := Get_Target_Object_Suffix.all; - -- File suffix for object files - - type Name_Location is record - Name : Name_Id; - Location : Source_Ptr; - Found : Boolean := False; - end record; - -- Information about file names found in string list attribute - -- Source_Files or in a source list file, stored in hash table - -- Source_Names, used by procedure Get_Path_Names_And_Record_Sources. - - No_Name_Location : constant Name_Location := - (Name => No_Name, Location => No_Location, Found => False); - - package Source_Names is new GNAT.HTable.Simple_HTable - (Header_Num => Header_Num, - Element => Name_Location, - No_Element => No_Name_Location, - Key => Name_Id, - Hash => Hash, - Equal => "="); - -- Hash table to store file names found in string list attribute - -- Source_Files or in a source list file, stored in hash table - -- Source_Names, used by procedure Get_Path_Names_And_Record_Sources. - - package Recursive_Dirs is new GNAT.HTable.Simple_HTable - (Header_Num => Header_Num, - Element => Boolean, - No_Element => False, - Key => Name_Id, - Hash => Hash, - Equal => "="); - -- Hash table to store recursive source directories, to avoid looking - -- several times, and to avoid cycles that may be introduced by symbolic - -- links. - - type Ada_Naming_Exception_Id is new Nat; - No_Ada_Naming_Exception : constant Ada_Naming_Exception_Id := 0; - - type Unit_Info is record - Kind : Spec_Or_Body; - Unit : Name_Id; - Next : Ada_Naming_Exception_Id := No_Ada_Naming_Exception; - end record; - -- No_Unit : constant Unit_Info := - -- (Specification, No_Name, No_Ada_Naming_Exception); - - package Ada_Naming_Exception_Table is new Table.Table - (Table_Component_Type => Unit_Info, - Table_Index_Type => Ada_Naming_Exception_Id, - Table_Low_Bound => 1, - Table_Initial => 20, - Table_Increment => 100, - Table_Name => "Prj.Nmsc.Ada_Naming_Exception_Table"); - - package Ada_Naming_Exceptions is new GNAT.HTable.Simple_HTable - (Header_Num => Header_Num, - Element => Ada_Naming_Exception_Id, - No_Element => No_Ada_Naming_Exception, - Key => Name_Id, - Hash => Hash, - Equal => "="); - -- A hash table to store naming exceptions for Ada. For each file name - -- there is one or several unit in table Ada_Naming_Exception_Table. - - function Hash (Unit : Unit_Info) return Header_Num; - - type Name_And_Index is record - Name : Name_Id := No_Name; - Index : Int := 0; - end record; - No_Name_And_Index : constant Name_And_Index := - (Name => No_Name, Index => 0); - - package Reverse_Ada_Naming_Exceptions is new GNAT.HTable.Simple_HTable - (Header_Num => Header_Num, - Element => Name_And_Index, - No_Element => No_Name_And_Index, - Key => Unit_Info, - Hash => Hash, - Equal => "="); - -- A table to check if a unit with an exceptional name will hide - -- a source with a file name following the naming convention. - - function ALI_File_Name (Source : String) return String; - -- Return the ALI file name corresponding to a source - - procedure Check_Ada_Name (Name : String; Unit : out Name_Id); - -- Check that a name is a valid Ada unit name - - procedure Check_Naming_Scheme - (Data : in out Project_Data; - Project : Project_Id; - In_Tree : Project_Tree_Ref); - -- Check the naming scheme part of Data - - procedure Check_Ada_Naming_Scheme_Validity - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Naming : Naming_Data); - -- Check that the package Naming is correct - - procedure Check_For_Source - (File_Name : Name_Id; - Path_Name : Name_Id; - Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - Location : Source_Ptr; - Language : Language_Index; - Suffix : String; - Naming_Exception : Boolean); - -- Check if a file, with name File_Name and path Path_Name, in a source - -- directory is a source for language Language in project Project of - -- project tree In_Tree. ??? - - procedure Check_If_Externally_Built - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data); - -- Check attribute Externally_Built of project Project in project tree - -- In_Tree and modify its data Data if it has the value "true". - - procedure Check_Library_Attributes - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data); - -- Check the library attributes of project Project in project tree In_Tree - -- and modify its data Data accordingly. - - procedure Check_Package_Naming - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data); - -- Check package Naming of project Project in project tree In_Tree and - -- modify its data Data accordingly. - - procedure Check_Programming_Languages - (In_Tree : Project_Tree_Ref; Data : in out Project_Data); - -- Check attribute Languages for the project with data Data in project - -- tree In_Tree and set the components of Data for all the programming - -- languages indicated in attribute Languages, if any. - - function Check_Project - (P : Project_Id; - Root_Project : Project_Id; - In_Tree : Project_Tree_Ref; - Extending : Boolean) return Boolean; - -- Returns True if P is Root_Project or, if Extending is True, a project - -- extended by Root_Project. - - procedure Check_Stand_Alone_Library - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - Extending : Boolean); - -- Check if project Project in project tree In_Tree is a Stand-Alone - -- Library project, and modify its data Data accordingly if it is one. - - function Compute_Directory_Last (Dir : String) return Natural; - -- Return the index of the last significant character in Dir. This is used - -- to avoid duplicates '/' at the end of directory names - - function Body_Suffix_Of - (Language : Language_Index; - In_Project : Project_Data; - In_Tree : Project_Tree_Ref) - return String; - -- Returns the suffix of sources of language Language in project In_Project - -- in project tree In_Tree. - - procedure Error_Msg - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Msg : String; - Flag_Location : Source_Ptr); - -- Output an error message. If Error_Report is null, simply call - -- Prj.Err.Error_Msg. Otherwise, disregard Flag_Location and use - -- Error_Report. - - procedure Find_Sources - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - For_Language : Language_Index; - Follow_Links : Boolean := False); - -- Find all the sources in all of the source directories of a project for - -- a specified language. - - procedure Free_Ada_Naming_Exceptions; - -- Free the internal hash tables used for checking naming exceptions - - procedure Get_Directories - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data); - -- Get the object directory, the exec directory and the source directories - -- of a project. - - procedure Get_Mains - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data); - -- Get the mains of a project from attribute Main, if it exists, and put - -- them in the project data. - - procedure Get_Sources_From_File - (Path : String; - Location : Source_Ptr; - Project : Project_Id; - In_Tree : Project_Tree_Ref); - -- Get the list of sources from a text file and put them in hash table - -- Source_Names. - - procedure Get_Unit - (Canonical_File_Name : Name_Id; - Naming : Naming_Data; - Exception_Id : out Ada_Naming_Exception_Id; - Unit_Name : out Name_Id; - Unit_Kind : out Spec_Or_Body; - Needs_Pragma : out Boolean); - -- Find out, from a file name, the unit name, the unit kind and if a - -- specific SFN pragma is needed. If the file name corresponds to no - -- unit, then Unit_Name will be No_Name. If the file is a multi-unit source - -- or an exception to the naming scheme, then Exception_Id is set to - -- the unit or units that the source contains. - - function Is_Illegal_Suffix - (Suffix : String; - Dot_Replacement_Is_A_Single_Dot : Boolean) return Boolean; - -- Returns True if the string Suffix cannot be used as - -- a spec suffix, a body suffix or a separate suffix. - - procedure Locate_Directory - (Name : Name_Id; - Parent : Name_Id; - Dir : out Name_Id; - Display : out Name_Id); - -- Locate a directory (returns No_Name for Dir and Display if directory - -- does not exist). Name is the directory name. Parent is the root - -- directory, if Name is a relative path name. Dir is the canonical case - -- path name of the directory, Display is the directory path name for - -- display purposes. - - procedure Look_For_Sources - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - Follow_Links : Boolean); - -- Find all the sources of a project - - function Path_Name_Of - (File_Name : Name_Id; - Directory : Name_Id) return String; - -- Returns the path name of a (non project) file. - -- Returns an empty string if file cannot be found. - - procedure Prepare_Ada_Naming_Exceptions - (List : Array_Element_Id; - In_Tree : Project_Tree_Ref; - Kind : Spec_Or_Body); - -- Prepare the internal hash tables used for checking naming exceptions - -- for Ada. Insert all elements of List in the tables. - - function Project_Extends - (Extending : Project_Id; - Extended : Project_Id; - In_Tree : Project_Tree_Ref) return Boolean; - -- Returns True if Extending is extending Extended either directly or - -- indirectly. - - procedure Record_Ada_Source - (File_Name : Name_Id; - Path_Name : Name_Id; - Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - Location : Source_Ptr; - Current_Source : in out String_List_Id; - Source_Recorded : in out Boolean; - Follow_Links : Boolean); - -- Put a unit in the list of units of a project, if the file name - -- corresponds to a valid unit name. - - procedure Record_Other_Sources - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - Language : Language_Index; - Naming_Exceptions : Boolean); - -- Record the sources of a language in a project. - -- When Naming_Exceptions is True, mark the found sources as such, to - -- later remove those that are not named in a list of sources. - - procedure Report_No_Ada_Sources - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Location : Source_Ptr); - -- Report an error or a warning depending on the value of When_No_Sources - - procedure Show_Source_Dirs - (Project : Project_Id; In_Tree : Project_Tree_Ref); - -- List all the source directories of a project - - function Suffix_For - (Language : Language_Index; - Naming : Naming_Data; - In_Tree : Project_Tree_Ref) return Name_Id; - -- Get the suffix for the source of a language from a package naming. - -- If not specified, return the default for the language. - - procedure Warn_If_Not_Sources - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Conventions : Array_Element_Id; - Specs : Boolean; - Extending : Boolean); - -- Check that individual naming conventions apply to immediate - -- sources of the project; if not, issue a warning. - - ------------------- - -- ALI_File_Name -- - ------------------- - - function ALI_File_Name (Source : String) return String is - begin - -- If the source name has an extension, then replace it with - -- the ALI suffix. - - for Index in reverse Source'First + 1 .. Source'Last loop - if Source (Index) = '.' then - return Source (Source'First .. Index - 1) & ALI_Suffix; - end if; - end loop; - - -- If there is no dot, or if it is the first character, just add the - -- ALI suffix. - - return Source & ALI_Suffix; - end ALI_File_Name; - - ----------- - -- Check -- - ----------- - - procedure Check - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Report_Error : Put_Line_Access; - Follow_Links : Boolean; - When_No_Sources : Error_Warning) - is - Data : Project_Data := In_Tree.Projects.Table (Project); - Extending : Boolean := False; - - begin - Nmsc.When_No_Sources := When_No_Sources; - Error_Report := Report_Error; - - Recursive_Dirs.Reset; - - -- Object, exec and source directories - - Get_Directories (Project, In_Tree, Data); - - -- Get the programming languages - - Check_Programming_Languages (In_Tree, Data); - - -- Library attributes - - Check_Library_Attributes (Project, In_Tree, Data); - - Check_If_Externally_Built (Project, In_Tree, Data); - - if Current_Verbosity = High then - Show_Source_Dirs (Project, In_Tree); - end if; - - Check_Package_Naming (Project, In_Tree, Data); - - Extending := Data.Extends /= No_Project; - - Check_Naming_Scheme (Data, Project, In_Tree); - - Prepare_Ada_Naming_Exceptions - (Data.Naming.Bodies, In_Tree, Body_Part); - Prepare_Ada_Naming_Exceptions - (Data.Naming.Specs, In_Tree, Specification); - - -- Find the sources - - if Data.Source_Dirs /= Nil_String then - Look_For_Sources (Project, In_Tree, Data, Follow_Links); - end if; - - if Data.Ada_Sources_Present then - - -- Check that all individual naming conventions apply to sources of - -- this project file. - - Warn_If_Not_Sources - (Project, In_Tree, Data.Naming.Bodies, - Specs => False, - Extending => Extending); - Warn_If_Not_Sources - (Project, In_Tree, Data.Naming.Specs, - Specs => True, - Extending => Extending); - end if; - - -- If it is a library project file, check if it is a standalone library - - if Data.Library then - Check_Stand_Alone_Library (Project, In_Tree, Data, Extending); - end if; - - -- Put the list of Mains, if any, in the project data - - Get_Mains (Project, In_Tree, Data); - - -- Update the project data in the Projects table - - In_Tree.Projects.Table (Project) := Data; - - Free_Ada_Naming_Exceptions; - end Check; - - -------------------- - -- Check_Ada_Name -- - -------------------- - - procedure Check_Ada_Name (Name : String; Unit : out Name_Id) is - The_Name : String := Name; - Real_Name : Name_Id; - Need_Letter : Boolean := True; - Last_Underscore : Boolean := False; - OK : Boolean := The_Name'Length > 0; - - begin - To_Lower (The_Name); - - Name_Len := The_Name'Length; - Name_Buffer (1 .. Name_Len) := The_Name; - Real_Name := Name_Find; - - -- Check first that the given name is not an Ada reserved word - - if Get_Name_Table_Byte (Real_Name) /= 0 - and then Real_Name /= Name_Project - and then Real_Name /= Name_Extends - and then Real_Name /= Name_External - then - Unit := No_Name; - - if Current_Verbosity = High then - Write_Str (The_Name); - Write_Line (" is an Ada reserved word."); - end if; - - return; - end if; - - for Index in The_Name'Range loop - if Need_Letter then - - -- We need a letter (at the beginning, and following a dot), - -- but we don't have one. - - if Is_Letter (The_Name (Index)) then - Need_Letter := False; - - else - OK := False; - - if Current_Verbosity = High then - Write_Int (Types.Int (Index)); - Write_Str (": '"); - Write_Char (The_Name (Index)); - Write_Line ("' is not a letter."); - end if; - - exit; - end if; - - elsif Last_Underscore - and then (The_Name (Index) = '_' or else The_Name (Index) = '.') - then - -- Two underscores are illegal, and a dot cannot follow - -- an underscore. - - OK := False; - - if Current_Verbosity = High then - Write_Int (Types.Int (Index)); - Write_Str (": '"); - Write_Char (The_Name (Index)); - Write_Line ("' is illegal here."); - end if; - - exit; - - elsif The_Name (Index) = '.' then - - -- We need a letter after a dot - - Need_Letter := True; - - elsif The_Name (Index) = '_' then - Last_Underscore := True; - - else - -- We need an letter or a digit - - Last_Underscore := False; - - if not Is_Alphanumeric (The_Name (Index)) then - OK := False; - - if Current_Verbosity = High then - Write_Int (Types.Int (Index)); - Write_Str (": '"); - Write_Char (The_Name (Index)); - Write_Line ("' is not alphanumeric."); - end if; - - exit; - end if; - end if; - end loop; - - -- Cannot end with an underscore or a dot - - OK := OK and then not Need_Letter and then not Last_Underscore; - - if OK then - Unit := Real_Name; - - else - -- Signal a problem with No_Name - - Unit := No_Name; - end if; - end Check_Ada_Name; - - -------------------------------------- - -- Check_Ada_Naming_Scheme_Validity -- - -------------------------------------- - - procedure Check_Ada_Naming_Scheme_Validity - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Naming : Naming_Data) - is - begin - -- Only check if we are not using the Default naming scheme - - if Naming /= In_Tree.Private_Part.Default_Naming then - declare - Dot_Replacement : constant String := - Get_Name_String - (Naming.Dot_Replacement); - - Spec_Suffix : constant String := - Get_Name_String - (Naming.Ada_Spec_Suffix); - - Body_Suffix : constant String := - Get_Name_String - (Naming.Ada_Body_Suffix); - - Separate_Suffix : constant String := - Get_Name_String - (Naming.Separate_Suffix); - - begin - -- Dot_Replacement cannot - -- - be empty - -- - start or end with an alphanumeric - -- - be a single '_' - -- - start with an '_' followed by an alphanumeric - -- - contain a '.' except if it is "." - - if Dot_Replacement'Length = 0 - or else Is_Alphanumeric - (Dot_Replacement (Dot_Replacement'First)) - or else Is_Alphanumeric - (Dot_Replacement (Dot_Replacement'Last)) - or else (Dot_Replacement (Dot_Replacement'First) = '_' - and then - (Dot_Replacement'Length = 1 - or else - Is_Alphanumeric - (Dot_Replacement (Dot_Replacement'First + 1)))) - or else (Dot_Replacement'Length > 1 - and then - Index (Source => Dot_Replacement, - Pattern => ".") /= 0) - then - Error_Msg - (Project, In_Tree, - '"' & Dot_Replacement & - """ is illegal for Dot_Replacement.", - Naming.Dot_Repl_Loc); - end if; - - -- Suffixes cannot - -- - be empty - - if Is_Illegal_Suffix - (Spec_Suffix, Dot_Replacement = ".") - then - Err_Vars.Error_Msg_Name_1 := Naming.Ada_Spec_Suffix; - Error_Msg - (Project, In_Tree, - "{ is illegal for Spec_Suffix", - Naming.Spec_Suffix_Loc); - end if; - - if Is_Illegal_Suffix - (Body_Suffix, Dot_Replacement = ".") - then - Err_Vars.Error_Msg_Name_1 := Naming.Ada_Body_Suffix; - Error_Msg - (Project, In_Tree, - "{ is illegal for Body_Suffix", - Naming.Body_Suffix_Loc); - end if; - - if Body_Suffix /= Separate_Suffix then - if Is_Illegal_Suffix - (Separate_Suffix, Dot_Replacement = ".") - then - Err_Vars.Error_Msg_Name_1 := Naming.Separate_Suffix; - Error_Msg - (Project, In_Tree, - "{ is illegal for Separate_Suffix", - Naming.Sep_Suffix_Loc); - end if; - end if; - - -- Spec_Suffix cannot have the same termination as - -- Body_Suffix or Separate_Suffix - - if Spec_Suffix'Length <= Body_Suffix'Length - and then - Body_Suffix (Body_Suffix'Last - - Spec_Suffix'Length + 1 .. - Body_Suffix'Last) = Spec_Suffix - then - Error_Msg - (Project, In_Tree, - "Body_Suffix (""" & - Body_Suffix & - """) cannot end with" & - " Spec_Suffix (""" & - Spec_Suffix & """).", - Naming.Body_Suffix_Loc); - end if; - - if Body_Suffix /= Separate_Suffix - and then Spec_Suffix'Length <= Separate_Suffix'Length - and then - Separate_Suffix - (Separate_Suffix'Last - Spec_Suffix'Length + 1 - .. - Separate_Suffix'Last) = Spec_Suffix - then - Error_Msg - (Project, In_Tree, - "Separate_Suffix (""" & - Separate_Suffix & - """) cannot end with" & - " Spec_Suffix (""" & - Spec_Suffix & """).", - Naming.Sep_Suffix_Loc); - end if; - end; - end if; - end Check_Ada_Naming_Scheme_Validity; - - ---------------------- - -- Check_For_Source -- - ---------------------- - - procedure Check_For_Source - (File_Name : Name_Id; - Path_Name : Name_Id; - Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - Location : Source_Ptr; - Language : Language_Index; - Suffix : String; - Naming_Exception : Boolean) - is - Name : String := Get_Name_String (File_Name); - Real_Location : Source_Ptr := Location; - - begin - Canonical_Case_File_Name (Name); - - -- A file is a source of a language if Naming_Exception is True (case - -- of naming exceptions) or if its file name ends with the suffix. - - if Naming_Exception or else - (Name'Length > Suffix'Length and then - Name (Name'Last - Suffix'Length + 1 .. Name'Last) = Suffix) - then - if Real_Location = No_Location then - Real_Location := Data.Location; - end if; - - declare - Path : String := Get_Name_String (Path_Name); - - Path_Id : Name_Id; - -- The path name id (in canonical case) - - File_Id : Name_Id; - -- The file name id (in canonical case) - - Obj_Id : Name_Id; - -- The object file name - - Obj_Path_Id : Name_Id; - -- The object path name - - Dep_Id : Name_Id; - -- The dependency file name - - Dep_Path_Id : Name_Id; - -- The dependency path name - - Dot_Pos : Natural := 0; - -- Position of the last dot in Name - - Source : Other_Source; - Source_Id : Other_Source_Id := Data.First_Other_Source; - - begin - Canonical_Case_File_Name (Path); - - -- Get the file name id - - Name_Len := Name'Length; - Name_Buffer (1 .. Name_Len) := Name; - File_Id := Name_Find; - - -- Get the path name id - - Name_Len := Path'Length; - Name_Buffer (1 .. Name_Len) := Path; - Path_Id := Name_Find; - - -- Find the position of the last dot - - for J in reverse Name'Range loop - if Name (J) = '.' then - Dot_Pos := J; - exit; - end if; - end loop; - - if Dot_Pos <= Name'First then - Dot_Pos := Name'Last + 1; - end if; - - -- Compute the object file name - - Get_Name_String (File_Id); - Name_Len := Dot_Pos - Name'First; - - for J in Object_Suffix'Range loop - Name_Len := Name_Len + 1; - Name_Buffer (Name_Len) := Object_Suffix (J); - end loop; - - Obj_Id := Name_Find; - - -- Compute the object path name - - Get_Name_String (Data.Object_Directory); - - if Name_Buffer (Name_Len) /= Directory_Separator and then - Name_Buffer (Name_Len) /= '/' - then - Name_Len := Name_Len + 1; - Name_Buffer (Name_Len) := Directory_Separator; - end if; - - Add_Str_To_Name_Buffer (Get_Name_String (Obj_Id)); - Obj_Path_Id := Name_Find; - - -- Compute the dependency file name - - Get_Name_String (File_Id); - Name_Len := Dot_Pos - Name'First + 1; - Name_Buffer (Name_Len) := '.'; - Name_Len := Name_Len + 1; - Name_Buffer (Name_Len) := 'd'; - Dep_Id := Name_Find; - - -- Compute the dependency path name - - Get_Name_String (Data.Object_Directory); - - if Name_Buffer (Name_Len) /= Directory_Separator and then - Name_Buffer (Name_Len) /= '/' - then - Name_Len := Name_Len + 1; - Name_Buffer (Name_Len) := Directory_Separator; - end if; - - Add_Str_To_Name_Buffer (Get_Name_String (Dep_Id)); - Dep_Path_Id := Name_Find; - - -- Check if source is already in the list of source for this - -- project: it may have already been specified as a naming - -- exception for the same language or an other language, or - -- they may be two identical file names in different source - -- directories. - - while Source_Id /= No_Other_Source loop - Source := In_Tree.Other_Sources.Table (Source_Id); - - if Source.File_Name = File_Id then - - -- Two sources of different languages cannot have the same - -- file name. - - if Source.Language /= Language then - Error_Msg_Name_1 := File_Name; - Error_Msg - (Project, In_Tree, - "{ cannot be a source of several languages", - Real_Location); - return; - - -- No problem if a file has already been specified as - -- a naming exception of this language. - - elsif Source.Path_Name = Path_Id then - - -- Reset the naming exception flag, if this is not a - -- naming exception. - - if not Naming_Exception then - In_Tree.Other_Sources.Table - (Source_Id).Naming_Exception := False; - end if; - - return; - - -- There are several files with the same names, but the - -- order of the source directories is known (no /**): - -- only the first one encountered is kept, the other ones - -- are ignored. - - elsif Data.Known_Order_Of_Source_Dirs then - return; - - -- But it is an error if the order of the source directories - -- is not known. - - else - Error_Msg_Name_1 := File_Name; - Error_Msg - (Project, In_Tree, - "{ is found in several source directories", - Real_Location); - return; - end if; - - -- Two sources with different file names cannot have the same - -- object file name. - - elsif Source.Object_Name = Obj_Id then - Error_Msg_Name_1 := File_Id; - Error_Msg_Name_2 := Source.File_Name; - Error_Msg_Name_3 := Obj_Id; - Error_Msg - (Project, In_Tree, - "{ and { have the same object file {", - Real_Location); - return; - end if; - - Source_Id := Source.Next; - end loop; - - if Current_Verbosity = High then - Write_Str (" found "); - Display_Language_Name (Language); - Write_Str (" source """); - Write_Str (Get_Name_String (File_Name)); - Write_Line (""""); - Write_Str (" object path = "); - Write_Line (Get_Name_String (Obj_Path_Id)); - end if; - - -- Create the Other_Source record - - Source := - (Language => Language, - File_Name => File_Id, - Path_Name => Path_Id, - Source_TS => File_Stamp (Path_Id), - Object_Name => Obj_Id, - Object_Path => Obj_Path_Id, - Object_TS => File_Stamp (Obj_Path_Id), - Dep_Name => Dep_Id, - Dep_Path => Dep_Path_Id, - Dep_TS => File_Stamp (Dep_Path_Id), - Naming_Exception => Naming_Exception, - Next => No_Other_Source); - - -- And add it to the Other_Sources table - - Other_Source_Table.Increment_Last - (In_Tree.Other_Sources); - In_Tree.Other_Sources.Table - (Other_Source_Table.Last (In_Tree.Other_Sources)) := - Source; - - -- There are sources of languages other than Ada in this project - - Data.Other_Sources_Present := True; - - -- And there are sources of this language in this project - - Set (Language, True, Data, In_Tree); - - -- Add this source to the list of sources of languages other than - -- Ada of the project. - - if Data.First_Other_Source = No_Other_Source then - Data.First_Other_Source := - Other_Source_Table.Last (In_Tree.Other_Sources); - - else - In_Tree.Other_Sources.Table (Data.Last_Other_Source).Next := - Other_Source_Table.Last (In_Tree.Other_Sources); - end if; - - Data.Last_Other_Source := - Other_Source_Table.Last (In_Tree.Other_Sources); - end; - end if; - end Check_For_Source; - - ------------------------------- - -- Check_If_Externally_Built -- - ------------------------------- - - procedure Check_If_Externally_Built - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data) - is - Externally_Built : constant Variable_Value := - Util.Value_Of - (Name_Externally_Built, - Data.Decl.Attributes, In_Tree); - - begin - if not Externally_Built.Default then - Get_Name_String (Externally_Built.Value); - To_Lower (Name_Buffer (1 .. Name_Len)); - - if Name_Buffer (1 .. Name_Len) = "true" then - Data.Externally_Built := True; - - elsif Name_Buffer (1 .. Name_Len) /= "false" then - Error_Msg (Project, In_Tree, - "Externally_Built may only be true or false", - Externally_Built.Location); - end if; - end if; - - if Current_Verbosity = High then - Write_Str ("Project is "); - - if not Data.Externally_Built then - Write_Str ("not "); - end if; - - Write_Line ("externally built."); - end if; - end Check_If_Externally_Built; - - ----------------------------- - -- Check_Naming_Scheme -- - ----------------------------- - - procedure Check_Naming_Scheme - (Data : in out Project_Data; - Project : Project_Id; - In_Tree : Project_Tree_Ref) - is - Naming_Id : constant Package_Id := - Util.Value_Of (Name_Naming, Data.Decl.Packages, In_Tree); - - Naming : Package_Element; - - procedure Check_Unit_Names (List : Array_Element_Id); - -- Check that a list of unit names contains only valid names - - ---------------------- - -- Check_Unit_Names -- - ---------------------- - - procedure Check_Unit_Names (List : Array_Element_Id) is - Current : Array_Element_Id := List; - Element : Array_Element; - Unit_Name : Name_Id; - - begin - -- Loop through elements of the string list - - while Current /= No_Array_Element loop - Element := In_Tree.Array_Elements.Table (Current); - - -- Put file name in canonical case - - Get_Name_String (Element.Value.Value); - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Element.Value.Value := Name_Find; - - -- Check that it contains a valid unit name - - Get_Name_String (Element.Index); - Check_Ada_Name (Name_Buffer (1 .. Name_Len), Unit_Name); - - if Unit_Name = No_Name then - Err_Vars.Error_Msg_Name_1 := Element.Index; - Error_Msg - (Project, In_Tree, - "{ is not a valid unit name.", - Element.Value.Location); - - else - if Current_Verbosity = High then - Write_Str (" Unit ("""); - Write_Str (Get_Name_String (Unit_Name)); - Write_Line (""")"); - end if; - - Element.Index := Unit_Name; - In_Tree.Array_Elements.Table (Current) := Element; - end if; - - Current := Element.Next; - end loop; - end Check_Unit_Names; - - -- Start of processing for Check_Naming_Scheme - - begin - -- If there is a package Naming, we will put in Data.Naming what is in - -- this package Naming. - - if Naming_Id /= No_Package then - Naming := In_Tree.Packages.Table (Naming_Id); - - if Current_Verbosity = High then - Write_Line ("Checking ""Naming"" for Ada."); - end if; - - declare - Bodies : constant Array_Element_Id := - Util.Value_Of (Name_Body, Naming.Decl.Arrays, In_Tree); - - Specs : constant Array_Element_Id := - Util.Value_Of (Name_Spec, Naming.Decl.Arrays, In_Tree); - - begin - if Bodies /= No_Array_Element then - - -- We have elements in the array Body_Part - - if Current_Verbosity = High then - Write_Line ("Found Bodies."); - end if; - - Data.Naming.Bodies := Bodies; - Check_Unit_Names (Bodies); - - else - if Current_Verbosity = High then - Write_Line ("No Bodies."); - end if; - end if; - - if Specs /= No_Array_Element then - - -- We have elements in the array Specs - - if Current_Verbosity = High then - Write_Line ("Found Specs."); - end if; - - Data.Naming.Specs := Specs; - Check_Unit_Names (Specs); - - else - if Current_Verbosity = High then - Write_Line ("No Specs."); - end if; - end if; - end; - - -- We are now checking if variables Dot_Replacement, Casing, - -- Spec_Suffix, Body_Suffix and/or Separate_Suffix - -- exist. - - -- For each variable, if it does not exist, we do nothing, - -- because we already have the default. - - -- Check Dot_Replacement - - declare - Dot_Replacement : constant Variable_Value := - Util.Value_Of - (Name_Dot_Replacement, - Naming.Decl.Attributes, In_Tree); - - begin - pragma Assert (Dot_Replacement.Kind = Single, - "Dot_Replacement is not a single string"); - - if not Dot_Replacement.Default then - Get_Name_String (Dot_Replacement.Value); - - if Name_Len = 0 then - Error_Msg - (Project, In_Tree, - "Dot_Replacement cannot be empty", - Dot_Replacement.Location); - - else - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Data.Naming.Dot_Replacement := Name_Find; - Data.Naming.Dot_Repl_Loc := Dot_Replacement.Location; - end if; - end if; - end; - - if Current_Verbosity = High then - Write_Str (" Dot_Replacement = """); - Write_Str (Get_Name_String (Data.Naming.Dot_Replacement)); - Write_Char ('"'); - Write_Eol; - end if; - - -- Check Casing - - declare - Casing_String : constant Variable_Value := - Util.Value_Of - (Name_Casing, Naming.Decl.Attributes, In_Tree); - - begin - pragma Assert (Casing_String.Kind = Single, - "Casing is not a single string"); - - if not Casing_String.Default then - declare - Casing_Image : constant String := - Get_Name_String (Casing_String.Value); - begin - declare - Casing_Value : constant Casing_Type := - Value (Casing_Image); - begin - Data.Naming.Casing := Casing_Value; - end; - - exception - when Constraint_Error => - if Casing_Image'Length = 0 then - Error_Msg - (Project, In_Tree, - "Casing cannot be an empty string", - Casing_String.Location); - - else - Name_Len := Casing_Image'Length; - Name_Buffer (1 .. Name_Len) := Casing_Image; - Err_Vars.Error_Msg_Name_1 := Name_Find; - Error_Msg - (Project, In_Tree, - "{ is not a correct Casing", - Casing_String.Location); - end if; - end; - end if; - end; - - if Current_Verbosity = High then - Write_Str (" Casing = "); - Write_Str (Image (Data.Naming.Casing)); - Write_Char ('.'); - Write_Eol; - end if; - - -- Check Spec_Suffix - - declare - Ada_Spec_Suffix : constant Variable_Value := - Prj.Util.Value_Of - (Index => Name_Ada, - Src_Index => 0, - In_Array => Data.Naming.Spec_Suffix, - In_Tree => In_Tree); - - begin - if Ada_Spec_Suffix.Kind = Single - and then Get_Name_String (Ada_Spec_Suffix.Value) /= "" - then - Get_Name_String (Ada_Spec_Suffix.Value); - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Data.Naming.Ada_Spec_Suffix := Name_Find; - Data.Naming.Spec_Suffix_Loc := Ada_Spec_Suffix.Location; - - else - Data.Naming.Ada_Spec_Suffix := Default_Ada_Spec_Suffix; - end if; - end; - - if Current_Verbosity = High then - Write_Str (" Spec_Suffix = """); - Write_Str (Get_Name_String (Data.Naming.Ada_Spec_Suffix)); - Write_Char ('"'); - Write_Eol; - end if; - - -- Check Body_Suffix - - declare - Ada_Body_Suffix : constant Variable_Value := - Prj.Util.Value_Of - (Index => Name_Ada, - Src_Index => 0, - In_Array => Data.Naming.Body_Suffix, - In_Tree => In_Tree); - - begin - if Ada_Body_Suffix.Kind = Single - and then Get_Name_String (Ada_Body_Suffix.Value) /= "" - then - Get_Name_String (Ada_Body_Suffix.Value); - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Data.Naming.Ada_Body_Suffix := Name_Find; - Data.Naming.Body_Suffix_Loc := Ada_Body_Suffix.Location; - - else - Data.Naming.Ada_Body_Suffix := Default_Ada_Body_Suffix; - end if; - end; - - if Current_Verbosity = High then - Write_Str (" Body_Suffix = """); - Write_Str (Get_Name_String (Data.Naming.Ada_Body_Suffix)); - Write_Char ('"'); - Write_Eol; - end if; - - -- Check Separate_Suffix - - declare - Ada_Sep_Suffix : constant Variable_Value := - Prj.Util.Value_Of - (Variable_Name => Name_Separate_Suffix, - In_Variables => Naming.Decl.Attributes, - In_Tree => In_Tree); - - begin - if Ada_Sep_Suffix.Default then - Data.Naming.Separate_Suffix := - Data.Naming.Ada_Body_Suffix; - - else - Get_Name_String (Ada_Sep_Suffix.Value); - - if Name_Len = 0 then - Error_Msg - (Project, In_Tree, - "Separate_Suffix cannot be empty", - Ada_Sep_Suffix.Location); - - else - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Data.Naming.Separate_Suffix := Name_Find; - Data.Naming.Sep_Suffix_Loc := Ada_Sep_Suffix.Location; - end if; - end if; - end; - - if Current_Verbosity = High then - Write_Str (" Separate_Suffix = """); - Write_Str (Get_Name_String (Data.Naming.Separate_Suffix)); - Write_Char ('"'); - Write_Eol; - end if; - - -- Check if Data.Naming is valid - - Check_Ada_Naming_Scheme_Validity (Project, In_Tree, Data.Naming); - - else - Data.Naming.Ada_Spec_Suffix := Default_Ada_Spec_Suffix; - Data.Naming.Ada_Body_Suffix := Default_Ada_Body_Suffix; - Data.Naming.Separate_Suffix := Default_Ada_Body_Suffix; - end if; - end Check_Naming_Scheme; - - ------------------------------ - -- Check_Library_Attributes -- - ------------------------------ - - procedure Check_Library_Attributes - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data) - is - Attributes : constant Prj.Variable_Id := Data.Decl.Attributes; - - Lib_Dir : constant Prj.Variable_Value := - Prj.Util.Value_Of - (Snames.Name_Library_Dir, Attributes, In_Tree); - - Lib_Name : constant Prj.Variable_Value := - Prj.Util.Value_Of - (Snames.Name_Library_Name, Attributes, In_Tree); - - Lib_Version : constant Prj.Variable_Value := - Prj.Util.Value_Of - (Snames.Name_Library_Version, Attributes, In_Tree); - - Lib_ALI_Dir : constant Prj.Variable_Value := - Prj.Util.Value_Of - (Snames.Name_Library_Ali_Dir, Attributes, In_Tree); - - The_Lib_Kind : constant Prj.Variable_Value := - Prj.Util.Value_Of - (Snames.Name_Library_Kind, Attributes, In_Tree); - - begin - -- Special case of extending project - - if Data.Extends /= No_Project then - declare - Extended_Data : constant Project_Data := - In_Tree.Projects.Table (Data.Extends); - - begin - -- If the project extended is a library project, we inherit - -- the library name, if it is not redefined; we check that - -- the library directory is specified; and we reset the - -- library flag for the extended project. - - if Extended_Data.Library then - if Lib_Name.Default then - Data.Library_Name := Extended_Data.Library_Name; - end if; - - if Lib_Dir.Default then - if not Data.Virtual then - Error_Msg - (Project, In_Tree, - "a project extending a library project must " & - "specify an attribute Library_Dir", - Data.Location); - end if; - end if; - - In_Tree.Projects.Table (Data.Extends).Library := - False; - end if; - end; - end if; - - pragma Assert (Lib_Dir.Kind = Single); - - if Lib_Dir.Value = Empty_String then - if Current_Verbosity = High then - Write_Line ("No library directory"); - end if; - - else - -- Find path name, check that it is a directory - - Locate_Directory - (Lib_Dir.Value, Data.Display_Directory, - Data.Library_Dir, Data.Display_Library_Dir); - - if Data.Library_Dir = No_Name then - - -- Get the absolute name of the library directory that - -- does not exist, to report an error. - - declare - Dir_Name : constant String := Get_Name_String (Lib_Dir.Value); - - begin - if Is_Absolute_Path (Dir_Name) then - Err_Vars.Error_Msg_Name_1 := Lib_Dir.Value; - - else - Get_Name_String (Data.Display_Directory); - - if Name_Buffer (Name_Len) /= Directory_Separator then - Name_Len := Name_Len + 1; - Name_Buffer (Name_Len) := Directory_Separator; - end if; - - Name_Buffer - (Name_Len + 1 .. Name_Len + Dir_Name'Length) := - Dir_Name; - Name_Len := Name_Len + Dir_Name'Length; - Err_Vars.Error_Msg_Name_1 := Name_Find; - end if; - - -- Report the error - - Error_Msg - (Project, In_Tree, - "library directory { does not exist", - Lib_Dir.Location); - end; - - -- The library directory cannot be the same as the Object directory - - elsif Data.Library_Dir = Data.Object_Directory then - Error_Msg - (Project, In_Tree, - "library directory cannot be the same " & - "as object directory", - Lib_Dir.Location); - Data.Library_Dir := No_Name; - Data.Display_Library_Dir := No_Name; - - else - declare - OK : Boolean := True; - Dirs_Id : String_List_Id; - Dir_Elem : String_Element; - - begin - -- The library directory cannot be the same as a source - -- directory of the current project. - - Dirs_Id := Data.Source_Dirs; - while Dirs_Id /= Nil_String loop - Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id); - Dirs_Id := Dir_Elem.Next; - - if Data.Library_Dir = Dir_Elem.Value then - Err_Vars.Error_Msg_Name_1 := Dir_Elem.Value; - Error_Msg - (Project, In_Tree, - "library directory cannot be the same " & - "as source directory {", - Lib_Dir.Location); - OK := False; - exit; - end if; - end loop; - - if OK then - - -- The library directory cannot be the same as a source - -- directory of another project either. - - Project_Loop : - for Pid in 1 .. Project_Table.Last (In_Tree.Projects) loop - if Pid /= Project then - Dirs_Id := In_Tree.Projects.Table (Pid).Source_Dirs; - - Dir_Loop : while Dirs_Id /= Nil_String loop - Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id); - Dirs_Id := Dir_Elem.Next; - - if Data.Library_Dir = Dir_Elem.Value then - Err_Vars.Error_Msg_Name_1 := Dir_Elem.Value; - Err_Vars.Error_Msg_Name_2 := - In_Tree.Projects.Table (Pid).Name; - - Error_Msg - (Project, In_Tree, - "library directory cannot be the same " & - "as source directory { of project {", - Lib_Dir.Location); - OK := False; - exit Project_Loop; - end if; - end loop Dir_Loop; - end if; - end loop Project_Loop; - end if; - - if not OK then - Data.Library_Dir := No_Name; - Data.Display_Library_Dir := No_Name; - - elsif Current_Verbosity = High then - - -- Display the Library directory in high verbosity - - Write_Str ("Library directory ="""); - Write_Str (Get_Name_String (Data.Display_Library_Dir)); - Write_Line (""""); - end if; - end; - end if; - end if; - - pragma Assert (Lib_Name.Kind = Single); - - if Lib_Name.Value = Empty_String then - if Current_Verbosity = High - and then Data.Library_Name = No_Name - then - Write_Line ("No library name"); - end if; - - else - -- There is no restriction on the syntax of library names - - Data.Library_Name := Lib_Name.Value; - end if; - - if Data.Library_Name /= No_Name - and then Current_Verbosity = High - then - Write_Str ("Library name = """); - Write_Str (Get_Name_String (Data.Library_Name)); - Write_Line (""""); - end if; - - Data.Library := - Data.Library_Dir /= No_Name - and then - Data.Library_Name /= No_Name; - - if Data.Library then - if MLib.Tgt.Support_For_Libraries = MLib.Tgt.None then - Error_Msg - (Project, In_Tree, - "?libraries are not supported on this platform", - Lib_Name.Location); - Data.Library := False; - - else - if Lib_ALI_Dir.Value = Empty_String then - if Current_Verbosity = High then - Write_Line ("No library 'A'L'I directory specified"); - end if; - Data.Library_ALI_Dir := Data.Library_Dir; - Data.Display_Library_ALI_Dir := Data.Display_Library_Dir; - - else - -- Find path name, check that it is a directory - - Locate_Directory - (Lib_ALI_Dir.Value, Data.Display_Directory, - Data.Library_ALI_Dir, Data.Display_Library_ALI_Dir); - - if Data.Library_ALI_Dir = No_Name then - - -- Get the absolute name of the library ALI directory that - -- does not exist, to report an error. - - declare - Dir_Name : constant String := - Get_Name_String (Lib_ALI_Dir.Value); - - begin - if Is_Absolute_Path (Dir_Name) then - Err_Vars.Error_Msg_Name_1 := Lib_Dir.Value; - - else - Get_Name_String (Data.Display_Directory); - - if Name_Buffer (Name_Len) /= Directory_Separator then - Name_Len := Name_Len + 1; - Name_Buffer (Name_Len) := Directory_Separator; - end if; - - Name_Buffer - (Name_Len + 1 .. Name_Len + Dir_Name'Length) := - Dir_Name; - Name_Len := Name_Len + Dir_Name'Length; - Err_Vars.Error_Msg_Name_1 := Name_Find; - end if; - - -- Report the error - - Error_Msg - (Project, In_Tree, - "library 'A'L'I directory { does not exist", - Lib_ALI_Dir.Location); - end; - end if; - - if Data.Library_ALI_Dir /= Data.Library_Dir then - - -- The library ALI directory cannot be the same as the - -- Object directory. - - if Data.Library_ALI_Dir = Data.Object_Directory then - Error_Msg - (Project, In_Tree, - "library 'A'L'I directory cannot be the same " & - "as object directory", - Lib_ALI_Dir.Location); - Data.Library_ALI_Dir := No_Name; - Data.Display_Library_ALI_Dir := No_Name; - - else - declare - OK : Boolean := True; - Dirs_Id : String_List_Id; - Dir_Elem : String_Element; - - begin - -- The library ALI directory cannot be the same as - -- a source directory of the current project. - - Dirs_Id := Data.Source_Dirs; - while Dirs_Id /= Nil_String loop - Dir_Elem := In_Tree.String_Elements.Table (Dirs_Id); - Dirs_Id := Dir_Elem.Next; - - if Data.Library_ALI_Dir = Dir_Elem.Value then - Err_Vars.Error_Msg_Name_1 := Dir_Elem.Value; - Error_Msg - (Project, In_Tree, - "library 'A'L'I directory cannot be " & - "the same as source directory {", - Lib_ALI_Dir.Location); - OK := False; - exit; - end if; - end loop; - - if OK then - - -- The library ALI directory cannot be the same as - -- a source directory of another project either. - - ALI_Project_Loop : - for - Pid in 1 .. Project_Table.Last (In_Tree.Projects) - loop - if Pid /= Project then - Dirs_Id := - In_Tree.Projects.Table (Pid).Source_Dirs; - - ALI_Dir_Loop : - while Dirs_Id /= Nil_String loop - Dir_Elem := - In_Tree.String_Elements.Table (Dirs_Id); - Dirs_Id := Dir_Elem.Next; - - if - Data.Library_ALI_Dir = Dir_Elem.Value - then - Err_Vars.Error_Msg_Name_1 := - Dir_Elem.Value; - Err_Vars.Error_Msg_Name_2 := - In_Tree.Projects.Table (Pid).Name; - - Error_Msg - (Project, In_Tree, - "library 'A'L'I directory cannot " & - "be the same as source directory " & - "{ of project {", - Lib_ALI_Dir.Location); - OK := False; - exit ALI_Project_Loop; - end if; - end loop ALI_Dir_Loop; - end if; - end loop ALI_Project_Loop; - end if; - - if not OK then - Data.Library_ALI_Dir := No_Name; - Data.Display_Library_ALI_Dir := No_Name; - - elsif Current_Verbosity = High then - - -- Display the Library ALI directory in high - -- verbosity. - - Write_Str ("Library ALI directory ="""); - Write_Str - (Get_Name_String (Data.Display_Library_ALI_Dir)); - Write_Line (""""); - end if; - end; - end if; - end if; - end if; - - pragma Assert (Lib_Version.Kind = Single); - - if Lib_Version.Value = Empty_String then - if Current_Verbosity = High then - Write_Line ("No library version specified"); - end if; - - else - Data.Lib_Internal_Name := Lib_Version.Value; - end if; - - pragma Assert (The_Lib_Kind.Kind = Single); - - if The_Lib_Kind.Value = Empty_String then - if Current_Verbosity = High then - Write_Line ("No library kind specified"); - end if; - - else - Get_Name_String (The_Lib_Kind.Value); - - declare - Kind_Name : constant String := - To_Lower (Name_Buffer (1 .. Name_Len)); - - OK : Boolean := True; - - begin - if Kind_Name = "static" then - Data.Library_Kind := Static; - - elsif Kind_Name = "dynamic" then - Data.Library_Kind := Dynamic; - - elsif Kind_Name = "relocatable" then - Data.Library_Kind := Relocatable; - - else - Error_Msg - (Project, In_Tree, - "illegal value for Library_Kind", - The_Lib_Kind.Location); - OK := False; - end if; - - if Current_Verbosity = High and then OK then - Write_Str ("Library kind = "); - Write_Line (Kind_Name); - end if; - - if Data.Library_Kind /= Static and then - MLib.Tgt.Support_For_Libraries = MLib.Tgt.Static_Only - then - Error_Msg - (Project, In_Tree, - "only static libraries are supported " & - "on this platform", - The_Lib_Kind.Location); - Data.Library := False; - end if; - end; - end if; - - if Data.Library and then Current_Verbosity = High then - Write_Line ("This is a library project file"); - end if; - - end if; - end if; - end Check_Library_Attributes; - - -------------------------- - -- Check_Package_Naming -- - -------------------------- - - procedure Check_Package_Naming - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data) - is - Naming_Id : constant Package_Id := - Util.Value_Of (Name_Naming, Data.Decl.Packages, In_Tree); - - Naming : Package_Element; - - begin - -- If there is a package Naming, we will put in Data.Naming - -- what is in this package Naming. - - if Naming_Id /= No_Package then - Naming := In_Tree.Packages.Table (Naming_Id); - - if Current_Verbosity = High then - Write_Line ("Checking ""Naming""."); - end if; - - -- Check Spec_Suffix - - declare - Spec_Suffixs : Array_Element_Id := - Util.Value_Of - (Name_Spec_Suffix, - Naming.Decl.Arrays, - In_Tree); - - Suffix : Array_Element_Id; - Element : Array_Element; - Suffix2 : Array_Element_Id; - - begin - -- If some suffixs have been specified, we make sure that - -- for each language for which a default suffix has been - -- specified, there is a suffix specified, either the one - -- in the project file or if there were none, the default. - - if Spec_Suffixs /= No_Array_Element then - Suffix := Data.Naming.Spec_Suffix; - - while Suffix /= No_Array_Element loop - Element := - In_Tree.Array_Elements.Table (Suffix); - Suffix2 := Spec_Suffixs; - - while Suffix2 /= No_Array_Element loop - exit when In_Tree.Array_Elements.Table - (Suffix2).Index = Element.Index; - Suffix2 := In_Tree.Array_Elements.Table - (Suffix2).Next; - end loop; - - -- There is a registered default suffix, but no - -- suffix specified in the project file. - -- Add the default to the array. - - if Suffix2 = No_Array_Element then - Array_Element_Table.Increment_Last - (In_Tree.Array_Elements); - In_Tree.Array_Elements.Table - (Array_Element_Table.Last - (In_Tree.Array_Elements)) := - (Index => Element.Index, - Src_Index => Element.Src_Index, - Index_Case_Sensitive => False, - Value => Element.Value, - Next => Spec_Suffixs); - Spec_Suffixs := Array_Element_Table.Last - (In_Tree.Array_Elements); - end if; - - Suffix := Element.Next; - end loop; - - -- Put the resulting array as the specification suffixs - - Data.Naming.Spec_Suffix := Spec_Suffixs; - end if; - end; - - declare - Current : Array_Element_Id := Data.Naming.Spec_Suffix; - Element : Array_Element; - - begin - while Current /= No_Array_Element loop - Element := In_Tree.Array_Elements.Table (Current); - Get_Name_String (Element.Value.Value); - - if Name_Len = 0 then - Error_Msg - (Project, In_Tree, - "Spec_Suffix cannot be empty", - Element.Value.Location); - end if; - - In_Tree.Array_Elements.Table (Current) := Element; - Current := Element.Next; - end loop; - end; - - -- Check Body_Suffix - - declare - Impl_Suffixs : Array_Element_Id := - Util.Value_Of - (Name_Body_Suffix, - Naming.Decl.Arrays, - In_Tree); - - Suffix : Array_Element_Id; - Element : Array_Element; - Suffix2 : Array_Element_Id; - - begin - -- If some suffixes have been specified, we make sure that - -- for each language for which a default suffix has been - -- specified, there is a suffix specified, either the one - -- in the project file or if there were noe, the default. - - if Impl_Suffixs /= No_Array_Element then - Suffix := Data.Naming.Body_Suffix; - - while Suffix /= No_Array_Element loop - Element := - In_Tree.Array_Elements.Table (Suffix); - Suffix2 := Impl_Suffixs; - - while Suffix2 /= No_Array_Element loop - exit when In_Tree.Array_Elements.Table - (Suffix2).Index = Element.Index; - Suffix2 := In_Tree.Array_Elements.Table - (Suffix2).Next; - end loop; - - -- There is a registered default suffix, but no suffix was - -- specified in the project file. Add the default to the - -- array. - - if Suffix2 = No_Array_Element then - Array_Element_Table.Increment_Last - (In_Tree.Array_Elements); - In_Tree.Array_Elements.Table - (Array_Element_Table.Last - (In_Tree.Array_Elements)) := - (Index => Element.Index, - Src_Index => Element.Src_Index, - Index_Case_Sensitive => False, - Value => Element.Value, - Next => Impl_Suffixs); - Impl_Suffixs := Array_Element_Table.Last - (In_Tree.Array_Elements); - end if; - - Suffix := Element.Next; - end loop; - - -- Put the resulting array as the implementation suffixs - - Data.Naming.Body_Suffix := Impl_Suffixs; - end if; - end; - - declare - Current : Array_Element_Id := Data.Naming.Body_Suffix; - Element : Array_Element; - - begin - while Current /= No_Array_Element loop - Element := In_Tree.Array_Elements.Table (Current); - Get_Name_String (Element.Value.Value); - - if Name_Len = 0 then - Error_Msg - (Project, In_Tree, - "Body_Suffix cannot be empty", - Element.Value.Location); - end if; - - In_Tree.Array_Elements.Table (Current) := Element; - Current := Element.Next; - end loop; - end; - - -- Get the exceptions, if any - - Data.Naming.Specification_Exceptions := - Util.Value_Of - (Name_Specification_Exceptions, - In_Arrays => Naming.Decl.Arrays, - In_Tree => In_Tree); - - Data.Naming.Implementation_Exceptions := - Util.Value_Of - (Name_Implementation_Exceptions, - In_Arrays => Naming.Decl.Arrays, - In_Tree => In_Tree); - end if; - end Check_Package_Naming; - - --------------------------------- - -- Check_Programming_Languages -- - --------------------------------- - - procedure Check_Programming_Languages - (In_Tree : Project_Tree_Ref; - Data : in out Project_Data) - is - Languages : Variable_Value := Nil_Variable_Value; - - begin - Languages := - Prj.Util.Value_Of (Name_Languages, Data.Decl.Attributes, In_Tree); - Data.Ada_Sources_Present := Data.Source_Dirs /= Nil_String; - Data.Other_Sources_Present := Data.Source_Dirs /= Nil_String; - - if Data.Source_Dirs /= Nil_String then - - -- Check if languages are specified in this project - - if Languages.Default then - - -- Attribute Languages is not specified. So, it defaults to - -- a project of language Ada only. - - Data.Languages (Ada_Language_Index) := True; - - -- No sources of languages other than Ada - - Data.Other_Sources_Present := False; - - else - declare - Current : String_List_Id := Languages.Values; - Element : String_Element; - Lang_Name : Name_Id; - Index : Language_Index; - - begin - -- Assume that there is no language specified yet - - Data.Other_Sources_Present := False; - Data.Ada_Sources_Present := False; - - -- Look through all the languages specified in attribute - -- Languages, if any - - while Current /= Nil_String loop - Element := - In_Tree.String_Elements.Table (Current); - Get_Name_String (Element.Value); - To_Lower (Name_Buffer (1 .. Name_Len)); - Lang_Name := Name_Find; - Index := Language_Indexes.Get (Lang_Name); - - if Index = No_Language_Index then - Add_Language_Name (Lang_Name); - Index := Last_Language_Index; - end if; - - Set (Index, True, Data, In_Tree); - Set (Language_Processing => Default_Language_Processing_Data, - For_Language => Index, - In_Project => Data, - In_Tree => In_Tree); - - if Index = Ada_Language_Index then - Data.Ada_Sources_Present := True; - - else - Data.Other_Sources_Present := True; - end if; - - Current := Element.Next; - end loop; - end; - end if; - end if; - end Check_Programming_Languages; - - ------------------- - -- Check_Project -- - ------------------- - - function Check_Project - (P : Project_Id; - Root_Project : Project_Id; - In_Tree : Project_Tree_Ref; - Extending : Boolean) return Boolean - is - begin - if P = Root_Project then - return True; - - elsif Extending then - declare - Data : Project_Data := In_Tree.Projects.Table (Root_Project); - - begin - while Data.Extends /= No_Project loop - if P = Data.Extends then - return True; - end if; - - Data := In_Tree.Projects.Table (Data.Extends); - end loop; - end; - end if; - - return False; - end Check_Project; - - ------------------------------- - -- Check_Stand_Alone_Library -- - ------------------------------- - - procedure Check_Stand_Alone_Library - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - Extending : Boolean) - is - Lib_Interfaces : constant Prj.Variable_Value := - Prj.Util.Value_Of - (Snames.Name_Library_Interface, - Data.Decl.Attributes, - In_Tree); - - Lib_Auto_Init : constant Prj.Variable_Value := - Prj.Util.Value_Of - (Snames.Name_Library_Auto_Init, - Data.Decl.Attributes, - In_Tree); - - Lib_Src_Dir : constant Prj.Variable_Value := - Prj.Util.Value_Of - (Snames.Name_Library_Src_Dir, - Data.Decl.Attributes, - In_Tree); - - Lib_Symbol_File : constant Prj.Variable_Value := - Prj.Util.Value_Of - (Snames.Name_Library_Symbol_File, - Data.Decl.Attributes, - In_Tree); - - Lib_Symbol_Policy : constant Prj.Variable_Value := - Prj.Util.Value_Of - (Snames.Name_Library_Symbol_Policy, - Data.Decl.Attributes, - In_Tree); - - Lib_Ref_Symbol_File : constant Prj.Variable_Value := - Prj.Util.Value_Of - (Snames.Name_Library_Reference_Symbol_File, - Data.Decl.Attributes, - In_Tree); - - Auto_Init_Supported : constant Boolean := - MLib.Tgt. - Standalone_Library_Auto_Init_Is_Supported; - - OK : Boolean := True; - - begin - pragma Assert (Lib_Interfaces.Kind = List); - - -- It is a stand-alone library project file if attribute - -- Library_Interface is defined. - - if not Lib_Interfaces.Default then - SAL_Library : declare - Interfaces : String_List_Id := Lib_Interfaces.Values; - Interface_ALIs : String_List_Id := Nil_String; - Unit : Name_Id; - The_Unit_Id : Unit_Id; - The_Unit_Data : Unit_Data; - - procedure Add_ALI_For (Source : Name_Id); - -- Add an ALI file name to the list of Interface ALIs - - ----------------- - -- Add_ALI_For -- - ----------------- - - procedure Add_ALI_For (Source : Name_Id) is - begin - Get_Name_String (Source); - - declare - ALI : constant String := - ALI_File_Name (Name_Buffer (1 .. Name_Len)); - ALI_Name_Id : Name_Id; - begin - Name_Len := ALI'Length; - Name_Buffer (1 .. Name_Len) := ALI; - ALI_Name_Id := Name_Find; - - String_Element_Table.Increment_Last - (In_Tree.String_Elements); - In_Tree.String_Elements.Table - (String_Element_Table.Last - (In_Tree.String_Elements)) := - (Value => ALI_Name_Id, - Index => 0, - Display_Value => ALI_Name_Id, - Location => - In_Tree.String_Elements.Table - (Interfaces).Location, - Flag => False, - Next => Interface_ALIs); - Interface_ALIs := String_Element_Table.Last - (In_Tree.String_Elements); - end; - end Add_ALI_For; - - -- Start of processing for SAL_Library - - begin - Data.Standalone_Library := True; - - -- Library_Interface cannot be an empty list - - if Interfaces = Nil_String then - Error_Msg - (Project, In_Tree, - "Library_Interface cannot be an empty list", - Lib_Interfaces.Location); - end if; - - -- Process each unit name specified in the attribute - -- Library_Interface. - - while Interfaces /= Nil_String loop - Get_Name_String - (In_Tree.String_Elements.Table - (Interfaces).Value); - To_Lower (Name_Buffer (1 .. Name_Len)); - - if Name_Len = 0 then - Error_Msg - (Project, In_Tree, - "an interface cannot be an empty string", - In_Tree.String_Elements.Table - (Interfaces).Location); - - else - Unit := Name_Find; - Error_Msg_Name_1 := Unit; - The_Unit_Id := - Units_Htable.Get (In_Tree.Units_HT, Unit); - - if The_Unit_Id = No_Unit then - Error_Msg - (Project, In_Tree, - "unknown unit {", - In_Tree.String_Elements.Table - (Interfaces).Location); - - else - -- Check that the unit is part of the project - - The_Unit_Data := - In_Tree.Units.Table (The_Unit_Id); - - if The_Unit_Data.File_Names (Body_Part).Name /= No_Name - and then The_Unit_Data.File_Names (Body_Part).Path /= - Slash - then - if Check_Project - (The_Unit_Data.File_Names (Body_Part).Project, - Project, In_Tree, Extending) - then - -- There is a body for this unit. - -- If there is no spec, we need to check - -- that it is not a subunit. - - if The_Unit_Data.File_Names - (Specification).Name = No_Name - then - declare - Src_Ind : Source_File_Index; - - begin - Src_Ind := Sinput.P.Load_Project_File - (Get_Name_String - (The_Unit_Data.File_Names - (Body_Part).Path)); - - if Sinput.P.Source_File_Is_Subunit - (Src_Ind) - then - Error_Msg - (Project, In_Tree, - "{ is a subunit; " & - "it cannot be an interface", - In_Tree. - String_Elements.Table - (Interfaces).Location); - end if; - end; - end if; - - -- The unit is not a subunit, so we add - -- to the Interface ALIs the ALI file - -- corresponding to the body. - - Add_ALI_For - (The_Unit_Data.File_Names (Body_Part).Name); - - else - Error_Msg - (Project, In_Tree, - "{ is not an unit of this project", - In_Tree.String_Elements.Table - (Interfaces).Location); - end if; - - elsif The_Unit_Data.File_Names - (Specification).Name /= No_Name - and then The_Unit_Data.File_Names - (Specification).Path /= Slash - and then Check_Project - (The_Unit_Data.File_Names - (Specification).Project, - Project, In_Tree, Extending) - - then - -- The unit is part of the project, it has - -- a spec, but no body. We add to the Interface - -- ALIs the ALI file corresponding to the spec. - - Add_ALI_For - (The_Unit_Data.File_Names (Specification).Name); - - else - Error_Msg - (Project, In_Tree, - "{ is not an unit of this project", - In_Tree.String_Elements.Table - (Interfaces).Location); - end if; - end if; - - end if; - - Interfaces := - In_Tree.String_Elements.Table (Interfaces).Next; - end loop; - - -- Put the list of Interface ALIs in the project data - - Data.Lib_Interface_ALIs := Interface_ALIs; - - -- Check value of attribute Library_Auto_Init and set - -- Lib_Auto_Init accordingly. - - if Lib_Auto_Init.Default then - - -- If no attribute Library_Auto_Init is declared, then - -- set auto init only if it is supported. - - Data.Lib_Auto_Init := Auto_Init_Supported; - - else - Get_Name_String (Lib_Auto_Init.Value); - To_Lower (Name_Buffer (1 .. Name_Len)); - - if Name_Buffer (1 .. Name_Len) = "false" then - Data.Lib_Auto_Init := False; - - elsif Name_Buffer (1 .. Name_Len) = "true" then - if Auto_Init_Supported then - Data.Lib_Auto_Init := True; - - else - -- Library_Auto_Init cannot be "true" if auto init - -- is not supported - - Error_Msg - (Project, In_Tree, - "library auto init not supported " & - "on this platform", - Lib_Auto_Init.Location); - end if; - - else - Error_Msg - (Project, In_Tree, - "invalid value for attribute Library_Auto_Init", - Lib_Auto_Init.Location); - end if; - end if; - end SAL_Library; - - -- If attribute Library_Src_Dir is defined and not the - -- empty string, check if the directory exist and is not - -- the object directory or one of the source directories. - -- This is the directory where copies of the interface - -- sources will be copied. Note that this directory may be - -- the library directory. - - if Lib_Src_Dir.Value /= Empty_String then - declare - Dir_Id : constant Name_Id := Lib_Src_Dir.Value; - - begin - Locate_Directory - (Dir_Id, Data.Display_Directory, - Data.Library_Src_Dir, - Data.Display_Library_Src_Dir); - - -- If directory does not exist, report an error - - if Data.Library_Src_Dir = No_Name then - - -- Get the absolute name of the library directory - -- that does not exist, to report an error. - - declare - Dir_Name : constant String := - Get_Name_String (Dir_Id); - - begin - if Is_Absolute_Path (Dir_Name) then - Err_Vars.Error_Msg_Name_1 := Dir_Id; - - else - Get_Name_String (Data.Directory); - - if Name_Buffer (Name_Len) /= - Directory_Separator - then - Name_Len := Name_Len + 1; - Name_Buffer (Name_Len) := - Directory_Separator; - end if; - - Name_Buffer - (Name_Len + 1 .. - Name_Len + Dir_Name'Length) := - Dir_Name; - Name_Len := Name_Len + Dir_Name'Length; - Err_Vars.Error_Msg_Name_1 := Name_Find; - end if; - - -- Report the error - - Error_Msg - (Project, In_Tree, - "Directory { does not exist", - Lib_Src_Dir.Location); - end; - - -- Report an error if it is the same as the object - -- directory. - - elsif Data.Library_Src_Dir = Data.Object_Directory then - Error_Msg - (Project, In_Tree, - "directory to copy interfaces cannot be " & - "the object directory", - Lib_Src_Dir.Location); - Data.Library_Src_Dir := No_Name; - - else - declare - Src_Dirs : String_List_Id; - Src_Dir : String_Element; - - begin - -- Interface copy directory cannot be one of the source - -- directory of the current project. - - Src_Dirs := Data.Source_Dirs; - while Src_Dirs /= Nil_String loop - Src_Dir := In_Tree.String_Elements.Table - (Src_Dirs); - - -- Report error if it is one of the source directories - - if Data.Library_Src_Dir = Src_Dir.Value then - Error_Msg - (Project, In_Tree, - "directory to copy interfaces cannot " & - "be one of the source directories", - Lib_Src_Dir.Location); - Data.Library_Src_Dir := No_Name; - exit; - end if; - - Src_Dirs := Src_Dir.Next; - end loop; - - if Data.Library_Src_Dir /= No_Name then - - -- It cannot be a source directory of any other - -- project either. - - Project_Loop : for Pid in 1 .. - Project_Table.Last (In_Tree.Projects) - loop - Src_Dirs := - In_Tree.Projects.Table (Pid).Source_Dirs; - Dir_Loop : while Src_Dirs /= Nil_String loop - Src_Dir := - In_Tree.String_Elements.Table (Src_Dirs); - - -- Report error if it is one of the source - -- directories - - if Data.Library_Src_Dir = Src_Dir.Value then - Error_Msg_Name_1 := Src_Dir.Value; - Error_Msg_Name_2 := - In_Tree.Projects.Table (Pid).Name; - Error_Msg - (Project, In_Tree, - "directory to copy interfaces cannot " & - "be the same as source directory { of " & - "project {", - Lib_Src_Dir.Location); - Data.Library_Src_Dir := No_Name; - exit Project_Loop; - end if; - - Src_Dirs := Src_Dir.Next; - end loop Dir_Loop; - end loop Project_Loop; - end if; - end; - - -- In high verbosity, if there is a valid Library_Src_Dir, - -- display its path name. - - if Data.Library_Src_Dir /= No_Name - and then Current_Verbosity = High - then - Write_Str ("Directory to copy interfaces ="""); - Write_Str (Get_Name_String (Data.Library_Src_Dir)); - Write_Line (""""); - end if; - end if; - end; - end if; - - -- Check the symbol related attributes - - -- First, the symbol policy - - if not Lib_Symbol_Policy.Default then - declare - Value : constant String := - To_Lower - (Get_Name_String (Lib_Symbol_Policy.Value)); - - begin - -- Symbol policy must hove one of a limited number of values - - if Value = "autonomous" or else Value = "default" then - Data.Symbol_Data.Symbol_Policy := Autonomous; - - elsif Value = "compliant" then - Data.Symbol_Data.Symbol_Policy := Compliant; - - elsif Value = "controlled" then - Data.Symbol_Data.Symbol_Policy := Controlled; - - elsif Value = "restricted" then - Data.Symbol_Data.Symbol_Policy := Restricted; - - else - Error_Msg - (Project, In_Tree, - "illegal value for Library_Symbol_Policy", - Lib_Symbol_Policy.Location); - end if; - end; - end if; - - -- If attribute Library_Symbol_File is not specified, symbol policy - -- cannot be Restricted. - - if Lib_Symbol_File.Default then - if Data.Symbol_Data.Symbol_Policy = Restricted then - Error_Msg - (Project, In_Tree, - "Library_Symbol_File needs to be defined when " & - "symbol policy is Restricted", - Lib_Symbol_Policy.Location); - end if; - - else - -- Library_Symbol_File is defined. Check that the file exists - - Data.Symbol_Data.Symbol_File := Lib_Symbol_File.Value; - - Get_Name_String (Lib_Symbol_File.Value); - - if Name_Len = 0 then - Error_Msg - (Project, In_Tree, - "symbol file name cannot be an empty string", - Lib_Symbol_File.Location); - - else - OK := not Is_Absolute_Path (Name_Buffer (1 .. Name_Len)); - - if OK then - for J in 1 .. Name_Len loop - if Name_Buffer (J) = '/' - or else Name_Buffer (J) = Directory_Separator - then - OK := False; - exit; - end if; - end loop; - end if; - - if not OK then - Error_Msg_Name_1 := Lib_Symbol_File.Value; - Error_Msg - (Project, In_Tree, - "symbol file name { is illegal. " & - "Name canot include directory info.", - Lib_Symbol_File.Location); - end if; - end if; - end if; - - -- If attribute Library_Reference_Symbol_File is not defined, - -- symbol policy cannot be Compilant or Controlled. - - if Lib_Ref_Symbol_File.Default then - if Data.Symbol_Data.Symbol_Policy = Compliant - or else Data.Symbol_Data.Symbol_Policy = Controlled - then - Error_Msg - (Project, In_Tree, - "a reference symbol file need to be defined", - Lib_Symbol_Policy.Location); - end if; - - else - -- Library_Reference_Symbol_File is defined, check file exists - - Data.Symbol_Data.Reference := Lib_Ref_Symbol_File.Value; - - Get_Name_String (Lib_Ref_Symbol_File.Value); - - if Name_Len = 0 then - Error_Msg - (Project, In_Tree, - "reference symbol file name cannot be an empty string", - Lib_Symbol_File.Location); - - else - OK := not Is_Absolute_Path (Name_Buffer (1 .. Name_Len)); - - if OK then - for J in 1 .. Name_Len loop - if Name_Buffer (J) = '/' - or else Name_Buffer (J) = Directory_Separator - then - OK := False; - exit; - end if; - end loop; - end if; - - if not OK then - Error_Msg_Name_1 := Lib_Ref_Symbol_File.Value; - Error_Msg - (Project, In_Tree, - "reference symbol file { name is illegal. " & - "Name canot include directory info.", - Lib_Ref_Symbol_File.Location); - end if; - - if not Is_Regular_File - (Get_Name_String (Data.Object_Directory) & - Directory_Separator & - Get_Name_String (Lib_Ref_Symbol_File.Value)) - then - Error_Msg_Name_1 := Lib_Ref_Symbol_File.Value; - - -- For controlled symbol policy, it is an error if the - -- reference symbol file does not exist. For other symbol - -- policies, this is just a warning - - Error_Msg_Warn := - Data.Symbol_Data.Symbol_Policy /= Controlled; - - Error_Msg - (Project, In_Tree, - "<library reference symbol file { does not exist", - Lib_Ref_Symbol_File.Location); - - -- In addition in the non-controlled case, if symbol policy - -- is Compliant, it is changed to Autonomous, because there - -- is no reference to check against, and we don't want to - -- fail in this case. - - if Data.Symbol_Data.Symbol_Policy /= Controlled then - if Data.Symbol_Data.Symbol_Policy = Compliant then - Data.Symbol_Data.Symbol_Policy := Autonomous; - end if; - end if; - end if; - end if; - end if; - end if; - end Check_Stand_Alone_Library; - - ---------------------------- - -- Compute_Directory_Last -- - ---------------------------- - - function Compute_Directory_Last (Dir : String) return Natural is - begin - if Dir'Length > 1 - and then (Dir (Dir'Last - 1) = Directory_Separator - or else Dir (Dir'Last - 1) = '/') - then - return Dir'Last - 1; - else - return Dir'Last; - end if; - end Compute_Directory_Last; - - -------------------- - -- Body_Suffix_Of -- - -------------------- - - function Body_Suffix_Of - (Language : Language_Index; - In_Project : Project_Data; - In_Tree : Project_Tree_Ref) return String - is - Suffix_Id : constant Name_Id := - Suffix_Of (Language, In_Project, In_Tree); - begin - if Suffix_Id /= No_Name then - return Get_Name_String (Suffix_Id); - else - return "." & Get_Name_String (Language_Names.Table (Language)); - end if; - end Body_Suffix_Of; - - --------------- - -- Error_Msg -- - --------------- - - procedure Error_Msg - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Msg : String; - Flag_Location : Source_Ptr) - is - Real_Location : Source_Ptr := Flag_Location; - Error_Buffer : String (1 .. 5_000); - Error_Last : Natural := 0; - Msg_Name : Natural := 0; - First : Positive := Msg'First; - - procedure Add (C : Character); - -- Add a character to the buffer - - procedure Add (S : String); - -- Add a string to the buffer - - procedure Add (Id : Name_Id); - -- Add a name to the buffer - - --------- - -- Add -- - --------- - - procedure Add (C : Character) is - begin - Error_Last := Error_Last + 1; - Error_Buffer (Error_Last) := C; - end Add; - - procedure Add (S : String) is - begin - Error_Buffer (Error_Last + 1 .. Error_Last + S'Length) := S; - Error_Last := Error_Last + S'Length; - end Add; - - procedure Add (Id : Name_Id) is - begin - Get_Name_String (Id); - Add (Name_Buffer (1 .. Name_Len)); - end Add; - - -- Start of processing for Error_Msg - - begin - -- If location of error is unknown, use the location of the project - - if Real_Location = No_Location then - Real_Location := In_Tree.Projects.Table (Project).Location; - end if; - - if Error_Report = null then - Prj.Err.Error_Msg (Msg, Real_Location); - return; - end if; - - -- Ignore continuation character - - if Msg (First) = '\' then - First := First + 1; - - -- Warniung character is always the first one in this package - -- this is an undoocumented kludge!!! - - elsif Msg (First) = '?' then - First := First + 1; - Add ("Warning: "); - - elsif Msg (First) = '<' then - First := First + 1; - - if Err_Vars.Error_Msg_Warn then - Add ("Warning: "); - end if; - end if; - - for Index in First .. Msg'Last loop - if Msg (Index) = '{' or else Msg (Index) = '%' then - - -- Include a name between double quotes - - Msg_Name := Msg_Name + 1; - Add ('"'); - - case Msg_Name is - when 1 => Add (Err_Vars.Error_Msg_Name_1); - when 2 => Add (Err_Vars.Error_Msg_Name_2); - when 3 => Add (Err_Vars.Error_Msg_Name_3); - - when others => null; - end case; - - Add ('"'); - - else - Add (Msg (Index)); - end if; - - end loop; - - Error_Report (Error_Buffer (1 .. Error_Last), Project, In_Tree); - end Error_Msg; - - ------------------ - -- Find_Sources -- - ------------------ - - procedure Find_Sources - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - For_Language : Language_Index; - Follow_Links : Boolean := False) - is - Source_Dir : String_List_Id := Data.Source_Dirs; - Element : String_Element; - Dir : Dir_Type; - Current_Source : String_List_Id := Nil_String; - Source_Recorded : Boolean := False; - - begin - if Current_Verbosity = High then - Write_Line ("Looking for sources:"); - end if; - - -- For each subdirectory - - while Source_Dir /= Nil_String loop - begin - Source_Recorded := False; - Element := In_Tree.String_Elements.Table (Source_Dir); - if Element.Value /= No_Name then - Get_Name_String (Element.Display_Value); - - declare - Source_Directory : constant String := - Name_Buffer (1 .. Name_Len) & Directory_Separator; - Dir_Last : constant Natural := - Compute_Directory_Last (Source_Directory); - - begin - if Current_Verbosity = High then - Write_Str ("Source_Dir = "); - Write_Line (Source_Directory); - end if; - - -- We look to every entry in the source directory - - Open (Dir, Source_Directory - (Source_Directory'First .. Dir_Last)); - - loop - Read (Dir, Name_Buffer, Name_Len); - - if Current_Verbosity = High then - Write_Str (" Checking "); - Write_Line (Name_Buffer (1 .. Name_Len)); - end if; - - exit when Name_Len = 0; - - declare - File_Name : constant Name_Id := Name_Find; - Path : constant String := - Normalize_Pathname - (Name => Name_Buffer (1 .. Name_Len), - Directory => Source_Directory - (Source_Directory'First .. Dir_Last), - Resolve_Links => Follow_Links, - Case_Sensitive => True); - Path_Name : Name_Id; - - begin - Name_Len := Path'Length; - Name_Buffer (1 .. Name_Len) := Path; - Path_Name := Name_Find; - - if For_Language = Ada_Language_Index then - - -- We attempt to register it as a source. However, - -- there is no error if the file does not contain - -- a valid source. But there is an error if we have - -- a duplicate unit name. - - Record_Ada_Source - (File_Name => File_Name, - Path_Name => Path_Name, - Project => Project, - In_Tree => In_Tree, - Data => Data, - Location => No_Location, - Current_Source => Current_Source, - Source_Recorded => Source_Recorded, - Follow_Links => Follow_Links); - - else - Check_For_Source - (File_Name => File_Name, - Path_Name => Path_Name, - Project => Project, - In_Tree => In_Tree, - Data => Data, - Location => No_Location, - Language => For_Language, - Suffix => - Body_Suffix_Of (For_Language, Data, In_Tree), - Naming_Exception => False); - end if; - end; - end loop; - - Close (Dir); - end; - end if; - - exception - when Directory_Error => - null; - end; - - if Source_Recorded then - In_Tree.String_Elements.Table (Source_Dir).Flag := - True; - end if; - - Source_Dir := Element.Next; - end loop; - - if Current_Verbosity = High then - Write_Line ("end Looking for sources."); - end if; - - if For_Language = Ada_Language_Index then - - -- If we have looked for sources and found none, then - -- it is an error, except if it is an extending project. - -- If a non extending project is not supposed to contain - -- any source, then we never call Find_Sources. - - if Current_Source /= Nil_String then - Data.Ada_Sources_Present := True; - - elsif Data.Extends = No_Project then - Report_No_Ada_Sources (Project, In_Tree, Data.Location); - end if; - end if; - end Find_Sources; - - -------------------------------- - -- Free_Ada_Naming_Exceptions -- - -------------------------------- - - procedure Free_Ada_Naming_Exceptions is - begin - Ada_Naming_Exception_Table.Set_Last (0); - Ada_Naming_Exceptions.Reset; - Reverse_Ada_Naming_Exceptions.Reset; - end Free_Ada_Naming_Exceptions; - - --------------------- - -- Get_Directories -- - --------------------- - - procedure Get_Directories - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data) - is - Object_Dir : constant Variable_Value := - Util.Value_Of - (Name_Object_Dir, Data.Decl.Attributes, In_Tree); - - Exec_Dir : constant Variable_Value := - Util.Value_Of - (Name_Exec_Dir, Data.Decl.Attributes, In_Tree); - - Source_Dirs : constant Variable_Value := - Util.Value_Of - (Name_Source_Dirs, Data.Decl.Attributes, In_Tree); - - Last_Source_Dir : String_List_Id := Nil_String; - - procedure Find_Source_Dirs (From : Name_Id; Location : Source_Ptr); - -- Find one or several source directories, and add them - -- to the list of source directories of the project. - - ---------------------- - -- Find_Source_Dirs -- - ---------------------- - - procedure Find_Source_Dirs (From : Name_Id; Location : Source_Ptr) is - Directory : constant String := Get_Name_String (From); - Element : String_Element; - - procedure Recursive_Find_Dirs (Path : Name_Id); - -- Find all the subdirectories (recursively) of Path and add them - -- to the list of source directories of the project. - - ------------------------- - -- Recursive_Find_Dirs -- - ------------------------- - - procedure Recursive_Find_Dirs (Path : Name_Id) is - Dir : Dir_Type; - Name : String (1 .. 250); - Last : Natural; - List : String_List_Id := Data.Source_Dirs; - Element : String_Element; - Found : Boolean := False; - - Non_Canonical_Path : Name_Id := No_Name; - Canonical_Path : Name_Id := No_Name; - - The_Path : constant String := - Normalize_Pathname (Get_Name_String (Path)) & - Directory_Separator; - - The_Path_Last : constant Natural := - Compute_Directory_Last (The_Path); - - begin - Name_Len := The_Path_Last - The_Path'First + 1; - Name_Buffer (1 .. Name_Len) := - The_Path (The_Path'First .. The_Path_Last); - Non_Canonical_Path := Name_Find; - Get_Name_String (Non_Canonical_Path); - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Canonical_Path := Name_Find; - - -- To avoid processing the same directory several times, check - -- if the directory is already in Recursive_Dirs. If it is, - -- then there is nothing to do, just return. If it is not, put - -- it there and continue recursive processing. - - if Recursive_Dirs.Get (Canonical_Path) then - return; - - else - Recursive_Dirs.Set (Canonical_Path, True); - end if; - - -- Check if directory is already in list - - while List /= Nil_String loop - Element := In_Tree.String_Elements.Table (List); - - if Element.Value /= No_Name then - Found := Element.Value = Canonical_Path; - exit when Found; - end if; - - List := Element.Next; - end loop; - - -- If directory is not already in list, put it there - - if not Found then - if Current_Verbosity = High then - Write_Str (" "); - Write_Line (The_Path (The_Path'First .. The_Path_Last)); - end if; - - String_Element_Table.Increment_Last - (In_Tree.String_Elements); - Element := - (Value => Canonical_Path, - Display_Value => Non_Canonical_Path, - Location => No_Location, - Flag => False, - Next => Nil_String, - Index => 0); - - -- Case of first source directory - - if Last_Source_Dir = Nil_String then - Data.Source_Dirs := String_Element_Table.Last - (In_Tree.String_Elements); - - -- Here we already have source directories - - else - -- Link the previous last to the new one - - In_Tree.String_Elements.Table - (Last_Source_Dir).Next := - String_Element_Table.Last - (In_Tree.String_Elements); - end if; - - -- And register this source directory as the new last - - Last_Source_Dir := String_Element_Table.Last - (In_Tree.String_Elements); - In_Tree.String_Elements.Table (Last_Source_Dir) := - Element; - end if; - - -- Now look for subdirectories. We do that even when this - -- directory is already in the list, because some of its - -- subdirectories may not be in the list yet. - - Open (Dir, The_Path (The_Path'First .. The_Path_Last)); - - loop - Read (Dir, Name, Last); - exit when Last = 0; - - if Name (1 .. Last) /= "." - and then Name (1 .. Last) /= ".." - then - -- Avoid . and .. directories - - if Current_Verbosity = High then - Write_Str (" Checking "); - Write_Line (Name (1 .. Last)); - end if; - - declare - Path_Name : constant String := - Normalize_Pathname - (Name => Name (1 .. Last), - Directory => - The_Path - (The_Path'First .. The_Path_Last), - Resolve_Links => False, - Case_Sensitive => True); - - begin - if Is_Directory (Path_Name) then - - -- We have found a new subdirectory, call self - - Name_Len := Path_Name'Length; - Name_Buffer (1 .. Name_Len) := Path_Name; - Recursive_Find_Dirs (Name_Find); - end if; - end; - end if; - end loop; - - Close (Dir); - - exception - when Directory_Error => - null; - end Recursive_Find_Dirs; - - -- Start of processing for Find_Source_Dirs - - begin - if Current_Verbosity = High then - Write_Str ("Find_Source_Dirs ("""); - Write_Str (Directory); - Write_Line (""")"); - end if; - - -- First, check if we are looking for a directory tree, - -- indicated by "/**" at the end. - - if Directory'Length >= 3 - and then Directory (Directory'Last - 1 .. Directory'Last) = "**" - and then (Directory (Directory'Last - 2) = '/' - or else - Directory (Directory'Last - 2) = Directory_Separator) - then - Data.Known_Order_Of_Source_Dirs := False; - - Name_Len := Directory'Length - 3; - - if Name_Len = 0 then - - -- This is the case of "/**": all directories - -- in the file system. - - Name_Len := 1; - Name_Buffer (1) := Directory (Directory'First); - - else - Name_Buffer (1 .. Name_Len) := - Directory (Directory'First .. Directory'Last - 3); - end if; - - if Current_Verbosity = High then - Write_Str ("Looking for all subdirectories of """); - Write_Str (Name_Buffer (1 .. Name_Len)); - Write_Line (""""); - end if; - - declare - Base_Dir : constant Name_Id := Name_Find; - Root_Dir : constant String := - Normalize_Pathname - (Name => Get_Name_String (Base_Dir), - Directory => - Get_Name_String (Data.Display_Directory), - Resolve_Links => False, - Case_Sensitive => True); - - begin - if Root_Dir'Length = 0 then - Err_Vars.Error_Msg_Name_1 := Base_Dir; - - if Location = No_Location then - Error_Msg - (Project, In_Tree, - "{ is not a valid directory.", - Data.Location); - else - Error_Msg - (Project, In_Tree, - "{ is not a valid directory.", - Location); - end if; - - else - -- We have an existing directory, we register it and all - -- of its subdirectories. - - if Current_Verbosity = High then - Write_Line ("Looking for source directories:"); - end if; - - Name_Len := Root_Dir'Length; - Name_Buffer (1 .. Name_Len) := Root_Dir; - Recursive_Find_Dirs (Name_Find); - - if Current_Verbosity = High then - Write_Line ("End of looking for source directories."); - end if; - end if; - end; - - -- We have a single directory - - else - declare - Path_Name : Name_Id; - Display_Path_Name : Name_Id; - - begin - Locate_Directory - (From, Data.Display_Directory, Path_Name, Display_Path_Name); - - if Path_Name = No_Name then - Err_Vars.Error_Msg_Name_1 := From; - - if Location = No_Location then - Error_Msg - (Project, In_Tree, - "{ is not a valid directory", - Data.Location); - else - Error_Msg - (Project, In_Tree, - "{ is not a valid directory", - Location); - end if; - - else - -- As it is an existing directory, we add it to - -- the list of directories. - - String_Element_Table.Increment_Last - (In_Tree.String_Elements); - Element.Value := Path_Name; - Element.Display_Value := Display_Path_Name; - - if Last_Source_Dir = Nil_String then - - -- This is the first source directory - - Data.Source_Dirs := String_Element_Table.Last - (In_Tree.String_Elements); - - else - -- We already have source directories, - -- link the previous last to the new one. - - In_Tree.String_Elements.Table - (Last_Source_Dir).Next := - String_Element_Table.Last - (In_Tree.String_Elements); - end if; - - -- And register this source directory as the new last - - Last_Source_Dir := String_Element_Table.Last - (In_Tree.String_Elements); - In_Tree.String_Elements.Table - (Last_Source_Dir) := Element; - end if; - end; - end if; - end Find_Source_Dirs; - - -- Start of processing for Get_Directories - - begin - if Current_Verbosity = High then - Write_Line ("Starting to look for directories"); - end if; - - -- Check the object directory - - pragma Assert (Object_Dir.Kind = Single, - "Object_Dir is not a single string"); - - -- We set the object directory to its default - - Data.Object_Directory := Data.Directory; - Data.Display_Object_Dir := Data.Display_Directory; - - if Object_Dir.Value /= Empty_String then - Get_Name_String (Object_Dir.Value); - - if Name_Len = 0 then - Error_Msg - (Project, In_Tree, - "Object_Dir cannot be empty", - Object_Dir.Location); - - else - -- We check that the specified object directory does exist - - Locate_Directory - (Object_Dir.Value, Data.Display_Directory, - Data.Object_Directory, Data.Display_Object_Dir); - - if Data.Object_Directory = No_Name then - - -- The object directory does not exist, report an error - - Err_Vars.Error_Msg_Name_1 := Object_Dir.Value; - Error_Msg - (Project, In_Tree, - "the object directory { cannot be found", - Data.Location); - - -- Do not keep a nil Object_Directory. Set it to the specified - -- (relative or absolute) path. This is for the benefit of - -- tools that recover from errors; for example, these tools - -- could create the non existent directory. - - Data.Display_Object_Dir := Object_Dir.Value; - Get_Name_String (Object_Dir.Value); - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Data.Object_Directory := Name_Find; - end if; - end if; - end if; - - if Current_Verbosity = High then - if Data.Object_Directory = No_Name then - Write_Line ("No object directory"); - else - Write_Str ("Object directory: """); - Write_Str (Get_Name_String (Data.Display_Object_Dir)); - Write_Line (""""); - end if; - end if; - - -- Check the exec directory - - pragma Assert (Exec_Dir.Kind = Single, - "Exec_Dir is not a single string"); - - -- We set the object directory to its default - - Data.Exec_Directory := Data.Object_Directory; - Data.Display_Exec_Dir := Data.Display_Object_Dir; - - if Exec_Dir.Value /= Empty_String then - Get_Name_String (Exec_Dir.Value); - - if Name_Len = 0 then - Error_Msg - (Project, In_Tree, - "Exec_Dir cannot be empty", - Exec_Dir.Location); - - else - -- We check that the specified object directory - -- does exist. - - Locate_Directory - (Exec_Dir.Value, Data.Directory, - Data.Exec_Directory, Data.Display_Exec_Dir); - - if Data.Exec_Directory = No_Name then - Err_Vars.Error_Msg_Name_1 := Exec_Dir.Value; - Error_Msg - (Project, In_Tree, - "the exec directory { cannot be found", - Data.Location); - end if; - end if; - end if; - - if Current_Verbosity = High then - if Data.Exec_Directory = No_Name then - Write_Line ("No exec directory"); - else - Write_Str ("Exec directory: """); - Write_Str (Get_Name_String (Data.Display_Exec_Dir)); - Write_Line (""""); - end if; - end if; - - -- Look for the source directories - - if Current_Verbosity = High then - Write_Line ("Starting to look for source directories"); - end if; - - pragma Assert (Source_Dirs.Kind = List, "Source_Dirs is not a list"); - - if Source_Dirs.Default then - - -- No Source_Dirs specified: the single source directory - -- is the one containing the project file - - String_Element_Table.Increment_Last - (In_Tree.String_Elements); - Data.Source_Dirs := String_Element_Table.Last - (In_Tree.String_Elements); - In_Tree.String_Elements.Table (Data.Source_Dirs) := - (Value => Data.Directory, - Display_Value => Data.Display_Directory, - Location => No_Location, - Flag => False, - Next => Nil_String, - Index => 0); - - if Current_Verbosity = High then - Write_Line ("Single source directory:"); - Write_Str (" """); - Write_Str (Get_Name_String (Data.Display_Directory)); - Write_Line (""""); - end if; - - elsif Source_Dirs.Values = Nil_String then - - -- If Source_Dirs is an empty string list, this means - -- that this project contains no source. For projects that - -- don't extend other projects, this also means that there is no - -- need for an object directory, if not specified. - - if Data.Extends = No_Project - and then Data.Object_Directory = Data.Directory - then - Data.Object_Directory := No_Name; - end if; - - Data.Source_Dirs := Nil_String; - Data.Ada_Sources_Present := False; - Data.Other_Sources_Present := False; - - else - declare - Source_Dir : String_List_Id := Source_Dirs.Values; - Element : String_Element; - - begin - -- We will find the source directories for each - -- element of the list - - while Source_Dir /= Nil_String loop - Element := - In_Tree.String_Elements.Table (Source_Dir); - Find_Source_Dirs (Element.Value, Element.Location); - Source_Dir := Element.Next; - end loop; - end; - end if; - - if Current_Verbosity = High then - Write_Line ("Putting source directories in canonical cases"); - end if; - - declare - Current : String_List_Id := Data.Source_Dirs; - Element : String_Element; - - begin - while Current /= Nil_String loop - Element := In_Tree.String_Elements.Table (Current); - if Element.Value /= No_Name then - Get_Name_String (Element.Value); - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Element.Value := Name_Find; - In_Tree.String_Elements.Table (Current) := Element; - end if; - - Current := Element.Next; - end loop; - end; - - end Get_Directories; - - --------------- - -- Get_Mains -- - --------------- - - procedure Get_Mains - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data) is - Mains : constant Variable_Value := - Prj.Util.Value_Of (Name_Main, Data.Decl.Attributes, In_Tree); - - begin - Data.Mains := Mains.Values; - - -- If no Mains were specified, and if we are an extending - -- project, inherit the Mains from the project we are extending. - - if Mains.Default then - if Data.Extends /= No_Project then - Data.Mains := - In_Tree.Projects.Table (Data.Extends).Mains; - end if; - - -- In a library project file, Main cannot be specified - - elsif Data.Library then - Error_Msg - (Project, In_Tree, - "a library project file cannot have Main specified", - Mains.Location); - end if; - end Get_Mains; - - --------------------------- - -- Get_Sources_From_File -- - --------------------------- - - procedure Get_Sources_From_File - (Path : String; - Location : Source_Ptr; - Project : Project_Id; - In_Tree : Project_Tree_Ref) - is - File : Prj.Util.Text_File; - Line : String (1 .. 250); - Last : Natural; - Source_Name : Name_Id; - - begin - Source_Names.Reset; - - if Current_Verbosity = High then - Write_Str ("Opening """); - Write_Str (Path); - Write_Line ("""."); - end if; - - -- Open the file - - Prj.Util.Open (File, Path); - - if not Prj.Util.Is_Valid (File) then - Error_Msg (Project, In_Tree, "file does not exist", Location); - else - -- Read the lines one by one - - while not Prj.Util.End_Of_File (File) loop - Prj.Util.Get_Line (File, Line, Last); - - -- A non empty, non comment line should contain a file name - - if Last /= 0 - and then (Last = 1 or else Line (1 .. 2) /= "--") - then - -- ??? we should check that there is no directory information - - Name_Len := Last; - Name_Buffer (1 .. Name_Len) := Line (1 .. Last); - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Source_Name := Name_Find; - Source_Names.Set - (K => Source_Name, - E => - (Name => Source_Name, - Location => Location, - Found => False)); - end if; - end loop; - - Prj.Util.Close (File); - - end if; - end Get_Sources_From_File; - - -------------- - -- Get_Unit -- - -------------- - - procedure Get_Unit - (Canonical_File_Name : Name_Id; - Naming : Naming_Data; - Exception_Id : out Ada_Naming_Exception_Id; - Unit_Name : out Name_Id; - Unit_Kind : out Spec_Or_Body; - Needs_Pragma : out Boolean) - is - Info_Id : Ada_Naming_Exception_Id - := Ada_Naming_Exceptions.Get (Canonical_File_Name); - VMS_Name : Name_Id; - - begin - if Info_Id = No_Ada_Naming_Exception then - if Hostparm.OpenVMS then - VMS_Name := Canonical_File_Name; - Get_Name_String (VMS_Name); - - if Name_Buffer (Name_Len) = '.' then - Name_Len := Name_Len - 1; - VMS_Name := Name_Find; - end if; - - Info_Id := Ada_Naming_Exceptions.Get (VMS_Name); - end if; - - end if; - - if Info_Id /= No_Ada_Naming_Exception then - Exception_Id := Info_Id; - Unit_Name := No_Name; - Unit_Kind := Specification; - Needs_Pragma := True; - return; - end if; - - Needs_Pragma := False; - Exception_Id := No_Ada_Naming_Exception; - - Get_Name_String (Canonical_File_Name); - - declare - File : String := Name_Buffer (1 .. Name_Len); - First : constant Positive := File'First; - Last : Natural := File'Last; - Standard_GNAT : Boolean; - - begin - Standard_GNAT := - Naming.Ada_Spec_Suffix = Default_Ada_Spec_Suffix - and then Naming.Ada_Body_Suffix = Default_Ada_Body_Suffix; - - -- Check if the end of the file name is Specification_Append - - Get_Name_String (Naming.Ada_Spec_Suffix); - - if File'Length > Name_Len - and then File (Last - Name_Len + 1 .. Last) = - Name_Buffer (1 .. Name_Len) - then - -- We have a spec - - Unit_Kind := Specification; - Last := Last - Name_Len; - - if Current_Verbosity = High then - Write_Str (" Specification: "); - Write_Line (File (First .. Last)); - end if; - - else - Get_Name_String (Naming.Ada_Body_Suffix); - - -- Check if the end of the file name is Body_Append - - if File'Length > Name_Len - and then File (Last - Name_Len + 1 .. Last) = - Name_Buffer (1 .. Name_Len) - then - -- We have a body - - Unit_Kind := Body_Part; - Last := Last - Name_Len; - - if Current_Verbosity = High then - Write_Str (" Body: "); - Write_Line (File (First .. Last)); - end if; - - elsif Naming.Separate_Suffix /= Naming.Ada_Spec_Suffix then - Get_Name_String (Naming.Separate_Suffix); - - -- Check if the end of the file name is Separate_Append - - if File'Length > Name_Len - and then File (Last - Name_Len + 1 .. Last) = - Name_Buffer (1 .. Name_Len) - then - -- We have a separate (a body) - - Unit_Kind := Body_Part; - Last := Last - Name_Len; - - if Current_Verbosity = High then - Write_Str (" Separate: "); - Write_Line (File (First .. Last)); - end if; - - else - Last := 0; - end if; - - else - Last := 0; - end if; - end if; - - if Last = 0 then - - -- This is not a source file - - Unit_Name := No_Name; - Unit_Kind := Specification; - - if Current_Verbosity = High then - Write_Line (" Not a valid file name."); - end if; - - return; - end if; - - Get_Name_String (Naming.Dot_Replacement); - Standard_GNAT := - Standard_GNAT and then Name_Buffer (1 .. Name_Len) = "-"; - - if Name_Buffer (1 .. Name_Len) /= "." then - - -- If Dot_Replacement is not a single dot, then there should - -- not be any dot in the name. - - for Index in First .. Last loop - if File (Index) = '.' then - if Current_Verbosity = High then - Write_Line - (" Not a valid file name (some dot not replaced)."); - end if; - - Unit_Name := No_Name; - return; - - end if; - end loop; - - -- Replace the substring Dot_Replacement with dots - - declare - Index : Positive := First; - - begin - while Index <= Last - Name_Len + 1 loop - - if File (Index .. Index + Name_Len - 1) = - Name_Buffer (1 .. Name_Len) - then - File (Index) := '.'; - - if Name_Len > 1 and then Index < Last then - File (Index + 1 .. Last - Name_Len + 1) := - File (Index + Name_Len .. Last); - end if; - - Last := Last - Name_Len + 1; - end if; - - Index := Index + 1; - end loop; - end; - end if; - - -- Check if the casing is right - - declare - Src : String := File (First .. Last); - - begin - case Naming.Casing is - when All_Lower_Case => - Fixed.Translate - (Source => Src, - Mapping => Lower_Case_Map); - - when All_Upper_Case => - Fixed.Translate - (Source => Src, - Mapping => Upper_Case_Map); - - when Mixed_Case | Unknown => - null; - end case; - - if Src /= File (First .. Last) then - if Current_Verbosity = High then - Write_Line (" Not a valid file name (casing)."); - end if; - - Unit_Name := No_Name; - return; - end if; - - -- We put the name in lower case - - Fixed.Translate - (Source => Src, - Mapping => Lower_Case_Map); - - -- In the standard GNAT naming scheme, check for special cases: - -- children or separates of A, G, I or S, and run time sources. - - if Standard_GNAT and then Src'Length >= 3 then - declare - S1 : constant Character := Src (Src'First); - S2 : constant Character := Src (Src'First + 1); - S3 : constant Character := Src (Src'First + 2); - - begin - if S1 = 'a' or else S1 = 'g' - or else S1 = 'i' or else S1 = 's' - then - -- Children or separates of packages A, G, I or S - - if (OpenVMS_On_Target - and then S2 = '_' - and then S3 = '_') - or else - S2 = '~' - then - Src (Src'First + 1) := '.'; - - -- If it is potentially a run time source, disable - -- filling of the mapping file to avoid warnings. - - elsif S2 = '.' then - Set_Mapping_File_Initial_State_To_Empty; - end if; - - end if; - end; - end if; - - if Current_Verbosity = High then - Write_Str (" "); - Write_Line (Src); - end if; - - -- Now, we check if this name is a valid unit name - - Check_Ada_Name (Name => Src, Unit => Unit_Name); - end; - - end; - end Get_Unit; - - ---------- - -- Hash -- - ---------- - - function Hash (Unit : Unit_Info) return Header_Num is - begin - return Header_Num (Unit.Unit mod 2048); - end Hash; - - ----------------------- - -- Is_Illegal_Suffix -- - ----------------------- - - function Is_Illegal_Suffix - (Suffix : String; - Dot_Replacement_Is_A_Single_Dot : Boolean) return Boolean - is - begin - if Suffix'Length = 0 or else Index (Suffix, ".") = 0 then - return True; - end if; - - -- If dot replacement is a single dot, and first character of - -- suffix is also a dot - - if Dot_Replacement_Is_A_Single_Dot - and then Suffix (Suffix'First) = '.' - then - for Index in Suffix'First + 1 .. Suffix'Last loop - - -- If there is another dot - - if Suffix (Index) = '.' then - - -- It is illegal to have a letter following the initial dot - - return Is_Letter (Suffix (Suffix'First + 1)); - end if; - end loop; - end if; - - -- Everything is OK - - return False; - end Is_Illegal_Suffix; - - ---------------------- - -- Locate_Directory -- - ---------------------- - - procedure Locate_Directory - (Name : Name_Id; - Parent : Name_Id; - Dir : out Name_Id; - Display : out Name_Id) - is - The_Name : constant String := Get_Name_String (Name); - - The_Parent : constant String := - Get_Name_String (Parent) & Directory_Separator; - - The_Parent_Last : constant Natural := - Compute_Directory_Last (The_Parent); - - begin - if Current_Verbosity = High then - Write_Str ("Locate_Directory ("""); - Write_Str (The_Name); - Write_Str (""", """); - Write_Str (The_Parent); - Write_Line (""")"); - end if; - - Dir := No_Name; - Display := No_Name; - - if Is_Absolute_Path (The_Name) then - if Is_Directory (The_Name) then - declare - Normed : constant String := - Normalize_Pathname - (The_Name, - Resolve_Links => False, - Case_Sensitive => True); - - Canonical_Path : constant String := - Normalize_Pathname - (Normed, - Resolve_Links => True, - Case_Sensitive => False); - - begin - Name_Len := Normed'Length; - Name_Buffer (1 .. Name_Len) := Normed; - Display := Name_Find; - - Name_Len := Canonical_Path'Length; - Name_Buffer (1 .. Name_Len) := Canonical_Path; - Dir := Name_Find; - end; - end if; - - else - declare - Full_Path : constant String := - The_Parent (The_Parent'First .. The_Parent_Last) & - The_Name; - - begin - if Is_Directory (Full_Path) then - declare - Normed : constant String := - Normalize_Pathname - (Full_Path, - Resolve_Links => False, - Case_Sensitive => True); - - Canonical_Path : constant String := - Normalize_Pathname - (Normed, - Resolve_Links => True, - Case_Sensitive => False); - - begin - Name_Len := Normed'Length; - Name_Buffer (1 .. Name_Len) := Normed; - Display := Name_Find; - - Name_Len := Canonical_Path'Length; - Name_Buffer (1 .. Name_Len) := Canonical_Path; - Dir := Name_Find; - end; - end if; - end; - end if; - end Locate_Directory; - - ---------------------- - -- Look_For_Sources -- - ---------------------- - - procedure Look_For_Sources - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - Follow_Links : Boolean) - is - procedure Get_Path_Names_And_Record_Sources (Follow_Links : Boolean); - -- Find the path names of the source files in the Source_Names table - -- in the source directories and record those that are Ada sources. - - procedure Get_Sources_From_File - (Path : String; - Location : Source_Ptr); - -- Get the sources of a project from a text file - - --------------------------------------- - -- Get_Path_Names_And_Record_Sources -- - --------------------------------------- - - procedure Get_Path_Names_And_Record_Sources (Follow_Links : Boolean) is - Source_Dir : String_List_Id := Data.Source_Dirs; - Element : String_Element; - Path : Name_Id; - - Dir : Dir_Type; - Name : Name_Id; - Canonical_Name : Name_Id; - Name_Str : String (1 .. 1_024); - Last : Natural := 0; - NL : Name_Location; - - Current_Source : String_List_Id := Nil_String; - - First_Error : Boolean := True; - - Source_Recorded : Boolean := False; - - begin - -- We look in all source directories for the file names in the - -- hash table Source_Names - - while Source_Dir /= Nil_String loop - Source_Recorded := False; - Element := In_Tree.String_Elements.Table (Source_Dir); - - declare - Dir_Path : constant String := Get_Name_String (Element.Value); - begin - if Current_Verbosity = High then - Write_Str ("checking directory """); - Write_Str (Dir_Path); - Write_Line (""""); - end if; - - Open (Dir, Dir_Path); - - loop - Read (Dir, Name_Str, Last); - exit when Last = 0; - Name_Len := Last; - Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last); - Name := Name_Find; - Canonical_Case_File_Name (Name_Str (1 .. Last)); - Name_Len := Last; - Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last); - Canonical_Name := Name_Find; - NL := Source_Names.Get (Canonical_Name); - - if NL /= No_Name_Location and then not NL.Found then - NL.Found := True; - Source_Names.Set (Canonical_Name, NL); - Name_Len := Dir_Path'Length; - Name_Buffer (1 .. Name_Len) := Dir_Path; - - if Name_Buffer (Name_Len) /= Directory_Separator then - Add_Char_To_Name_Buffer (Directory_Separator); - end if; - - Add_Str_To_Name_Buffer (Name_Str (1 .. Last)); - Path := Name_Find; - - if Current_Verbosity = High then - Write_Str (" found "); - Write_Line (Get_Name_String (Name)); - end if; - - -- Register the source if it is an Ada compilation unit - - Record_Ada_Source - (File_Name => Name, - Path_Name => Path, - Project => Project, - In_Tree => In_Tree, - Data => Data, - Location => NL.Location, - Current_Source => Current_Source, - Source_Recorded => Source_Recorded, - Follow_Links => Follow_Links); - end if; - end loop; - - Close (Dir); - end; - - if Source_Recorded then - In_Tree.String_Elements.Table (Source_Dir).Flag := - True; - end if; - - Source_Dir := Element.Next; - end loop; - - -- It is an error if a source file name in a source list or - -- in a source list file is not found. - - NL := Source_Names.Get_First; - - while NL /= No_Name_Location loop - if not NL.Found then - Err_Vars.Error_Msg_Name_1 := NL.Name; - - if First_Error then - Error_Msg - (Project, In_Tree, - "source file { cannot be found", - NL.Location); - First_Error := False; - - else - Error_Msg - (Project, In_Tree, - "\source file { cannot be found", - NL.Location); - end if; - end if; - - NL := Source_Names.Get_Next; - end loop; - end Get_Path_Names_And_Record_Sources; - - --------------------------- - -- Get_Sources_From_File -- - --------------------------- - - procedure Get_Sources_From_File - (Path : String; - Location : Source_Ptr) - is - begin - -- Get the list of sources from the file and put them in hash table - -- Source_Names. - - Get_Sources_From_File (Path, Location, Project, In_Tree); - - -- Look in the source directories to find those sources - - Get_Path_Names_And_Record_Sources (Follow_Links); - - -- We should have found at least one source. - -- If not, report an error/warning. - - if Data.Sources = Nil_String then - Report_No_Ada_Sources (Project, In_Tree, Location); - end if; - end Get_Sources_From_File; - - begin - if Data.Ada_Sources_Present then - declare - Sources : constant Variable_Value := - Util.Value_Of - (Name_Source_Files, - Data.Decl.Attributes, - In_Tree); - - Source_List_File : constant Variable_Value := - Util.Value_Of - (Name_Source_List_File, - Data.Decl.Attributes, - In_Tree); - - Locally_Removed : constant Variable_Value := - Util.Value_Of - (Name_Locally_Removed_Files, - Data.Decl.Attributes, - In_Tree); - - begin - pragma Assert - (Sources.Kind = List, - "Source_Files is not a list"); - - pragma Assert - (Source_List_File.Kind = Single, - "Source_List_File is not a single string"); - - if not Sources.Default then - if not Source_List_File.Default then - Error_Msg - (Project, In_Tree, - "?both variables source_files and " & - "source_list_file are present", - Source_List_File.Location); - end if; - - -- Sources is a list of file names - - declare - Current : String_List_Id := Sources.Values; - Element : String_Element; - Location : Source_Ptr; - Name : Name_Id; - - begin - Source_Names.Reset; - - Data.Ada_Sources_Present := Current /= Nil_String; - - while Current /= Nil_String loop - Element := - In_Tree.String_Elements.Table (Current); - Get_Name_String (Element.Value); - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Name := Name_Find; - - -- If the element has no location, then use the - -- location of Sources to report possible errors. - - if Element.Location = No_Location then - Location := Sources.Location; - else - Location := Element.Location; - end if; - - Source_Names.Set - (K => Name, - E => - (Name => Name, - Location => Location, - Found => False)); - - Current := Element.Next; - end loop; - - Get_Path_Names_And_Record_Sources (Follow_Links); - end; - - -- No source_files specified - - -- We check Source_List_File has been specified - - elsif not Source_List_File.Default then - - -- Source_List_File is the name of the file - -- that contains the source file names - - declare - Source_File_Path_Name : constant String := - Path_Name_Of - (Source_List_File.Value, - Data.Directory); - - begin - if Source_File_Path_Name'Length = 0 then - Err_Vars.Error_Msg_Name_1 := Source_List_File.Value; - Error_Msg - (Project, In_Tree, - "file with sources { does not exist", - Source_List_File.Location); - - else - Get_Sources_From_File - (Source_File_Path_Name, - Source_List_File.Location); - end if; - end; - - else - -- Neither Source_Files nor Source_List_File has been - -- specified. Find all the files that satisfy the naming - -- scheme in all the source directories. - - Find_Sources - (Project, In_Tree, Data, Ada_Language_Index, Follow_Links); - end if; - - -- If there are sources that are locally removed, mark them as - -- such in the Units table. - - if not Locally_Removed.Default then - - -- Sources can be locally removed only in extending - -- project files. - - if Data.Extends = No_Project then - Error_Msg - (Project, In_Tree, - "Locally_Removed_Files can only be used " & - "in an extending project file", - Locally_Removed.Location); - - else - declare - Current : String_List_Id := Locally_Removed.Values; - Element : String_Element; - Location : Source_Ptr; - OK : Boolean; - Unit : Unit_Data; - Name : Name_Id; - Extended : Project_Id; - - begin - while Current /= Nil_String loop - Element := - In_Tree.String_Elements.Table (Current); - Get_Name_String (Element.Value); - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Name := Name_Find; - - -- If the element has no location, then use the - -- location of Locally_Removed to report - -- possible errors. - - if Element.Location = No_Location then - Location := Locally_Removed.Location; - else - Location := Element.Location; - end if; - - OK := False; - - for Index in Unit_Table.First .. - Unit_Table.Last (In_Tree.Units) - loop - Unit := In_Tree.Units.Table (Index); - - if Unit.File_Names (Specification).Name = Name then - OK := True; - - -- Check that this is from a project that - -- the current project extends, but not the - -- current project. - - Extended := Unit.File_Names - (Specification).Project; - - if Extended = Project then - Error_Msg - (Project, In_Tree, - "cannot remove a source " & - "of the same project", - Location); - - elsif - Project_Extends (Project, Extended, In_Tree) - then - Unit.File_Names - (Specification).Path := Slash; - Unit.File_Names - (Specification).Needs_Pragma := False; - In_Tree.Units.Table (Index) := - Unit; - Add_Forbidden_File_Name - (Unit.File_Names (Specification).Name); - exit; - - else - Error_Msg - (Project, In_Tree, - "cannot remove a source from " & - "another project", - Location); - end if; - - elsif - Unit.File_Names (Body_Part).Name = Name - then - OK := True; - - -- Check that this is from a project that - -- the current project extends, but not the - -- current project. - - Extended := Unit.File_Names - (Body_Part).Project; - - if Extended = Project then - Error_Msg - (Project, In_Tree, - "cannot remove a source " & - "of the same project", - Location); - - elsif - Project_Extends (Project, Extended, In_Tree) - then - Unit.File_Names (Body_Part).Path := Slash; - Unit.File_Names (Body_Part).Needs_Pragma - := False; - In_Tree.Units.Table (Index) := - Unit; - Add_Forbidden_File_Name - (Unit.File_Names (Body_Part).Name); - exit; - end if; - - end if; - end loop; - - if not OK then - Err_Vars.Error_Msg_Name_1 := Name; - Error_Msg - (Project, In_Tree, "unknown file {", Location); - end if; - - Current := Element.Next; - end loop; - end; - end if; - end if; - end; - end if; - - if Data.Other_Sources_Present then - - -- Set Source_Present to False. It will be set back to True - -- whenever a source is found. - - Data.Other_Sources_Present := False; - for Lang in Ada_Language_Index + 1 .. Last_Language_Index loop - - -- For each language (other than Ada) in the project file - - if Is_Present (Lang, Data, In_Tree) then - - -- Reset the indication that there are sources of this - -- language. It will be set back to True whenever we find a - -- source of the language. - - Set (Lang, False, Data, In_Tree); - - -- First, get the source suffix for the language - - Set (Suffix => Suffix_For (Lang, Data.Naming, In_Tree), - For_Language => Lang, - In_Project => Data, - In_Tree => In_Tree); - - -- Then, deal with the naming exceptions, if any - - Source_Names.Reset; - - declare - Naming_Exceptions : constant Variable_Value := - Value_Of - (Index => Language_Names.Table (Lang), - Src_Index => 0, - In_Array => Data.Naming.Implementation_Exceptions, - In_Tree => In_Tree); - Element_Id : String_List_Id; - Element : String_Element; - File_Id : Name_Id; - Source_Found : Boolean := False; - - begin - -- If there are naming exceptions, look through them one - -- by one. - - if Naming_Exceptions /= Nil_Variable_Value then - Element_Id := Naming_Exceptions.Values; - - while Element_Id /= Nil_String loop - Element := In_Tree.String_Elements.Table - (Element_Id); - Get_Name_String (Element.Value); - Canonical_Case_File_Name - (Name_Buffer (1 .. Name_Len)); - File_Id := Name_Find; - - -- Put each naming exception in the Source_Names - -- hash table, but if there are repetition, don't - -- bother after the first instance. - - if - Source_Names.Get (File_Id) = No_Name_Location - then - Source_Found := True; - Source_Names.Set - (File_Id, - (Name => File_Id, - Location => Element.Location, - Found => False)); - end if; - - Element_Id := Element.Next; - end loop; - - -- If there is at least one naming exception, record - -- those that are found in the source directories. - - if Source_Found then - Record_Other_Sources - (Project => Project, - In_Tree => In_Tree, - Data => Data, - Language => Lang, - Naming_Exceptions => True); - end if; - - end if; - end; - - -- Now, check if a list of sources is declared either through - -- a string list (attribute Source_Files) or a text file - -- (attribute Source_List_File). If a source list is declared, - -- we will consider only those naming exceptions that are - -- on the list. - - declare - Sources : constant Variable_Value := - Util.Value_Of - (Name_Source_Files, - Data.Decl.Attributes, - In_Tree); - - Source_List_File : constant Variable_Value := - Util.Value_Of - (Name_Source_List_File, - Data.Decl.Attributes, - In_Tree); - - begin - pragma Assert - (Sources.Kind = List, - "Source_Files is not a list"); - - pragma Assert - (Source_List_File.Kind = Single, - "Source_List_File is not a single string"); - - if not Sources.Default then - if not Source_List_File.Default then - Error_Msg - (Project, In_Tree, - "?both variables source_files and " & - "source_list_file are present", - Source_List_File.Location); - end if; - - -- Sources is a list of file names - - declare - Current : String_List_Id := Sources.Values; - Element : String_Element; - Location : Source_Ptr; - Name : Name_Id; - - begin - Source_Names.Reset; - - -- Put all the sources in the Source_Names hash table - - while Current /= Nil_String loop - Element := - In_Tree.String_Elements.Table - (Current); - Get_Name_String (Element.Value); - Canonical_Case_File_Name - (Name_Buffer (1 .. Name_Len)); - Name := Name_Find; - - -- If the element has no location, then use the - -- location of Sources to report possible errors. - - if Element.Location = No_Location then - Location := Sources.Location; - else - Location := Element.Location; - end if; - - Source_Names.Set - (K => Name, - E => - (Name => Name, - Location => Location, - Found => False)); - - Current := Element.Next; - end loop; - - -- And look for their directories - - Record_Other_Sources - (Project => Project, - In_Tree => In_Tree, - Data => Data, - Language => Lang, - Naming_Exceptions => False); - end; - - -- No source_files specified - - -- We check if Source_List_File has been specified - - elsif not Source_List_File.Default then - - -- Source_List_File is the name of the file - -- that contains the source file names - - declare - Source_File_Path_Name : constant String := - Path_Name_Of - (Source_List_File.Value, - Data.Directory); - - begin - if Source_File_Path_Name'Length = 0 then - Err_Vars.Error_Msg_Name_1 := - Source_List_File.Value; - Error_Msg - (Project, In_Tree, - "file with sources { does not exist", - Source_List_File.Location); - - else - -- Read the file, putting each source in the - -- Source_Names hash table. - - Get_Sources_From_File - (Source_File_Path_Name, - Source_List_File.Location, - Project, In_Tree); - - -- And look for their directories - - Record_Other_Sources - (Project => Project, - In_Tree => In_Tree, - Data => Data, - Language => Lang, - Naming_Exceptions => False); - end if; - end; - - -- Neither Source_Files nor Source_List_File was specified - - else - -- Find all the files that satisfy the naming scheme in - -- all the source directories. All the naming exceptions - -- that effectively exist are also part of the source - -- of this language. - - Find_Sources (Project, In_Tree, Data, Lang); - end if; - end; - end if; - end loop; - end if; - end Look_For_Sources; - - ------------------ - -- Path_Name_Of -- - ------------------ - - function Path_Name_Of - (File_Name : Name_Id; - Directory : Name_Id) return String - is - Result : String_Access; - - The_Directory : constant String := Get_Name_String (Directory); - - begin - Get_Name_String (File_Name); - Result := Locate_Regular_File - (File_Name => Name_Buffer (1 .. Name_Len), - Path => The_Directory); - - if Result = null then - return ""; - else - Canonical_Case_File_Name (Result.all); - return Result.all; - end if; - end Path_Name_Of; - - ------------------------------- - -- Prepare_Ada_Naming_Exceptions -- - ------------------------------- - - procedure Prepare_Ada_Naming_Exceptions - (List : Array_Element_Id; - In_Tree : Project_Tree_Ref; - Kind : Spec_Or_Body) - is - Current : Array_Element_Id := List; - Element : Array_Element; - - Unit : Unit_Info; - - begin - -- Traverse the list - - while Current /= No_Array_Element loop - Element := In_Tree.Array_Elements.Table (Current); - - if Element.Index /= No_Name then - Unit := - (Kind => Kind, - Unit => Element.Index, - Next => No_Ada_Naming_Exception); - Reverse_Ada_Naming_Exceptions.Set - (Unit, (Element.Value.Value, Element.Value.Index)); - Unit.Next := Ada_Naming_Exceptions.Get (Element.Value.Value); - Ada_Naming_Exception_Table.Increment_Last; - Ada_Naming_Exception_Table.Table - (Ada_Naming_Exception_Table.Last) := Unit; - Ada_Naming_Exceptions.Set - (Element.Value.Value, Ada_Naming_Exception_Table.Last); - end if; - - Current := Element.Next; - end loop; - end Prepare_Ada_Naming_Exceptions; - - --------------------- - -- Project_Extends -- - --------------------- - - function Project_Extends - (Extending : Project_Id; - Extended : Project_Id; - In_Tree : Project_Tree_Ref) return Boolean - is - Current : Project_Id := Extending; - begin - loop - if Current = No_Project then - return False; - - elsif Current = Extended then - return True; - end if; - - Current := In_Tree.Projects.Table (Current).Extends; - end loop; - end Project_Extends; - - ----------------------- - -- Record_Ada_Source -- - ----------------------- - - procedure Record_Ada_Source - (File_Name : Name_Id; - Path_Name : Name_Id; - Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - Location : Source_Ptr; - Current_Source : in out String_List_Id; - Source_Recorded : in out Boolean; - Follow_Links : Boolean) - is - Canonical_File_Name : Name_Id; - Canonical_Path_Name : Name_Id; - - Exception_Id : Ada_Naming_Exception_Id; - Unit_Name : Name_Id; - Unit_Kind : Spec_Or_Body; - Unit_Index : Int := 0; - Info : Unit_Info; - Name_Index : Name_And_Index; - Needs_Pragma : Boolean; - - The_Location : Source_Ptr := Location; - Previous_Source : constant String_List_Id := Current_Source; - Except_Name : Name_And_Index := No_Name_And_Index; - - Unit_Prj : Unit_Project; - - File_Name_Recorded : Boolean := False; - - begin - Get_Name_String (File_Name); - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Canonical_File_Name := Name_Find; - - declare - Canonical_Path : constant String := - Normalize_Pathname - (Get_Name_String (Path_Name), - Resolve_Links => Follow_Links, - Case_Sensitive => False); - begin - Name_Len := 0; - Add_Str_To_Name_Buffer (Canonical_Path); - Canonical_Path_Name := Name_Find; - end; - - -- Find out the unit name, the unit kind and if it needs - -- a specific SFN pragma. - - Get_Unit - (Canonical_File_Name => Canonical_File_Name, - Naming => Data.Naming, - Exception_Id => Exception_Id, - Unit_Name => Unit_Name, - Unit_Kind => Unit_Kind, - Needs_Pragma => Needs_Pragma); - - if Exception_Id = No_Ada_Naming_Exception and then - Unit_Name = No_Name - then - if Current_Verbosity = High then - Write_Str (" """); - Write_Str (Get_Name_String (Canonical_File_Name)); - Write_Line (""" is not a valid source file name (ignored)."); - end if; - - else - -- Check to see if the source has been hidden by an exception, - -- but only if it is not an exception. - - if not Needs_Pragma then - Except_Name := - Reverse_Ada_Naming_Exceptions.Get - ((Unit_Kind, Unit_Name, No_Ada_Naming_Exception)); - - if Except_Name /= No_Name_And_Index then - if Current_Verbosity = High then - Write_Str (" """); - Write_Str (Get_Name_String (Canonical_File_Name)); - Write_Str (""" contains a unit that is found in """); - Write_Str (Get_Name_String (Except_Name.Name)); - Write_Line (""" (ignored)."); - end if; - - -- The file is not included in the source of the project, - -- because it is hidden by the exception. - -- So, there is nothing else to do. - - return; - end if; - end if; - - loop - if Exception_Id /= No_Ada_Naming_Exception then - Info := Ada_Naming_Exception_Table.Table (Exception_Id); - Exception_Id := Info.Next; - Info.Next := No_Ada_Naming_Exception; - Name_Index := Reverse_Ada_Naming_Exceptions.Get (Info); - - Unit_Name := Info.Unit; - Unit_Index := Name_Index.Index; - Unit_Kind := Info.Kind; - end if; - - -- Put the file name in the list of sources of the project - - if not File_Name_Recorded then - String_Element_Table.Increment_Last - (In_Tree.String_Elements); - In_Tree.String_Elements.Table - (String_Element_Table.Last - (In_Tree.String_Elements)) := - (Value => Canonical_File_Name, - Display_Value => File_Name, - Location => No_Location, - Flag => False, - Next => Nil_String, - Index => Unit_Index); - end if; - - if Current_Source = Nil_String then - Data.Sources := String_Element_Table.Last - (In_Tree.String_Elements); - else - In_Tree.String_Elements.Table - (Current_Source).Next := - String_Element_Table.Last - (In_Tree.String_Elements); - end if; - - Current_Source := String_Element_Table.Last - (In_Tree.String_Elements); - - -- Put the unit in unit list - - declare - The_Unit : Unit_Id := - Units_Htable.Get (In_Tree.Units_HT, Unit_Name); - The_Unit_Data : Unit_Data; - - begin - if Current_Verbosity = High then - Write_Str ("Putting "); - Write_Str (Get_Name_String (Unit_Name)); - Write_Line (" in the unit list."); - end if; - - -- The unit is already in the list, but may be it is - -- only the other unit kind (spec or body), or what is - -- in the unit list is a unit of a project we are extending. - - if The_Unit /= No_Unit then - The_Unit_Data := In_Tree.Units.Table (The_Unit); - - if The_Unit_Data.File_Names (Unit_Kind).Name = No_Name - or else Project_Extends - (Data.Extends, - The_Unit_Data.File_Names (Unit_Kind).Project, - In_Tree) - then - if The_Unit_Data.File_Names (Unit_Kind).Path = Slash then - Remove_Forbidden_File_Name - (The_Unit_Data.File_Names (Unit_Kind).Name); - end if; - - -- Record the file name in the hash table Files_Htable - - Unit_Prj := (Unit => The_Unit, Project => Project); - Files_Htable.Set - (In_Tree.Files_HT, - Canonical_File_Name, - Unit_Prj); - - The_Unit_Data.File_Names (Unit_Kind) := - (Name => Canonical_File_Name, - Index => Unit_Index, - Display_Name => File_Name, - Path => Canonical_Path_Name, - Display_Path => Path_Name, - Project => Project, - Needs_Pragma => Needs_Pragma); - In_Tree.Units.Table (The_Unit) := - The_Unit_Data; - Source_Recorded := True; - - elsif The_Unit_Data.File_Names (Unit_Kind).Project = Project - and then (Data.Known_Order_Of_Source_Dirs or else - The_Unit_Data.File_Names (Unit_Kind).Path = - Canonical_Path_Name) - then - if Previous_Source = Nil_String then - Data.Sources := Nil_String; - else - In_Tree.String_Elements.Table - (Previous_Source).Next := Nil_String; - String_Element_Table.Decrement_Last - (In_Tree.String_Elements); - end if; - - Current_Source := Previous_Source; - - else - -- It is an error to have two units with the same name - -- and the same kind (spec or body). - - if The_Location = No_Location then - The_Location := - In_Tree.Projects.Table - (Project).Location; - end if; - - Err_Vars.Error_Msg_Name_1 := Unit_Name; - Error_Msg - (Project, In_Tree, "duplicate source {", The_Location); - - Err_Vars.Error_Msg_Name_1 := - In_Tree.Projects.Table - (The_Unit_Data.File_Names (Unit_Kind).Project).Name; - Err_Vars.Error_Msg_Name_2 := - The_Unit_Data.File_Names (Unit_Kind).Path; - Error_Msg - (Project, In_Tree, - "\ project file {, {", The_Location); - - Err_Vars.Error_Msg_Name_1 := - In_Tree.Projects.Table (Project).Name; - Err_Vars.Error_Msg_Name_2 := Canonical_Path_Name; - Error_Msg - (Project, In_Tree, - "\ project file {, {", The_Location); - end if; - - -- It is a new unit, create a new record - - else - -- First, check if there is no other unit with this file - -- name in another project. If it is, report an error. - -- Of course, we do that only for the first unit in the - -- source file. - - Unit_Prj := Files_Htable.Get - (In_Tree.Files_HT, Canonical_File_Name); - - if not File_Name_Recorded and then - Unit_Prj /= No_Unit_Project - then - Error_Msg_Name_1 := File_Name; - Error_Msg_Name_2 := - In_Tree.Projects.Table - (Unit_Prj.Project).Name; - Error_Msg - (Project, In_Tree, - "{ is already a source of project {", - Location); - - else - Unit_Table.Increment_Last (In_Tree.Units); - The_Unit := Unit_Table.Last (In_Tree.Units); - Units_Htable.Set - (In_Tree.Units_HT, Unit_Name, The_Unit); - Unit_Prj := (Unit => The_Unit, Project => Project); - Files_Htable.Set - (In_Tree.Files_HT, - Canonical_File_Name, - Unit_Prj); - The_Unit_Data.Name := Unit_Name; - The_Unit_Data.File_Names (Unit_Kind) := - (Name => Canonical_File_Name, - Index => Unit_Index, - Display_Name => File_Name, - Path => Canonical_Path_Name, - Display_Path => Path_Name, - Project => Project, - Needs_Pragma => Needs_Pragma); - In_Tree.Units.Table (The_Unit) := - The_Unit_Data; - Source_Recorded := True; - end if; - end if; - end; - - exit when Exception_Id = No_Ada_Naming_Exception; - File_Name_Recorded := True; - end loop; - end if; - end Record_Ada_Source; - - -------------------------- - -- Record_Other_Sources -- - -------------------------- - - procedure Record_Other_Sources - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Data : in out Project_Data; - Language : Language_Index; - Naming_Exceptions : Boolean) - is - Source_Dir : String_List_Id := Data.Source_Dirs; - Element : String_Element; - Path : Name_Id; - - Dir : Dir_Type; - Canonical_Name : Name_Id; - - Name_Str : String (1 .. 1_024); - Last : Natural := 0; - NL : Name_Location; - - First_Error : Boolean := True; - - Suffix : constant String := Body_Suffix_Of (Language, Data, In_Tree); - - begin - while Source_Dir /= Nil_String loop - Element := In_Tree.String_Elements.Table (Source_Dir); - - declare - Dir_Path : constant String := Get_Name_String (Element.Value); - - begin - if Current_Verbosity = High then - Write_Str ("checking directory """); - Write_Str (Dir_Path); - Write_Str (""" for "); - - if Naming_Exceptions then - Write_Str ("naming exceptions"); - - else - Write_Str ("sources"); - end if; - - Write_Str (" of Language "); - Display_Language_Name (Language); - end if; - - Open (Dir, Dir_Path); - - loop - Read (Dir, Name_Str, Last); - exit when Last = 0; - - if Is_Regular_File - (Dir_Path & Directory_Separator & Name_Str (1 .. Last)) - then - Name_Len := Last; - Name_Buffer (1 .. Name_Len) := Name_Str (1 .. Last); - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - Canonical_Name := Name_Find; - NL := Source_Names.Get (Canonical_Name); - - if NL /= No_Name_Location then - if NL.Found then - if not Data.Known_Order_Of_Source_Dirs then - Error_Msg_Name_1 := Canonical_Name; - Error_Msg - (Project, In_Tree, - "{ is found in several source directories", - NL.Location); - end if; - - else - NL.Found := True; - Source_Names.Set (Canonical_Name, NL); - Name_Len := Dir_Path'Length; - Name_Buffer (1 .. Name_Len) := Dir_Path; - Add_Char_To_Name_Buffer (Directory_Separator); - Add_Str_To_Name_Buffer (Name_Str (1 .. Last)); - Path := Name_Find; - - Check_For_Source - (File_Name => Canonical_Name, - Path_Name => Path, - Project => Project, - In_Tree => In_Tree, - Data => Data, - Location => NL.Location, - Language => Language, - Suffix => Suffix, - Naming_Exception => Naming_Exceptions); - end if; - end if; - end if; - end loop; - - Close (Dir); - end; - - Source_Dir := Element.Next; - end loop; - - if not Naming_Exceptions then - NL := Source_Names.Get_First; - - -- It is an error if a source file name in a source list or - -- in a source list file is not found. - - while NL /= No_Name_Location loop - if not NL.Found then - Err_Vars.Error_Msg_Name_1 := NL.Name; - - if First_Error then - Error_Msg - (Project, In_Tree, - "source file { cannot be found", - NL.Location); - First_Error := False; - - else - Error_Msg - (Project, In_Tree, - "\source file { cannot be found", - NL.Location); - end if; - end if; - - NL := Source_Names.Get_Next; - end loop; - - -- Any naming exception of this language that is not in a list - -- of sources must be removed. - - declare - Source_Id : Other_Source_Id := Data.First_Other_Source; - Prev_Id : Other_Source_Id := No_Other_Source; - Source : Other_Source; - - begin - while Source_Id /= No_Other_Source loop - Source := In_Tree.Other_Sources.Table (Source_Id); - - if Source.Language = Language - and then Source.Naming_Exception - then - if Current_Verbosity = High then - Write_Str ("Naming exception """); - Write_Str (Get_Name_String (Source.File_Name)); - Write_Str (""" is not in the list of sources,"); - Write_Line (" so it is removed."); - end if; - - if Prev_Id = No_Other_Source then - Data.First_Other_Source := Source.Next; - - else - In_Tree.Other_Sources.Table - (Prev_Id).Next := Source.Next; - end if; - - Source_Id := Source.Next; - - if Source_Id = No_Other_Source then - Data.Last_Other_Source := Prev_Id; - end if; - - else - Prev_Id := Source_Id; - Source_Id := Source.Next; - end if; - end loop; - end; - end if; - end Record_Other_Sources; - - --------------------------- - -- Report_No_Ada_Sources -- - --------------------------- - - procedure Report_No_Ada_Sources - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Location : Source_Ptr) - is - begin - case When_No_Sources is - when Silent => - null; - - when Warning | Error => - Error_Msg_Warn := When_No_Sources = Warning; - - Error_Msg - (Project, In_Tree, - "<there are no Ada sources in this project", - Location); - end case; - end Report_No_Ada_Sources; - - ---------------------- - -- Show_Source_Dirs -- - ---------------------- - - procedure Show_Source_Dirs - (Project : Project_Id; - In_Tree : Project_Tree_Ref) - is - Current : String_List_Id; - Element : String_Element; - - begin - Write_Line ("Source_Dirs:"); - - Current := In_Tree.Projects.Table (Project).Source_Dirs; - while Current /= Nil_String loop - Element := In_Tree.String_Elements.Table (Current); - Write_Str (" "); - Write_Line (Get_Name_String (Element.Value)); - Current := Element.Next; - end loop; - - Write_Line ("end Source_Dirs."); - end Show_Source_Dirs; - - ---------------- - -- Suffix_For -- - ---------------- - - function Suffix_For - (Language : Language_Index; - Naming : Naming_Data; - In_Tree : Project_Tree_Ref) return Name_Id - is - Suffix : constant Variable_Value := - Value_Of - (Index => Language_Names.Table (Language), - Src_Index => 0, - In_Array => Naming.Body_Suffix, - In_Tree => In_Tree); - begin - -- If no suffix for this language in package Naming, use the default - - if Suffix = Nil_Variable_Value then - Name_Len := 0; - - case Language is - when Ada_Language_Index => - Add_Str_To_Name_Buffer (".adb"); - - when C_Language_Index => - Add_Str_To_Name_Buffer (".c"); - - when C_Plus_Plus_Language_Index => - Add_Str_To_Name_Buffer (".cpp"); - - when others => - return No_Name; - end case; - - -- Otherwise use the one specified - - else - Get_Name_String (Suffix.Value); - end if; - - Canonical_Case_File_Name (Name_Buffer (1 .. Name_Len)); - return Name_Find; - end Suffix_For; - - ------------------------- - -- Warn_If_Not_Sources -- - ------------------------- - - -- comments needed in this body ??? - - procedure Warn_If_Not_Sources - (Project : Project_Id; - In_Tree : Project_Tree_Ref; - Conventions : Array_Element_Id; - Specs : Boolean; - Extending : Boolean) - is - Conv : Array_Element_Id := Conventions; - Unit : Name_Id; - The_Unit_Id : Unit_Id; - The_Unit_Data : Unit_Data; - Location : Source_Ptr; - - begin - while Conv /= No_Array_Element loop - Unit := In_Tree.Array_Elements.Table (Conv).Index; - Error_Msg_Name_1 := Unit; - Get_Name_String (Unit); - To_Lower (Name_Buffer (1 .. Name_Len)); - Unit := Name_Find; - The_Unit_Id := Units_Htable.Get - (In_Tree.Units_HT, Unit); - Location := In_Tree.Array_Elements.Table - (Conv).Value.Location; - - if The_Unit_Id = No_Unit then - Error_Msg - (Project, In_Tree, - "?unknown unit {", - Location); - - else - The_Unit_Data := In_Tree.Units.Table (The_Unit_Id); - Error_Msg_Name_2 := - In_Tree.Array_Elements.Table (Conv).Value.Value; - - if Specs then - if not Check_Project - (The_Unit_Data.File_Names (Specification).Project, - Project, In_Tree, Extending) - then - Error_Msg - (Project, In_Tree, - "?source of spec of unit { ({)" & - " cannot be found in this project", - Location); - end if; - - else - if not Check_Project - (The_Unit_Data.File_Names (Body_Part).Project, - Project, In_Tree, Extending) - then - Error_Msg - (Project, In_Tree, - "?source of body of unit { ({)" & - " cannot be found in this project", - Location); - end if; - end if; - end if; - - Conv := In_Tree.Array_Elements.Table (Conv).Next; - end loop; - end Warn_If_Not_Sources; - -end Prj.Nmsc; |