Commit fc2c32e2 by Emmanuel Briot Committed by Arnaud Charlet

gnatcmd.adb, [...] (Immediate_Directory_Of): Removed.

2009-07-13  Emmanuel Briot  <briot@adacore.com>

	* gnatcmd.adb, make.adb, mlib-prj.adb, prj-part.adb, mlib.adb,
	prj.adb, prj.ads, clean.adb, prj-nmsc.adb, prj-nmsc.ads, prj-pars.adb,
	prj-pars.ads, prj-conf.adb, prj-conf.ads, prj-tree.adb,
	prj-tree.ads (Immediate_Directory_Of): Removed.
	(Prj.Pars): Now parse the project simulating a default config file.
	(Add_Default_GNAT_Naming_Scheme): New subprogram
	(Check_Naming_Multi_Lang): Fix default value for Dot_Replacement.
	Remove gnatmake-specific parsing of source files.
	(Check_Illegal_Suffix): Renames Is_Illegal_Suffix, since it now raises
	the error itself to provide more precise diagnostics.
	(Process_Exceptions_Unit_Based): Avoid duplicate error message when
	a unit belongs to several projects.
	(Copy_Interface_Sources): Search the full path of files to copy in the
	list of sources of the application rather than in the list of units.
	(Parse_Project_And_Apply_Config): Do not reset the name of the main
 	project file.
	(Check_File): Use htables to find out whether a source is duplicated.
	(Add_Source): check whether the source or unit were already seen earlier

	* gcc-interface/Makefile.in: Update gnatmake dependencies.

From-SVN: r149557
parent 1629f700
2009-07-13 Emmanuel Briot <briot@adacore.com>
* gnatcmd.adb, make.adb, mlib-prj.adb, prj-part.adb, mlib.adb,
prj.adb, prj.ads, clean.adb, prj-nmsc.adb, prj-nmsc.ads, prj-pars.adb,
prj-pars.ads, prj-conf.adb, prj-conf.ads, prj-tree.adb,
prj-tree.ads (Immediate_Directory_Of): Removed.
(Prj.Pars): Now parse the project simulating a default config file.
(Add_Default_GNAT_Naming_Scheme): New subprogram
(Check_Naming_Multi_Lang): Fix default value for Dot_Replacement.
Remove gnatmake-specific parsing of source files.
(Check_Illegal_Suffix): Renames Is_Illegal_Suffix, since it now raises
the error itself to provide more precise diagnostics.
(Process_Exceptions_Unit_Based): Avoid duplicate error message when
a unit belongs to several projects.
(Copy_Interface_Sources): Search the full path of files to copy in the
list of sources of the application rather than in the list of units.
(Parse_Project_And_Apply_Config): Do not reset the name of the main
project file.
(Check_File): Use htables to find out whether a source is duplicated.
(Add_Source): check whether the source or unit were already seen earlier
* gcc-interface/Makefile.in: Update gnatmake dependencies.
2009-07-13 Robert Dewar <dewar@adacore.com> 2009-07-13 Robert Dewar <dewar@adacore.com>
* par-ch3.adb (P_Discrete_Choice_List): Choice can only be simple * par-ch3.adb (P_Discrete_Choice_List): Choice can only be simple
......
...@@ -1391,8 +1391,7 @@ package body Clean is ...@@ -1391,8 +1391,7 @@ package body Clean is
(Project => Main_Project, (Project => Main_Project,
In_Tree => Project_Tree, In_Tree => Project_Tree,
Project_File_Name => Project_File_Name.all, Project_File_Name => Project_File_Name.all,
Packages_To_Check => Packages_To_Check_By_Gnatmake, Packages_To_Check => Packages_To_Check_By_Gnatmake);
Is_Config_File => False);
if Main_Project = No_Project then if Main_Project = No_Project then
Fail ("""" & Project_File_Name.all & """ processing failed"); Fail ("""" & Project_File_Name.all & """ processing failed");
......
...@@ -295,6 +295,7 @@ GNATMAKE_OBJS = a-except.o ali.o ali-util.o s-casuti.o \ ...@@ -295,6 +295,7 @@ GNATMAKE_OBJS = a-except.o ali.o ali-util.o s-casuti.o \
make.o makeusg.o makeutl.o mlib.o mlib-fil.o mlib-prj.o mlib-tgt.o \ make.o makeusg.o makeutl.o mlib.o mlib-fil.o mlib-prj.o mlib-tgt.o \
mlib-tgt-specific.o mlib-utl.o namet.o nlists.o opt.o osint.o osint-m.o \ mlib-tgt-specific.o mlib-utl.o namet.o nlists.o opt.o osint.o osint-m.o \
output.o prj.o prj-attr.o prj-attr-pm.o prj-com.o prj-dect.o prj-env.o \ output.o prj.o prj-attr.o prj-attr-pm.o prj-com.o prj-dect.o prj-env.o \
prj-conf.o \
prj-err.o prj-ext.o prj-nmsc.o prj-pars.o prj-part.o prj-proc.o prj-strt.o \ prj-err.o prj-ext.o prj-nmsc.o prj-pars.o prj-part.o prj-proc.o prj-strt.o \
prj-tree.o prj-util.o rident.o s-exctab.o s-secsta.o s-stalib.o s-stoele.o \ prj-tree.o prj-util.o rident.o s-exctab.o s-secsta.o s-stalib.o s-stoele.o \
scans.o scng.o sdefault.o sfn_scan.o s-purexc.o s-htable.o sinfo.o sinput.o \ scans.o scng.o sdefault.o sfn_scan.o s-purexc.o s-htable.o sinfo.o sinput.o \
......
...@@ -365,7 +365,6 @@ procedure GNATCmd is ...@@ -365,7 +365,6 @@ procedure GNATCmd is
new String' new String'
(Get_Name_String (Get_Name_String
(Proj.Project.Object_Directory.Name) & (Proj.Project.Object_Directory.Name) &
Directory_Separator &
B_Start.all & B_Start.all &
MLib.Fil.Ext_To MLib.Fil.Ext_To
(Get_Name_String (Get_Name_String
...@@ -392,7 +391,6 @@ procedure GNATCmd is ...@@ -392,7 +391,6 @@ procedure GNATCmd is
new String' new String'
(Get_Name_String (Get_Name_String
(Proj.Project.Object_Directory.Name) & (Proj.Project.Object_Directory.Name) &
Directory_Separator &
B_Start.all & B_Start.all &
Get_Name_String (Proj.Project.Library_Name) & Get_Name_String (Proj.Project.Library_Name) &
".ci"); ".ci");
...@@ -514,7 +512,6 @@ procedure GNATCmd is ...@@ -514,7 +512,6 @@ procedure GNATCmd is
(Get_Name_String (Get_Name_String
(Unit.File_Names (Unit.File_Names
(Impl).Project. Object_Directory.Name) & (Impl).Project. Object_Directory.Name) &
Directory_Separator &
MLib.Fil.Ext_To MLib.Fil.Ext_To
(Get_Name_String (Get_Name_String
(Unit.File_Names (Impl).Display_File), (Unit.File_Names (Impl).Display_File),
...@@ -1077,7 +1074,6 @@ procedure GNATCmd is ...@@ -1077,7 +1074,6 @@ procedure GNATCmd is
begin begin
if Is_Regular_File if Is_Regular_File
(Dir & (Dir &
Directory_Separator &
ALI_File (1 .. Last)) ALI_File (1 .. Last))
then then
-- We have found the correct project, so we -- We have found the correct project, so we
...@@ -1085,8 +1081,8 @@ procedure GNATCmd is ...@@ -1085,8 +1081,8 @@ procedure GNATCmd is
Last_Switches.Table (J) := Last_Switches.Table (J) :=
new String' new String'
(Dir & Directory_Separator & (Dir
ALI_File (1 .. Last)); & ALI_File (1 .. Last));
-- And we are done -- And we are done
...@@ -1155,7 +1151,6 @@ procedure GNATCmd is ...@@ -1155,7 +1151,6 @@ procedure GNATCmd is
Last_Switches.Increment_Last; Last_Switches.Increment_Last;
Last_Switches.Table (Last_Switches.Last) := Last_Switches.Table (Last_Switches.Last) :=
new String'(Name_Buffer (1 .. Name_Len) & new String'(Name_Buffer (1 .. Name_Len) &
Directory_Separator &
Executable_Name Executable_Name
(Base_Name (Arg (Arg'First .. Last)))); (Base_Name (Arg (Arg'First .. Last))));
exit; exit;
...@@ -1784,8 +1779,7 @@ begin ...@@ -1784,8 +1779,7 @@ begin
(Project => Project, (Project => Project,
In_Tree => Project_Tree, In_Tree => Project_Tree,
Project_File_Name => Project_File.all, Project_File_Name => Project_File.all,
Packages_To_Check => Packages_To_Check, Packages_To_Check => Packages_To_Check);
Is_Config_File => False);
if Project = Prj.No_Project then if Project = Prj.No_Project then
Fail ("""" & Project_File.all & """ processing failed"); Fail ("""" & Project_File.all & """ processing failed");
......
...@@ -1978,12 +1978,8 @@ package body Make is ...@@ -1978,12 +1978,8 @@ package body Make is
Name_Len := 0; Name_Len := 0;
Add_Str_To_Name_Buffer (Res_Obj_Dir); Add_Str_To_Name_Buffer (Res_Obj_Dir);
if Name_Len > 1 and then if not Is_Directory_Separator (Name_Buffer (Name_Len)) then
(Name_Buffer (Name_Len) = '/' Add_Char_To_Name_Buffer (Directory_Separator);
or else
Name_Buffer (Name_Len) = Directory_Separator)
then
Name_Len := Name_Len - 1;
end if; end if;
Obj_Dir := Name_Find; Obj_Dir := Name_Find;
...@@ -4450,8 +4446,8 @@ package body Make is ...@@ -4450,8 +4446,8 @@ package body Make is
(ALI_Project.Object_Directory.Name); (ALI_Project.Object_Directory.Name);
end if; end if;
if Name_Buffer (Name_Len) /= if not Is_Directory_Separator
Directory_Separator (Name_Buffer (Name_Len))
then then
Add_Char_To_Name_Buffer (Directory_Separator); Add_Char_To_Name_Buffer (Directory_Separator);
end if; end if;
...@@ -5312,7 +5308,9 @@ package body Make is ...@@ -5312,7 +5308,9 @@ package body Make is
if not Is_Absolute_Path (Exec_File_Name) then if not Is_Absolute_Path (Exec_File_Name) then
Get_Name_String (Main_Project.Exec_Directory.Name); Get_Name_String (Main_Project.Exec_Directory.Name);
if Name_Buffer (Name_Len) /= Directory_Separator then if
not Is_Directory_Separator (Name_Buffer (Name_Len))
then
Add_Char_To_Name_Buffer (Directory_Separator); Add_Char_To_Name_Buffer (Directory_Separator);
end if; end if;
...@@ -6867,8 +6865,7 @@ package body Make is ...@@ -6867,8 +6865,7 @@ package body Make is
(Project => Main_Project, (Project => Main_Project,
In_Tree => Project_Tree, In_Tree => Project_Tree,
Project_File_Name => Project_File_Name.all, Project_File_Name => Project_File_Name.all,
Packages_To_Check => Packages_To_Check_By_Gnatmake, Packages_To_Check => Packages_To_Check_By_Gnatmake);
Is_Config_File => False);
-- The parsing of project files may have changed the current output -- The parsing of project files may have changed the current output
...@@ -7611,8 +7608,7 @@ package body Make is ...@@ -7611,8 +7608,7 @@ package body Make is
-- separator. -- separator.
if Argv (Argv'Last) = Directory_Separator then if Argv (Argv'Last) = Directory_Separator then
Object_Directory_Path := Object_Directory_Path := new String'(Argv);
new String'(Argv);
else else
Object_Directory_Path := Object_Directory_Path :=
new String'(Argv & Directory_Separator); new String'(Argv & Directory_Separator);
......
...@@ -2152,20 +2152,12 @@ package body MLib.Prj is ...@@ -2152,20 +2152,12 @@ package body MLib.Prj is
First_Unit : ALI.Unit_Id; First_Unit : ALI.Unit_Id;
Second_Unit : ALI.Unit_Id; Second_Unit : ALI.Unit_Id;
Data : Unit_Index;
Copy_Subunits : Boolean := False; Copy_Subunits : Boolean := False;
-- When True, indicates that subunits, if any, need to be copied too -- When True, indicates that subunits, if any, need to be copied too
procedure Copy (File_Name : File_Name_Type); procedure Copy (File_Name : File_Name_Type);
-- Copy one source of the project to the target directory -- Copy one source of the project to the target directory
function Is_Same_Or_Extension
(Extending : Project_Id;
Extended : Project_Id) return Boolean;
-- Return True if project Extending is equal to or extends project
-- Extended.
---------- ----------
-- Copy -- -- Copy --
---------- ----------
...@@ -2174,56 +2166,26 @@ package body MLib.Prj is ...@@ -2174,56 +2166,26 @@ package body MLib.Prj is
Success : Boolean; Success : Boolean;
pragma Warnings (Off, Success); pragma Warnings (Off, Success);
Source : Standard.Prj.Source_Id;
begin begin
Data := Units_Htable.Get_First (In_Tree.Units_HT); Source := Find_Source
(In_Tree, For_Project,
Unit_Loop : In_Extended_Only => True,
while Data /= No_Unit_Index loop Base_Name => File_Name);
-- Find and copy the immediate or inherited source
if Source /= No_Source
for J in Data.File_Names'Range loop and then not Source.Locally_Removed
if Data.File_Names (J) /= null and then Source.Replaced_By = No_Source
and then Is_Same_Or_Extension then
(For_Project, Data.File_Names (J).Project) Copy_File
and then Data.File_Names (J).File = File_Name (Get_Name_String (Source.Path.Name),
then Target,
Copy_File Success,
(Get_Name_String (Data.File_Names (J).Path.Name), Mode => Overwrite,
Target, Preserve => Preserve);
Success, end if;
Mode => Overwrite,
Preserve => Preserve);
exit Unit_Loop;
end if;
end loop;
Data := Units_Htable.Get_Next (In_Tree.Units_HT);
end loop Unit_Loop;
end Copy; end Copy;
--------------------------
-- Is_Same_Or_Extension --
--------------------------
function Is_Same_Or_Extension
(Extending : Project_Id;
Extended : Project_Id) return Boolean
is
Ext : Project_Id;
begin
Ext := Extending;
while Ext /= No_Project loop
if Ext = Extended then
return True;
end if;
Ext := Ext.Extends;
end loop;
return False;
end Is_Same_Or_Extension;
-- Start of processing for Copy_Interface_Sources -- Start of processing for Copy_Interface_Sources
begin begin
......
...@@ -55,7 +55,7 @@ package body MLib is ...@@ -55,7 +55,7 @@ package body MLib is
Write_Line (Output_File); Write_Line (Output_File);
end if; end if;
Ar (Output_Dir & Directory_Separator & Ar (Output_Dir &
"lib" & Output_File & ".a", Objects => Ofiles); "lib" & Output_File & ".a", Objects => Ofiles);
end Build_Library; end Build_Library;
......
...@@ -34,7 +34,6 @@ with Prj.Proc; use Prj.Proc; ...@@ -34,7 +34,6 @@ with Prj.Proc; use Prj.Proc;
with Prj.Tree; use Prj.Tree; with Prj.Tree; use Prj.Tree;
with Prj.Util; use Prj.Util; with Prj.Util; use Prj.Util;
with Prj; use Prj; with Prj; use Prj;
with Sinput.P;
with Snames; use Snames; with Snames; use Snames;
with System.Case_Util; use System.Case_Util; with System.Case_Util; use System.Case_Util;
with System; with System;
...@@ -908,7 +907,9 @@ package body Prj.Conf is ...@@ -908,7 +907,9 @@ package body Prj.Conf is
Report_Error : Put_Line_Access := null; Report_Error : Put_Line_Access := null;
On_Load_Config : Config_File_Hook := null; On_Load_Config : Config_File_Hook := null;
Compiler_Driver_Mandatory : Boolean := True; Compiler_Driver_Mandatory : Boolean := True;
Allow_Duplicate_Basenames : Boolean := False) Allow_Duplicate_Basenames : Boolean := False;
Reset_Tree : Boolean := True;
When_No_Sources : Error_Warning := Warning)
is is
Main_Config_Project : Project_Id; Main_Config_Project : Project_Id;
Success : Boolean; Success : Boolean;
...@@ -923,7 +924,8 @@ package body Prj.Conf is ...@@ -923,7 +924,8 @@ package body Prj.Conf is
Success => Success, Success => Success,
From_Project_Node => User_Project_Node, From_Project_Node => User_Project_Node,
From_Project_Node_Tree => Project_Node_Tree, From_Project_Node_Tree => Project_Node_Tree,
Report_Error => Report_Error); Report_Error => Report_Error,
Reset_Tree => Reset_Tree);
if not Success then if not Success then
Main_Project := No_Project; Main_Project := No_Project;
...@@ -951,8 +953,6 @@ package body Prj.Conf is ...@@ -951,8 +953,6 @@ package body Prj.Conf is
-- Finish processing the user's project -- Finish processing the user's project
Sinput.P.Reset_First;
Prj.Proc.Process_Project_Tree_Phase_2 Prj.Proc.Process_Project_Tree_Phase_2
(In_Tree => Project_Tree, (In_Tree => Project_Tree,
Project => Main_Project, Project => Main_Project,
...@@ -961,7 +961,7 @@ package body Prj.Conf is ...@@ -961,7 +961,7 @@ package body Prj.Conf is
From_Project_Node_Tree => Project_Node_Tree, From_Project_Node_Tree => Project_Node_Tree,
Report_Error => Report_Error, Report_Error => Report_Error,
Current_Dir => Current_Directory, Current_Dir => Current_Directory,
When_No_Sources => Warning, When_No_Sources => When_No_Sources,
Compiler_Driver_Mandatory => Compiler_Driver_Mandatory, Compiler_Driver_Mandatory => Compiler_Driver_Mandatory,
Allow_Duplicate_Basenames => Allow_Duplicate_Basenames, Allow_Duplicate_Basenames => Allow_Duplicate_Basenames,
Is_Config_File => False); Is_Config_File => False);
...@@ -1121,4 +1121,76 @@ package body Prj.Conf is ...@@ -1121,4 +1121,76 @@ package body Prj.Conf is
end if; end if;
end Runtime_Name_For; end Runtime_Name_For;
------------------------------------
-- Add_Default_GNAT_Naming_Scheme --
------------------------------------
procedure Add_Default_GNAT_Naming_Scheme
(Config_File : in out Project_Node_Id;
Project_Tree : Project_Node_Tree_Ref)
is
Name : Name_Id;
begin
if Config_File = Empty_Node then
-- Create a dummy config file is none was found.
Name_Len := Auto_Cgpr'Length;
Name_Buffer (1 .. Name_Len) := Auto_Cgpr;
Name := Name_Find;
Config_File := Create_Project
(In_Tree => Project_Tree,
Name => Name,
Full_Path => Path_Name_Type (Name),
Is_Config_File => True);
-- ??? This isn't strictly required, since Prj.Nmsc.Add_Language
-- already has a workaround in the Ada_Only case. But it would be
-- nicer to do it this way
-- Likewise for the default language, hard-coded in
-- Pjr.Nmsc.Check_Programming_Languages
-- Update_Attribute_Value_In_Scenario
-- (Tree => Project_Tree,
-- Project => Config_File,
-- Scenario_Variables => No_Scenario,
-- Attribute => "default_language",
-- Value => "Ada");
--
-- Update_Attribute_Value_In_Scenario
-- (Tree => Project_Tree,
-- Project => Config_File,
-- Scenario_Variables => No_Scenario,
-- Attribute => Separate_Suffix_Attribute,
-- Value => ".adb",
-- Attribute_Index => "Ada");
-- Update_Attribute_Value_In_Scenario
-- (Tree => Project_Tree,
-- Project => Config_File,
-- Scenario_Variables => No_Scenario,
-- Attribute => Spec_Suffix_Attribute,
-- Value => ".ads",
-- Attribute_Index => "Ada");
-- Update_Attribute_Value_In_Scenario
-- (Tree => Project_Tree,
-- Project => Config_File,
-- Scenario_Variables => No_Scenario,
-- Attribute => Impl_Suffix_Attribute,
-- Value => ".adb",
-- Attribute_Index => "Ada");
-- Update_Attribute_Value_In_Scenario
-- (Tree => Project_Tree,
-- Project => Config_File,
-- Scenario_Variables => No_Scenario,
-- Attribute => Dot_Replacement_Attribute,
-- Value => "-");
-- Update_Attribute_Value_In_Scenario
-- (Tree => Project_Tree,
-- Project => Config_File,
-- Scenario_Variables => No_Scenario,
-- Attribute => Casing_Attribute,
-- Value => "lowercase");
end if;
end Add_Default_GNAT_Naming_Scheme;
end Prj.Conf; end Prj.Conf;
...@@ -99,10 +99,15 @@ package Prj.Conf is ...@@ -99,10 +99,15 @@ package Prj.Conf is
Report_Error : Put_Line_Access := null; Report_Error : Put_Line_Access := null;
On_Load_Config : Config_File_Hook := null; On_Load_Config : Config_File_Hook := null;
Compiler_Driver_Mandatory : Boolean := True; Compiler_Driver_Mandatory : Boolean := True;
Allow_Duplicate_Basenames : Boolean := False); Allow_Duplicate_Basenames : Boolean := False;
Reset_Tree : Boolean := True;
When_No_Sources : Error_Warning := Warning);
-- Same as above, except the project must already have been parsed through -- Same as above, except the project must already have been parsed through
-- Prj.Part.Parse, and only the processing of the project and the -- Prj.Part.Parse, and only the processing of the project and the
-- configuration is done at this level. -- configuration is done at this level.
-- If Reset_Tree is true, all projects are first removed from the tree.
-- When_No_Sources indicates what should be done when no sources are found
-- for one of the languages of the project.
Invalid_Config : exception; Invalid_Config : exception;
...@@ -162,6 +167,15 @@ package Prj.Conf is ...@@ -162,6 +167,15 @@ package Prj.Conf is
-- projects, so that when the second phase of the processing is performed -- projects, so that when the second phase of the processing is performed
-- these attributes are automatically taken into account. -- these attributes are automatically taken into account.
procedure Add_Default_GNAT_Naming_Scheme
(Config_File : in out Prj.Tree.Project_Node_Id;
Project_Tree : Prj.Tree.Project_Node_Tree_Ref);
-- A hook for Get_Or_Create_Configuration_File and
-- Process_Project_And_Apply_Config that will create a new config file (in
-- memory) and add the default GNAT naming scheme to it. Nothing is done
-- if the config_file already exists, to avoid overriding what the user
-- might have put in there.
-------------- --------------
-- Runtimes -- -- Runtimes --
-------------- --------------
......
...@@ -28,7 +28,6 @@ with GNAT.Directory_Operations; use GNAT.Directory_Operations; ...@@ -28,7 +28,6 @@ with GNAT.Directory_Operations; use GNAT.Directory_Operations;
with GNAT.HTable; with GNAT.HTable;
with Err_Vars; use Err_Vars; with Err_Vars; use Err_Vars;
with Hostparm;
with MLib.Tgt; with MLib.Tgt;
with Opt; use Opt; with Opt; use Opt;
with Osint; use Osint; with Osint; use Osint;
...@@ -165,8 +164,8 @@ package body Prj.Nmsc is ...@@ -165,8 +164,8 @@ package body Prj.Nmsc is
package Object_File_Names is new GNAT.HTable.Simple_HTable package Object_File_Names is new GNAT.HTable.Simple_HTable
(Header_Num => Header_Num, (Header_Num => Header_Num,
Element => File_Name_Type, Element => Source_Id,
No_Element => No_File, No_Element => No_Source,
Key => File_Name_Type, Key => File_Name_Type,
Hash => Hash, Hash => Hash,
Equal => "="); Equal => "=");
...@@ -235,24 +234,23 @@ package body Prj.Nmsc is ...@@ -235,24 +234,23 @@ package body Prj.Nmsc is
procedure Add_Source procedure Add_Source
(Id : out Source_Id; (Id : out Source_Id;
In_Tree : Project_Tree_Ref; In_Tree : Project_Tree_Ref;
File_To_Source : in out Files_Htable.Instance;
Project : Project_Id; Project : Project_Id;
Lang_Id : Language_Ptr; Lang_Id : Language_Ptr;
Kind : Source_Kind; Kind : Source_Kind;
File_Name : File_Name_Type; File_Name : File_Name_Type;
Display_File : File_Name_Type; Display_File : File_Name_Type;
Allow_Duplicate_Basenames : Boolean;
Naming_Exception : Boolean := False; Naming_Exception : Boolean := False;
Path : Path_Information := No_Path_Information; Path : Path_Information := No_Path_Information;
Alternate_Languages : Language_List := null; Alternate_Languages : Language_List := null;
Unit : Name_Id := No_Name; Unit : Name_Id := No_Name;
Index : Int := 0; Index : Int := 0);
Source_To_Replace : Source_Id := No_Source);
-- Add a new source to the different lists: list of all sources in the -- Add a new source to the different lists: list of all sources in the
-- project tree, list of source of a project and list of sources of a -- project tree, list of source of a project and list of sources of a
-- language. -- language.
-- --
-- If Path is specified, the file is also added to Source_Paths_HT. -- If Path is specified, the file is also added to Source_Paths_HT.
-- If Source_To_Replace is specified, it points to the source in the
-- extended project that the new file is overriding.
function Canonical_Case_File_Name (Name : Name_Id) return File_Name_Type; function Canonical_Case_File_Name (Name : Name_Id) return File_Name_Type;
-- Same as Osint.Canonical_Case_File_Name but applies to Name_Id. -- Same as Osint.Canonical_Case_File_Name but applies to Name_Id.
...@@ -278,11 +276,13 @@ package body Prj.Nmsc is ...@@ -278,11 +276,13 @@ package body Prj.Nmsc is
-- Check that a name is a valid Ada unit name -- Check that a name is a valid Ada unit name
procedure Check_Package_Naming procedure Check_Package_Naming
(Project : Project_Id; (Project : Project_Id;
In_Tree : Project_Tree_Ref; In_Tree : Project_Tree_Ref;
Is_Config_File : Boolean; File_To_Source : in out Files_Htable.Instance;
Bodies : out Array_Element_Id; Is_Config_File : Boolean;
Specs : out Array_Element_Id); Allow_Duplicate_Basenames : Boolean;
Bodies : out Array_Element_Id;
Specs : out Array_Element_Id);
-- Check the naming scheme part of Data, and initialize the naming scheme -- Check the naming scheme part of Data, and initialize the naming scheme
-- data in the config of the various languages. Is_Config_File should be -- data in the config of the various languages. Is_Config_File should be
-- True if Project is a config file (.cgpr) This also returns the naming -- True if Project is a config file (.cgpr) This also returns the naming
...@@ -342,27 +342,6 @@ package body Prj.Nmsc is ...@@ -342,27 +342,6 @@ package body Prj.Nmsc is
-- Current_Dir should represent the current directory, and is passed for -- Current_Dir should represent the current directory, and is passed for
-- efficiency to avoid system calls to recompute it. -- efficiency to avoid system calls to recompute it.
procedure Check_And_Normalize_Unit_Names
(Project : Project_Id;
In_Tree : Project_Tree_Ref;
List : Array_Element_Id;
Debug_Name : String);
-- Check that a list of unit names contains only valid names. Casing
-- is normalized where appropriate.
-- Debug_Name is the name representing the list, and is used for debug
-- output only.
procedure Find_Ada_Sources
(Project : Project_Id;
In_Tree : Project_Tree_Ref;
Explicit_Sources_Only : Boolean;
Proc_Data : in out Processing_Data);
-- Find all Ada sources by traversing all source directories. If
-- Explicit_Sources_Only is True, then the sources found must belong to
-- the list of sources specified explicitly in the project file. If
-- Explicit_Sources_Only is False, then all sources matching the naming
-- scheme are recorded.
function Compute_Directory_Last (Dir : String) return Natural; function Compute_Directory_Last (Dir : String) return Natural;
-- Return the index of the last significant character in Dir. This is used -- Return the index of the last significant character in Dir. This is used
-- to avoid duplicate '/' (slash) characters at the end of directory names. -- to avoid duplicate '/' (slash) characters at the end of directory names.
...@@ -379,6 +358,7 @@ package body Prj.Nmsc is ...@@ -379,6 +358,7 @@ package body Prj.Nmsc is
procedure Search_Directories procedure Search_Directories
(Project : Project_Id; (Project : Project_Id;
In_Tree : Project_Tree_Ref; In_Tree : Project_Tree_Ref;
File_To_Source : in out Files_Htable.Instance;
For_All_Sources : Boolean; For_All_Sources : Boolean;
Allow_Duplicate_Basenames : Boolean; Allow_Duplicate_Basenames : Boolean;
Excluded : in out Excluded_Sources_Htable.Instance); Excluded : in out Excluded_Sources_Htable.Instance);
...@@ -392,9 +372,11 @@ package body Prj.Nmsc is ...@@ -392,9 +372,11 @@ package body Prj.Nmsc is
procedure Check_File procedure Check_File
(Project : Project_Id; (Project : Project_Id;
In_Tree : Project_Tree_Ref; In_Tree : Project_Tree_Ref;
File_To_Source : in out Files_Htable.Instance;
Path : Path_Name_Type; Path : Path_Name_Type;
File_Name : File_Name_Type; File_Name : File_Name_Type;
Display_File_Name : File_Name_Type; Display_File_Name : File_Name_Type;
Locally_Removed : Boolean;
For_All_Sources : Boolean; For_All_Sources : Boolean;
Allow_Duplicate_Basenames : Boolean); Allow_Duplicate_Basenames : Boolean);
-- Check if file File_Name is a valid source of the project. This is used -- Check if file File_Name is a valid source of the project. This is used
...@@ -464,7 +446,7 @@ package body Prj.Nmsc is ...@@ -464,7 +446,7 @@ package body Prj.Nmsc is
procedure Find_Sources procedure Find_Sources
(Project : Project_Id; (Project : Project_Id;
In_Tree : Project_Tree_Ref; In_Tree : Project_Tree_Ref;
Proc_Data : in out Processing_Data; File_To_Source : in out Files_Htable.Instance;
Allow_Duplicate_Basenames : Boolean; Allow_Duplicate_Basenames : Boolean;
Excluded : in out Excluded_Sources_Htable.Instance); Excluded : in out Excluded_Sources_Htable.Instance);
-- Process the Source_Files and Source_List_File attributes, and store the -- Process the Source_Files and Source_List_File attributes, and store the
...@@ -484,24 +466,17 @@ package body Prj.Nmsc is ...@@ -484,24 +466,17 @@ package body Prj.Nmsc is
-- compute its unit name. If Unit is set to No_Name on exit, none of the -- compute its unit name. If Unit is set to No_Name on exit, none of the
-- other out parameters are relevant. -- other out parameters are relevant.
procedure Get_Unit procedure Check_Illegal_Suffix
(In_Tree : Project_Tree_Ref; (Project : Project_Id;
Canonical_File_Name : File_Name_Type; In_Tree : Project_Tree_Ref;
Project : Project_Id; Suffix : File_Name_Type;
Exception_Id : out Ada_Naming_Exception_Id; Dot_Replacement : File_Name_Type;
Unit_Name : out Name_Id; Attribute_Name : String;
Unit_Kind : out Spec_Or_Body); Location : Source_Ptr);
-- Find out, from a file name, the unit name, the unit kind and if a -- Display an error message if the given suffix is illegal for some reason.
-- specific SFN pragma is needed. If the file name corresponds to no unit, -- The name of the attribute we are testing is specified in Attribute_Name,
-- then Unit_Name will be No_Name. If the file is a multi-unit source or an -- which is used in the error message. Location is the location where the
-- exception to the naming scheme, then Exception_Id is set to the unit or -- suffix is defined.
-- units that the source contains, and the other information are not set.
function Is_Illegal_Suffix
(Suffix : File_Name_Type;
Dot_Replacement : File_Name_Type) 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 procedure Locate_Directory
(Project : Project_Id; (Project : Project_Id;
...@@ -542,26 +517,6 @@ package body Prj.Nmsc is ...@@ -542,26 +517,6 @@ package body Prj.Nmsc is
-- Returns the path name of a (non project) file. Returns an empty string -- Returns the path name of a (non project) file. Returns an empty string
-- if file cannot be found. -- 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.
procedure Record_Ada_Source
(File_Name : File_Name_Type;
Path_Name : Path_Name_Type;
Project : Project_Id;
In_Tree : Project_Tree_Ref;
Proc_Data : in out Processing_Data;
Ada_Language : Language_Ptr;
Location : Source_Ptr;
Source_Recorded : in out Boolean);
-- Put a unit in the list of units of a project, if the file name
-- corresponds to a valid unit name. Ada_Language is a pointer to the
-- Language_Data for "Ada" in Project.
procedure Remove_Source procedure Remove_Source
(Id : Source_Id; (Id : Source_Id;
Replaced_By : Source_Id); Replaced_By : Source_Id);
...@@ -684,28 +639,160 @@ package body Prj.Nmsc is ...@@ -684,28 +639,160 @@ package body Prj.Nmsc is
procedure Add_Source procedure Add_Source
(Id : out Source_Id; (Id : out Source_Id;
In_Tree : Project_Tree_Ref; In_Tree : Project_Tree_Ref;
File_To_Source : in out Files_Htable.Instance;
Project : Project_Id; Project : Project_Id;
Lang_Id : Language_Ptr; Lang_Id : Language_Ptr;
Kind : Source_Kind; Kind : Source_Kind;
File_Name : File_Name_Type; File_Name : File_Name_Type;
Display_File : File_Name_Type; Display_File : File_Name_Type;
Allow_Duplicate_Basenames : Boolean;
Naming_Exception : Boolean := False; Naming_Exception : Boolean := False;
Path : Path_Information := No_Path_Information; Path : Path_Information := No_Path_Information;
Alternate_Languages : Language_List := null; Alternate_Languages : Language_List := null;
Unit : Name_Id := No_Name; Unit : Name_Id := No_Name;
Index : Int := 0; Index : Int := 0)
Source_To_Replace : Source_Id := No_Source)
is is
Config : constant Language_Config := Lang_Id.Config; Config : constant Language_Config := Lang_Id.Config;
UData : Unit_Index; UData : Unit_Index;
Add_Src : Boolean;
Source : Source_Id;
Prev_Unit : Unit_Index := No_Unit_Index;
Source_To_Replace : Source_Id := No_Source;
begin begin
-- Check if the same file name or unit is used in the prj tree
Add_Src := True;
Source := Files_Htable.Get (File_To_Source, File_Name);
if Unit /= No_Name then
Prev_Unit := Units_Htable.Get (In_Tree.Units_HT, Unit);
end if;
if Prev_Unit /= No_Unit_Index
and then (Kind = Impl or Kind = Spec)
and then Prev_Unit.File_Names (Kind) /= null
then
-- Suspicious, we need to check later whether this is authorized
Add_Src := False;
Source := Prev_Unit.File_Names (Kind);
elsif Source /= No_Source then
if Source.Index = Index then
Add_Src := False;
end if;
end if;
-- Duplication of file/unit in same project is allowed
-- if order of source directories is known.
if Add_Src = False then
Add_Src := True;
if Project = Source.Project then
if Prev_Unit = No_Unit_Index then
if Allow_Duplicate_Basenames then
Add_Src := True;
elsif Project.Known_Order_Of_Source_Dirs then
Add_Src := False;
else
Error_Msg_File_1 := File_Name;
Error_Msg
(Project, In_Tree, "duplicate source file name {",
No_Location);
Add_Src := False;
end if;
else
if Project.Known_Order_Of_Source_Dirs then
Add_Src := False;
-- We might be seeing the same file through a different path
-- (for instance because of symbolic links)
elsif Source.Path.Name /= Path.Name then
Error_Msg_Name_1 := Unit;
Error_Msg
(Project, In_Tree, "duplicate unit %%",
No_Location);
Add_Src := False;
end if;
end if;
-- Do not allow the same unit name in different projects,
-- except if one is extending the other.
-- For a file based language, the same file name replaces
-- a file in a project being extended, but it is allowed
-- to have the same file name in unrelated projects.
elsif Is_Extending (Project, Source.Project) then
Source_To_Replace := Source;
elsif Prev_Unit /= No_Unit_Index
and then not Source.Locally_Removed
then
if Path /= No_Path_Information then
Error_Msg_Name_1 := Unit;
Error_Msg
(Project, In_Tree,
"unit %% cannot belong to several projects",
No_Location);
Error_Msg_Name_1 := Project.Name;
Error_Msg_Name_2 := Name_Id (Path.Name);
Error_Msg
(Project, In_Tree, "\ project %%, %%", No_Location);
Error_Msg_Name_1 := Source.Project.Name;
Error_Msg_Name_2 := Name_Id (Source.Path.Display_Name);
Error_Msg
(Project, In_Tree, "\ project %%, %%", No_Location);
else
Error_Msg_Name_1 := Unit;
Error_Msg_Name_2 := Source.Project.Name;
Error_Msg
(Project, In_Tree,
"unit %% already belongs to project %%",
No_Location);
end if;
Add_Src := False;
elsif not Source.Locally_Removed
and then not Allow_Duplicate_Basenames
and then Lang_Id.Config.Kind = Unit_Based
then
Error_Msg_File_1 := File_Name;
Error_Msg_File_2 := File_Name_Type (Source.Project.Name);
Error_Msg
(Project, In_Tree,
"{ is already a source of project {",
No_Location);
-- Add the file anyway, to avoid further warnings like "language
-- unknown"
Add_Src := True;
end if;
end if;
if not Add_Src then
return;
end if;
-- Add the new file
Id := new Source_Data; Id := new Source_Data;
if Current_Verbosity = High then if Current_Verbosity = High then
Write_Str ("Adding source File: "); Write_Str ("Adding source File: ");
Write_Str (Get_Name_String (File_Name)); Write_Str (Get_Name_String (File_Name));
if Index /= 0 then
Write_Str (" at" & Index'Img);
end if;
if Lang_Id.Config.Kind = Unit_Based then if Lang_Id.Config.Kind = Unit_Based then
Write_Str (" Unit: "); Write_Str (" Unit: ");
...@@ -778,6 +865,8 @@ package body Prj.Nmsc is ...@@ -778,6 +865,8 @@ package body Prj.Nmsc is
if Source_To_Replace /= No_Source then if Source_To_Replace /= No_Source then
Remove_Source (Source_To_Replace, Id); Remove_Source (Source_To_Replace, Id);
end if; end if;
Files_Htable.Set (File_To_Source, File_Name, Id);
end Add_Source; end Add_Source;
------------------- -------------------
...@@ -906,12 +995,10 @@ package body Prj.Nmsc is ...@@ -906,12 +995,10 @@ package body Prj.Nmsc is
Extending := Project.Extends /= No_Project; Extending := Project.Extends /= No_Project;
Check_Package_Naming (Project, In_Tree, Is_Config_File, Bodies, Specs); Check_Package_Naming
(Project, In_Tree, Proc_Data.Units, Is_Config_File,
if Get_Mode = Ada_Only then Allow_Duplicate_Basenames => Allow_Duplicate_Basenames,
Prepare_Ada_Naming_Exceptions (Bodies, In_Tree, Impl); Bodies => Bodies, Specs => Specs);
Prepare_Ada_Naming_Exceptions (Specs, In_Tree, Spec);
end if;
-- Find the sources -- Find the sources
...@@ -2648,79 +2735,24 @@ package body Prj.Nmsc is ...@@ -2648,79 +2735,24 @@ package body Prj.Nmsc is
end if; end if;
end Check_Interfaces; end Check_Interfaces;
------------------------------------
-- Check_And_Normalize_Unit_Names --
------------------------------------
procedure Check_And_Normalize_Unit_Names
(Project : Project_Id;
In_Tree : Project_Tree_Ref;
List : Array_Element_Id;
Debug_Name : String)
is
Current : Array_Element_Id;
Element : Array_Element;
Unit_Name : Name_Id;
begin
if Current_Verbosity = High then
Write_Line (" Checking unit names in " & Debug_Name);
end if;
Current := List;
while Current /= No_Array_Element loop
Element := In_Tree.Array_Elements.Table (Current);
Element.Value.Value :=
Name_Id (Canonical_Case_File_Name (Element.Value.Value));
-- 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 (" for unit: ");
Write_Line (Get_Name_String (Unit_Name));
end if;
Element.Index := Unit_Name;
In_Tree.Array_Elements.Table (Current) := Element;
end if;
Current := Element.Next;
end loop;
end Check_And_Normalize_Unit_Names;
-------------------------- --------------------------
-- Check_Package_Naming -- -- Check_Package_Naming --
-------------------------- --------------------------
procedure Check_Package_Naming procedure Check_Package_Naming
(Project : Project_Id; (Project : Project_Id;
In_Tree : Project_Tree_Ref; In_Tree : Project_Tree_Ref;
Is_Config_File : Boolean; File_To_Source : in out Files_Htable.Instance;
Bodies : out Array_Element_Id; Is_Config_File : Boolean;
Specs : out Array_Element_Id) Allow_Duplicate_Basenames : Boolean;
Bodies : out Array_Element_Id;
Specs : out Array_Element_Id)
is is
Naming_Id : constant Package_Id := Naming_Id : constant Package_Id :=
Util.Value_Of (Name_Naming, Project.Decl.Packages, In_Tree); Util.Value_Of (Name_Naming, Project.Decl.Packages, In_Tree);
Naming : Package_Element; Naming : Package_Element;
Ada_Body_Suffix_Loc : Source_Ptr := No_Location; Ada_Body_Suffix_Loc : Source_Ptr := No_Location;
Ada_Spec_Suffix_Loc : Source_Ptr := No_Location;
procedure Check_Naming_Ada_Only;
-- Does Check_Naming_Schemes processing in Ada_Only mode.
-- If there is a package Naming, puts in Data.Naming the contents of
-- this package.
procedure Check_Naming_Multi_Lang; procedure Check_Naming_Multi_Lang;
-- Does Check_Naming_Schemes processing for Multi_Language mode -- Does Check_Naming_Schemes processing for Multi_Language mode
...@@ -2873,13 +2905,9 @@ package body Prj.Nmsc is ...@@ -2873,13 +2905,9 @@ package body Prj.Nmsc is
Separate_Suffix := Canonical_Case_File_Name (Sep_Suffix.Value); Separate_Suffix := Canonical_Case_File_Name (Sep_Suffix.Value);
Sep_Suffix_Loc := Sep_Suffix.Location; Sep_Suffix_Loc := Sep_Suffix.Location;
if Is_Illegal_Suffix (Separate_Suffix, Dot_Replacement) then Check_Illegal_Suffix
Err_Vars.Error_Msg_File_1 := Separate_Suffix; (Project, In_Tree, Separate_Suffix,
Error_Msg Dot_Replacement, "Separate_Suffix", Sep_Suffix.Location);
(Project, In_Tree,
"{ is illegal for Separate_Suffix",
Sep_Suffix.Location);
end if;
end if; end if;
end if; end if;
...@@ -2945,9 +2973,11 @@ package body Prj.Nmsc is ...@@ -2945,9 +2973,11 @@ package body Prj.Nmsc is
Add_Source Add_Source
(Id => Source, (Id => Source,
In_Tree => In_Tree, In_Tree => In_Tree,
File_To_Source => File_To_Source,
Project => Project, Project => Project,
Lang_Id => Lang_Id, Lang_Id => Lang_Id,
Kind => Kind, Kind => Kind,
Allow_Duplicate_Basenames => Allow_Duplicate_Basenames,
File_Name => File_Name, File_Name => File_Name,
Display_File => File_Name_Type (Element.Value), Display_File => File_Name_Type (Element.Value),
Naming_Exception => True); Naming_Exception => True);
...@@ -2997,9 +3027,6 @@ package body Prj.Nmsc is ...@@ -2997,9 +3027,6 @@ package body Prj.Nmsc is
Index : Int; Index : Int;
File_Name : File_Name_Type; File_Name : File_Name_Type;
Source : Source_Id; Source : Source_Id;
Source_To_Replace : Source_Id := No_Source;
Other_Project : Project_Id;
Iter : Source_Iterator;
begin begin
case Kind is case Kind is
...@@ -3057,182 +3084,32 @@ package body Prj.Nmsc is ...@@ -3057,182 +3084,32 @@ package body Prj.Nmsc is
end if; end if;
if Unit /= No_Name then if Unit /= No_Name then
Add_Source
-- Check if the source already exists (Id => Source,
-- ??? In Ada_Only mode (Record_Unit), we use a htable for In_Tree => In_Tree,
-- efficiency File_To_Source => File_To_Source,
Project => Project,
Source_To_Replace := No_Source; Lang_Id => Lang_Id,
Iter := For_Each_Source (In_Tree); Kind => Kind,
File_Name => File_Name,
loop Allow_Duplicate_Basenames => Allow_Duplicate_Basenames,
Source := Prj.Element (Iter); Display_File => File_Name_Type (Element.Value.Value),
exit when Source = No_Source Unit => Unit,
or else (Source.Unit /= null Index => Index,
and then Source.Unit.Name = Unit Naming_Exception => True);
and then Source.Index = Index);
Next (Iter);
end loop;
if Source /= No_Source then
if Source.Kind /= Kind then
loop
Next (Iter);
Source := Prj.Element (Iter);
exit when Source = No_Source
or else (Source.Unit /= null
and then Source.Unit.Name = Unit
and then Source.Index = Index);
end loop;
end if;
if Source /= No_Source then
Other_Project := Source.Project;
if Is_Extending (Project, Other_Project) then
Source_To_Replace := Source;
Source := No_Source;
else
Error_Msg_Name_1 := Unit;
Error_Msg_Name_2 := Other_Project.Name;
Error_Msg
(Project,
In_Tree,
"%% is already a source of project %%",
Element.Value.Location);
end if;
end if;
end if;
if Source = No_Source then
Add_Source
(Id => Source,
In_Tree => In_Tree,
Project => Project,
Lang_Id => Lang_Id,
Kind => Kind,
File_Name => File_Name,
Display_File => File_Name_Type (Element.Value.Value),
Unit => Unit,
Index => Index,
Naming_Exception => True,
Source_To_Replace => Source_To_Replace);
end if;
end if; end if;
Exceptions := Element.Next; Exceptions := Element.Next;
end loop; end loop;
end Process_Exceptions_Unit_Based; end Process_Exceptions_Unit_Based;
---------------------------
-- Check_Naming_Ada_Only --
---------------------------
procedure Check_Naming_Ada_Only is
Ada : constant Language_Ptr :=
Get_Language_From_Name (Project, "ada");
Casing_Defined : Boolean;
Sep_Suffix_Loc : Source_Ptr;
begin
-- If no language, then nothing to do
if Ada = null then
return;
end if;
declare
Data : Lang_Naming_Data renames Ada.Config.Naming_Data;
begin
-- The default value of separate suffix should be the same as the
-- body suffix, so we need to compute that first.
Data.Separate_Suffix := Data.Body_Suffix;
Write_Attr ("Body_Suffix", Get_Name_String (Data.Body_Suffix));
-- We'll need the dot replacement below, so compute it now
Check_Common
(Dot_Replacement => Data.Dot_Replacement,
Casing => Data.Casing,
Casing_Defined => Casing_Defined,
Separate_Suffix => Data.Separate_Suffix,
Sep_Suffix_Loc => Sep_Suffix_Loc);
Bodies := Util.Value_Of (Name_Body, Naming.Decl.Arrays, In_Tree);
if Bodies /= No_Array_Element then
Check_And_Normalize_Unit_Names
(Project, In_Tree, Bodies, "Naming.Bodies");
end if;
Specs := Util.Value_Of (Name_Spec, Naming.Decl.Arrays, In_Tree);
if Specs /= No_Array_Element then
Check_And_Normalize_Unit_Names
(Project, In_Tree, Specs, "Naming.Specs");
end if;
-- Check Spec_Suffix
if Is_Illegal_Suffix (Data.Spec_Suffix, Data.Dot_Replacement) then
Err_Vars.Error_Msg_File_1 := Data.Spec_Suffix;
Error_Msg
(Project, In_Tree,
"{ is illegal for Spec_Suffix",
Ada_Spec_Suffix_Loc);
end if;
Write_Attr ("Spec_Suffix", Get_Name_String (Data.Spec_Suffix));
-- Check Body_Suffix
if Is_Illegal_Suffix (Data.Body_Suffix, Data.Dot_Replacement) then
Err_Vars.Error_Msg_File_1 := Data.Body_Suffix;
Error_Msg
(Project, In_Tree,
"{ is illegal for Body_Suffix",
Ada_Body_Suffix_Loc);
end if;
-- Spec_Suffix cannot be equal to Body_Suffix or Separate_Suffix,
-- since that would cause a clear ambiguity. Note that we do allow
-- a Spec_Suffix to have the same termination as one of these,
-- which causes a potential ambiguity, but we resolve that my
-- matching the longest possible suffix.
if Data.Spec_Suffix = Data.Body_Suffix then
Error_Msg
(Project, In_Tree,
"Body_Suffix ("""
& Get_Name_String (Data.Body_Suffix)
& """) cannot be the same as Spec_Suffix.",
Ada_Body_Suffix_Loc);
end if;
if Data.Body_Suffix /= Data.Separate_Suffix
and then Data.Spec_Suffix = Data.Separate_Suffix
then
Error_Msg
(Project, In_Tree,
"Separate_Suffix ("""
& Get_Name_String (Data.Separate_Suffix)
& """) cannot be the same as Spec_Suffix.",
Sep_Suffix_Loc);
end if;
end;
end Check_Naming_Ada_Only;
----------------------------- -----------------------------
-- Check_Naming_Multi_Lang -- -- Check_Naming_Multi_Lang --
----------------------------- -----------------------------
procedure Check_Naming_Multi_Lang is procedure Check_Naming_Multi_Lang is
Dot_Replacement : File_Name_Type := No_File; Dot_Replacement : File_Name_Type :=
File_Name_Type (First_Name_Id + Character'Pos ('-'));
Separate_Suffix : File_Name_Type := No_File; Separate_Suffix : File_Name_Type := No_File;
Casing : Casing_Type := All_Lower_Case; Casing : Casing_Type := All_Lower_Case;
Casing_Defined : Boolean; Casing_Defined : Boolean;
...@@ -3269,11 +3146,6 @@ package body Prj.Nmsc is ...@@ -3269,11 +3146,6 @@ package body Prj.Nmsc is
if Casing_Defined then if Casing_Defined then
Lang_Id.Config.Naming_Data.Casing := Casing; Lang_Id.Config.Naming_Data.Casing := Casing;
end if; end if;
if Separate_Suffix /= No_File then
Lang_Id.Config.Naming_Data.Separate_Suffix :=
Separate_Suffix;
end if;
end if; end if;
Lang_Id := Lang_Id.Next; Lang_Id := Lang_Id.Next;
...@@ -3297,7 +3169,7 @@ package body Prj.Nmsc is ...@@ -3297,7 +3169,7 @@ package body Prj.Nmsc is
if Suffix = Nil_Variable_Value then if Suffix = Nil_Variable_Value then
Suffix := Value_Of Suffix := Value_Of
(Name => Lang, (Name => Lang,
Attribute_Or_Array_Name => Name_Spec_Suffix, Attribute_Or_Array_Name => Name_Specification_Suffix,
In_Package => Naming_Id, In_Package => Naming_Id,
In_Tree => In_Tree); In_Tree => In_Tree);
end if; end if;
...@@ -3305,6 +3177,16 @@ package body Prj.Nmsc is ...@@ -3305,6 +3177,16 @@ package body Prj.Nmsc is
if Suffix /= Nil_Variable_Value then if Suffix /= Nil_Variable_Value then
Lang_Id.Config.Naming_Data.Spec_Suffix := Lang_Id.Config.Naming_Data.Spec_Suffix :=
File_Name_Type (Suffix.Value); File_Name_Type (Suffix.Value);
Check_Illegal_Suffix
(Project, In_Tree,
Lang_Id.Config.Naming_Data.Spec_Suffix,
Lang_Id.Config.Naming_Data.Dot_Replacement,
"Spec_Suffix", Suffix.Location);
Write_Attr
("Spec_Suffix",
Get_Name_String (Lang_Id.Config.Naming_Data.Spec_Suffix));
end if; end if;
-- Body_Suffix -- Body_Suffix
...@@ -3325,14 +3207,68 @@ package body Prj.Nmsc is ...@@ -3325,14 +3207,68 @@ package body Prj.Nmsc is
if Suffix /= Nil_Variable_Value then if Suffix /= Nil_Variable_Value then
Lang_Id.Config.Naming_Data.Body_Suffix := Lang_Id.Config.Naming_Data.Body_Suffix :=
File_Name_Type (Suffix.Value); File_Name_Type (Suffix.Value);
-- The default value of separate suffix should be the same as
-- the body suffix, so we need to compute that first.
if Separate_Suffix = No_File then
Lang_Id.Config.Naming_Data.Separate_Suffix :=
Lang_Id.Config.Naming_Data.Body_Suffix;
Write_Attr
("Sep_Suffix",
Get_Name_String
(Lang_Id.Config.Naming_Data.Separate_Suffix));
else
Lang_Id.Config.Naming_Data.Separate_Suffix :=
Separate_Suffix;
end if;
Check_Illegal_Suffix
(Project, In_Tree,
Lang_Id.Config.Naming_Data.Body_Suffix,
Lang_Id.Config.Naming_Data.Dot_Replacement,
"Body_Suffix", Suffix.Location);
Write_Attr
("Body_Suffix",
Get_Name_String (Lang_Id.Config.Naming_Data.Body_Suffix));
elsif Separate_Suffix /= No_File then
Lang_Id.Config.Naming_Data.Separate_Suffix := Separate_Suffix;
end if;
-- Spec_Suffix cannot be equal to Body_Suffix or Separate_Suffix,
-- since that would cause a clear ambiguity. Note that we do allow
-- a Spec_Suffix to have the same termination as one of these,
-- which causes a potential ambiguity, but we resolve that my
-- matching the longest possible suffix.
if Lang_Id.Config.Naming_Data.Spec_Suffix /= No_File
and then Lang_Id.Config.Naming_Data.Spec_Suffix =
Lang_Id.Config.Naming_Data.Body_Suffix
then
Error_Msg
(Project, In_Tree,
"Body_Suffix ("""
& Get_Name_String (Lang_Id.Config.Naming_Data.Body_Suffix)
& """) cannot be the same as Spec_Suffix.",
Ada_Body_Suffix_Loc);
end if; end if;
-- ??? As opposed to what is done in Check_Naming_Ada_Only, if Lang_Id.Config.Naming_Data.Body_Suffix /=
-- we do not check whether spec_suffix=body_suffix, which Lang_Id.Config.Naming_Data.Separate_Suffix
-- should be illegal. Best would be to share this code into and then Lang_Id.Config.Naming_Data.Spec_Suffix =
-- Check_Common, but we access the attributes from the project Lang_Id.Config.Naming_Data.Separate_Suffix
-- files slightly differently apparently. then
Error_Msg
(Project, In_Tree,
"Separate_Suffix ("""
& Get_Name_String
(Lang_Id.Config.Naming_Data.Separate_Suffix)
& """) cannot be the same as Spec_Suffix.",
Sep_Suffix_Loc);
end if;
Lang_Id := Lang_Id.Next; Lang_Id := Lang_Id.Next;
end loop; end loop;
...@@ -3421,10 +3357,6 @@ package body Prj.Nmsc is ...@@ -3421,10 +3357,6 @@ package body Prj.Nmsc is
else else
Value := In_Tree.Array_Elements.Table (Specs).Value; Value := In_Tree.Array_Elements.Table (Specs).Value;
if Lang.Name = Name_Ada then
Ada_Spec_Suffix_Loc := Value.Location;
end if;
if Value.Kind = Single then if Value.Kind = Single then
Lang.Config.Naming_Data.Spec_Suffix := Lang.Config.Naming_Data.Spec_Suffix :=
Canonical_Case_File_Name (Value.Value); Canonical_Case_File_Name (Value.Value);
...@@ -3480,13 +3412,7 @@ package body Prj.Nmsc is ...@@ -3480,13 +3412,7 @@ package body Prj.Nmsc is
end if; end if;
Initialize_Naming_Data; Initialize_Naming_Data;
Check_Naming_Multi_Lang;
case Get_Mode is
when Ada_Only =>
Check_Naming_Ada_Only;
when Multi_Language =>
Check_Naming_Multi_Lang;
end case;
end if; end if;
end Check_Package_Naming; end Check_Package_Naming;
...@@ -4981,7 +4907,6 @@ package body Prj.Nmsc is ...@@ -4981,7 +4907,6 @@ package body Prj.Nmsc is
Name_Len := 0; Name_Len := 0;
Add_Str_To_Name_Buffer Add_Str_To_Name_Buffer
(Get_Name_String (Project.Directory.Name)); (Get_Name_String (Project.Directory.Name));
Add_Char_To_Name_Buffer (Directory_Separator);
Add_Str_To_Name_Buffer Add_Str_To_Name_Buffer
(Get_Name_String (Lib_Ref_Symbol_File.Value)); (Get_Name_String (Lib_Ref_Symbol_File.Value));
Project.Symbol_Data.Reference := Name_Find; Project.Symbol_Data.Reference := Name_Find;
...@@ -5030,7 +4955,6 @@ package body Prj.Nmsc is ...@@ -5030,7 +4955,6 @@ package body Prj.Nmsc is
Normalize_Pathname Normalize_Pathname
(Get_Name_String (Get_Name_String
(Project.Object_Directory.Name) & (Project.Object_Directory.Name) &
Directory_Separator &
Name_Buffer (1 .. Name_Len), Name_Buffer (1 .. Name_Len),
Directory => Current_Dir, Directory => Current_Dir,
Resolve_Links => Resolve_Links =>
...@@ -5584,15 +5508,13 @@ package body Prj.Nmsc is ...@@ -5584,15 +5508,13 @@ package body Prj.Nmsc is
else else
declare declare
Path : constant String := Path : constant String :=
Get_Name_String (Path_Name.Name) & Get_Name_String (Path_Name.Name);
Directory_Separator;
Last_Path : constant Natural := Last_Path : constant Natural :=
Compute_Directory_Last (Path); Compute_Directory_Last (Path);
Path_Id : Name_Id; Path_Id : Name_Id;
Display_Path : constant String := Display_Path : constant String :=
Get_Name_String Get_Name_String
(Path_Name.Display_Name) & (Path_Name.Display_Name);
Directory_Separator;
Last_Display_Path : constant Natural := Last_Display_Path : constant Natural :=
Compute_Directory_Last Compute_Directory_Last
(Display_Path); (Display_Path);
...@@ -6006,10 +5928,6 @@ package body Prj.Nmsc is ...@@ -6006,10 +5928,6 @@ package body Prj.Nmsc is
Name_Loc : Name_Location; Name_Loc : Name_Location;
begin begin
if Get_Mode = Ada_Only then
Source_Names.Reset;
end if;
if Current_Verbosity = High then if Current_Verbosity = High then
Write_Str ("Opening """); Write_Str ("Opening """);
Write_Str (Path); Write_Str (Path);
...@@ -6139,7 +6057,7 @@ package body Prj.Nmsc is ...@@ -6139,7 +6057,7 @@ package body Prj.Nmsc is
if Last = Filename'Last then if Last = Filename'Last then
if Current_Verbosity = High then if Current_Verbosity = High then
Write_Line (" No matching suffix"); Write_Line (" no matching suffix");
end if; end if;
return; return;
...@@ -6306,67 +6224,6 @@ package body Prj.Nmsc is ...@@ -6306,67 +6224,6 @@ package body Prj.Nmsc is
end if; end if;
end Compute_Unit_Name; end Compute_Unit_Name;
--------------
-- Get_Unit --
--------------
procedure Get_Unit
(In_Tree : Project_Tree_Ref;
Canonical_File_Name : File_Name_Type;
Project : Project_Id;
Exception_Id : out Ada_Naming_Exception_Id;
Unit_Name : out Name_Id;
Unit_Kind : out Spec_Or_Body)
is
Info_Id : Ada_Naming_Exception_Id :=
Ada_Naming_Exceptions.Get (Canonical_File_Name);
VMS_Name : File_Name_Type;
Kind : Source_Kind;
Lang : Language_Ptr;
begin
if Info_Id = No_Ada_Naming_Exception
and then 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;
if Info_Id /= No_Ada_Naming_Exception then
Exception_Id := Info_Id;
Unit_Name := No_Name;
Unit_Kind := Spec;
else
Exception_Id := No_Ada_Naming_Exception;
Lang := Get_Language_From_Name (Project, "ada");
if Lang = null then
Unit_Name := No_Name;
Unit_Kind := Spec;
else
Compute_Unit_Name
(File_Name => Canonical_File_Name,
Naming => Lang.Config.Naming_Data,
Kind => Kind,
Unit => Unit_Name,
In_Tree => In_Tree);
case Kind is
when Spec => Unit_Kind := Spec;
when Impl | Sep => Unit_Kind := Impl;
end case;
end if;
end if;
end Get_Unit;
---------- ----------
-- Hash -- -- Hash --
---------- ----------
...@@ -6376,44 +6233,62 @@ package body Prj.Nmsc is ...@@ -6376,44 +6233,62 @@ package body Prj.Nmsc is
return Header_Num (Unit.Unit mod 2048); return Header_Num (Unit.Unit mod 2048);
end Hash; end Hash;
----------------------- --------------------------
-- Is_Illegal_Suffix -- -- Check_Illegal_Suffix --
----------------------- --------------------------
function Is_Illegal_Suffix procedure Check_Illegal_Suffix
(Suffix : File_Name_Type; (Project : Project_Id;
Dot_Replacement : File_Name_Type) return Boolean In_Tree : Project_Tree_Ref;
Suffix : File_Name_Type;
Dot_Replacement : File_Name_Type;
Attribute_Name : String;
Location : Source_Ptr)
is is
Suffix_Str : constant String := Get_Name_String (Suffix); Suffix_Str : constant String := Get_Name_String (Suffix);
begin begin
if Suffix_Str'Length = 0 then if Suffix_Str'Length = 0 then
return False; -- Always valid
return;
elsif Index (Suffix_Str, ".") = 0 then elsif Index (Suffix_Str, ".") = 0 then
return True; Err_Vars.Error_Msg_File_1 := Suffix;
Error_Msg
(Project, In_Tree,
"{ is illegal for " & Attribute_Name & ": must have a dot",
Location);
return;
end if; end if;
-- Case of dot replacement is a single dot, and first character of -- Case of dot replacement is a single dot, and first character of
-- suffix is also a dot. -- suffix is also a dot.
if Get_Name_String (Dot_Replacement) = "." if Dot_Replacement /= No_File
and then Get_Name_String (Dot_Replacement) = "."
and then Suffix_Str (Suffix_Str'First) = '.' and then Suffix_Str (Suffix_Str'First) = '.'
then then
for Index in Suffix_Str'First + 1 .. Suffix_Str'Last loop for Index in Suffix_Str'First + 1 .. Suffix_Str'Last loop
-- Case of following dot -- If there are multiple dots in the name
if Suffix_Str (Index) = '.' then if Suffix_Str (Index) = '.' then
-- It is illegal to have a letter following the initial dot -- It is illegal to have a letter following the initial dot
return Is_Letter (Suffix_Str (Suffix_Str'First + 1)); if Is_Letter (Suffix_Str (Suffix_Str'First + 1)) then
Err_Vars.Error_Msg_File_1 := Suffix;
Error_Msg
(Project, In_Tree,
"{ is illegal for " & Attribute_Name
& ": ambiguous prefix when Dot_Replacement is a dot",
Location);
end if;
return;
end if; end if;
end loop; end loop;
end if; end if;
end Check_Illegal_Suffix;
return False;
end Is_Illegal_Suffix;
---------------------- ----------------------
-- Locate_Directory -- -- Locate_Directory --
...@@ -6433,7 +6308,7 @@ package body Prj.Nmsc is ...@@ -6433,7 +6308,7 @@ package body Prj.Nmsc is
Parent : constant Path_Name_Type := Parent : constant Path_Name_Type :=
Project.Directory.Display_Name; Project.Directory.Display_Name;
The_Parent : constant String := The_Parent : constant String :=
Get_Name_String (Parent) & Directory_Separator; Get_Name_String (Parent);
The_Parent_Last : constant Natural := The_Parent_Last : constant Natural :=
Compute_Directory_Last (The_Parent); Compute_Directory_Last (The_Parent);
Full_Name : File_Name_Type; Full_Name : File_Name_Type;
...@@ -6560,10 +6435,22 @@ package body Prj.Nmsc is ...@@ -6560,10 +6435,22 @@ package body Prj.Nmsc is
begin begin
Name_Len := Normed'Length; Name_Len := Normed'Length;
Name_Buffer (1 .. Name_Len) := Normed; Name_Buffer (1 .. Name_Len) := Normed;
-- Directories should always end with a directory separator
if Name_Buffer (Name_Len) /= Directory_Separator then
Add_Char_To_Name_Buffer (Directory_Separator);
end if;
Path.Display_Name := Name_Find; Path.Display_Name := Name_Find;
Name_Len := Canonical_Path'Length; Name_Len := Canonical_Path'Length;
Name_Buffer (1 .. Name_Len) := Canonical_Path; Name_Buffer (1 .. Name_Len) := Canonical_Path;
if Name_Buffer (Name_Len) /= Directory_Separator then
Add_Char_To_Name_Buffer (Directory_Separator);
end if;
Path.Name := Name_Find; Path.Name := Name_Find;
end; end;
end if; end if;
...@@ -6730,7 +6617,7 @@ package body Prj.Nmsc is ...@@ -6730,7 +6617,7 @@ package body Prj.Nmsc is
procedure Find_Sources procedure Find_Sources
(Project : Project_Id; (Project : Project_Id;
In_Tree : Project_Tree_Ref; In_Tree : Project_Tree_Ref;
Proc_Data : in out Processing_Data; File_To_Source : in out Files_Htable.Instance;
Allow_Duplicate_Basenames : Boolean; Allow_Duplicate_Basenames : Boolean;
Excluded : in out Excluded_Sources_Htable.Instance) Excluded : in out Excluded_Sources_Htable.Instance)
is is
...@@ -6775,7 +6662,7 @@ package body Prj.Nmsc is ...@@ -6775,7 +6662,7 @@ package body Prj.Nmsc is
Name : File_Name_Type; Name : File_Name_Type;
begin begin
if Get_Mode = Multi_Language then -- if Get_Mode = Multi_Language then
if Current = Nil_String then if Current = Nil_String then
Project.Languages := No_Language_Index; Project.Languages := No_Language_Index;
...@@ -6789,7 +6676,7 @@ package body Prj.Nmsc is ...@@ -6789,7 +6676,7 @@ package body Prj.Nmsc is
Project.Object_Directory := No_Path_Information; Project.Object_Directory := No_Path_Information;
end if; end if;
end if; end if;
end if; -- end if;
while Current /= Nil_String loop while Current /= Nil_String loop
Element := In_Tree.String_Elements.Table (Current); Element := In_Tree.String_Elements.Table (Current);
...@@ -6822,17 +6709,11 @@ package body Prj.Nmsc is ...@@ -6822,17 +6709,11 @@ package body Prj.Nmsc is
end if; end if;
end loop; end loop;
-- In Multi_Language mode, check whether the file is already -- Check whether the file is already there: the same file name
-- there: the same file name may be in the list. If the source -- may be in the list. If the source is missing, the error will
-- is missing, the error will be on the first mention of the -- be on the first mention of the source file name.
-- source file name.
case Get_Mode is Name_Loc := Source_Names.Get (Name);
when Ada_Only =>
Name_Loc := No_Name_Location;
when Multi_Language =>
Name_Loc := Source_Names.Get (Name);
end case;
if Name_Loc = No_Name_Location then if Name_Loc = No_Name_Location then
Name_Loc := Name_Loc :=
...@@ -6890,20 +6771,12 @@ package body Prj.Nmsc is ...@@ -6890,20 +6771,12 @@ package body Prj.Nmsc is
Has_Explicit_Sources := False; Has_Explicit_Sources := False;
end if; end if;
if Get_Mode = Ada_Only then Search_Directories
Find_Ada_Sources (Project, In_Tree,
(Project, In_Tree, File_To_Source => File_To_Source,
Explicit_Sources_Only => Has_Explicit_Sources, For_All_Sources => Sources.Default and then Source_List_File.Default,
Proc_Data => Proc_Data); Allow_Duplicate_Basenames => Allow_Duplicate_Basenames,
Excluded => Excluded);
else
Search_Directories
(Project, In_Tree,
For_All_Sources =>
Sources.Default and then Source_List_File.Default,
Allow_Duplicate_Basenames => Allow_Duplicate_Basenames,
Excluded => Excluded);
end if;
-- Check if all exceptions have been found. For Ada, it is an error if -- Check if all exceptions have been found. For Ada, it is an error if
-- an exception is not found. For other language, the source is simply -- an exception is not found. For other language, the source is simply
...@@ -6937,10 +6810,29 @@ package body Prj.Nmsc is ...@@ -6937,10 +6810,29 @@ package body Prj.Nmsc is
(Project, In_Tree, (Project, In_Tree,
"source file %% for unit %% not found", "source file %% for unit %% not found",
No_Location); No_Location);
else
-- Set the full path information since we know it
-- anyway
Source.Path := Files_Htable.Get
(File_To_Source, Source.File).Path;
if Current_Verbosity = High then
if Source.Path /= No_Path_Information then
Write_Line ("Setting full path for "
& Get_Name_String (Source.File)
& " at" & Source.Index'Img
& " to "
& Get_Name_String (Source.Path.Name));
end if;
end if;
end if; end if;
end if; end if;
Remove_Source (Source, No_Source); if Source.Path = No_Path_Information then
Remove_Source (Source, No_Source);
end if;
end if; end if;
Next (Iter); Next (Iter);
...@@ -7012,154 +6904,6 @@ package body Prj.Nmsc is ...@@ -7012,154 +6904,6 @@ package body Prj.Nmsc is
Files_Htable.Reset (Proc_Data.Units); Files_Htable.Reset (Proc_Data.Units);
end Free; end Free;
----------------------
-- Find_Ada_Sources --
----------------------
procedure Find_Ada_Sources
(Project : Project_Id;
In_Tree : Project_Tree_Ref;
Explicit_Sources_Only : Boolean;
Proc_Data : in out Processing_Data)
is
Source_Dir : String_List_Id;
Element : String_Element;
Dir : Dir_Type;
Dir_Has_Source : Boolean := False;
NL : Name_Location;
Ada_Language : Language_Ptr;
begin
if Current_Verbosity = High then
Write_Line ("Looking for Ada sources:");
end if;
Ada_Language := Project.Languages;
while Ada_Language /= No_Language_Index
and then Ada_Language.Name /= Name_Ada
loop
Ada_Language := Ada_Language.Next;
end loop;
-- We look in all source directories for the file names in the hash
-- table Source_Names.
Source_Dir := Project.Source_Dirs;
while Source_Dir /= Nil_String loop
Dir_Has_Source := False;
Element := In_Tree.String_Elements.Table (Source_Dir);
declare
Dir_Path : constant String :=
Get_Name_String (Element.Display_Value) &
Directory_Separator;
Dir_Last : constant Natural := Compute_Directory_Last (Dir_Path);
begin
if Current_Verbosity = High then
Write_Line ("checking directory """ & Dir_Path & """");
end if;
-- Look for all files in the current source directory
Open (Dir, Dir_Path (Dir_Path'First .. Dir_Last));
loop
Read (Dir, Name_Buffer, Name_Len);
exit when Name_Len = 0;
if Current_Verbosity = High then
Write_Line (" Checking " & Name_Buffer (1 .. Name_Len));
end if;
declare
Name : constant File_Name_Type := Name_Find;
Canonical_Name : File_Name_Type;
-- ??? We could probably optimize the following call: we
-- need to resolve links only once for the directory itself,
-- and then do a single call to readlink() for each file.
-- Unfortunately that would require Normalize_Pathname to
-- be changed so that it has the option of not resolving
-- links for its Directory parameter, only for Name.
Path : constant String :=
Normalize_Pathname
(Name => Name_Buffer (1 .. Name_Len),
Directory => Dir_Path (Dir_Path'First .. Dir_Last),
Resolve_Links => Opt.Follow_Links_For_Files,
Case_Sensitive => True); -- no case folding
Path_Name : Path_Name_Type;
To_Record : Boolean := False;
Location : Source_Ptr;
begin
-- If the file was listed in the explicit list of sources,
-- mark it as such (since we'll need to report an error when
-- an explicit source was not found)
if Explicit_Sources_Only then
Canonical_Name :=
Canonical_Case_File_Name (Name_Id (Name));
NL := Source_Names.Get (Canonical_Name);
To_Record := NL /= No_Name_Location and then not NL.Found;
if To_Record then
NL.Found := True;
Location := NL.Location;
Source_Names.Set (Canonical_Name, NL);
end if;
else
To_Record := True;
Location := No_Location;
end if;
if To_Record then
Name_Len := Path'Length;
Name_Buffer (1 .. Name_Len) := Path;
Path_Name := Name_Find;
if Current_Verbosity = High then
Write_Line (" recording " & 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_Name,
Project => Project,
In_Tree => In_Tree,
Proc_Data => Proc_Data,
Ada_Language => Ada_Language,
Location => Location,
Source_Recorded => Dir_Has_Source);
end if;
end;
end loop;
Close (Dir);
exception
when others =>
Close (Dir);
raise;
end;
if Dir_Has_Source 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;
end Find_Ada_Sources;
------------------------------- -------------------------------
-- Check_File_Naming_Schemes -- -- Check_File_Naming_Schemes --
------------------------------- -------------------------------
...@@ -7328,9 +7072,11 @@ package body Prj.Nmsc is ...@@ -7328,9 +7072,11 @@ package body Prj.Nmsc is
procedure Check_File procedure Check_File
(Project : Project_Id; (Project : Project_Id;
In_Tree : Project_Tree_Ref; In_Tree : Project_Tree_Ref;
File_To_Source : in out Files_Htable.Instance;
Path : Path_Name_Type; Path : Path_Name_Type;
File_Name : File_Name_Type; File_Name : File_Name_Type;
Display_File_Name : File_Name_Type; Display_File_Name : File_Name_Type;
Locally_Removed : Boolean;
For_All_Sources : Boolean; For_All_Sources : Boolean;
Allow_Duplicate_Basenames : Boolean) Allow_Duplicate_Basenames : Boolean)
is is
...@@ -7343,14 +7089,11 @@ package body Prj.Nmsc is ...@@ -7343,14 +7089,11 @@ package body Prj.Nmsc is
Alternate_Languages : Language_List; Alternate_Languages : Language_List;
Language : Language_Ptr; Language : Language_Ptr;
Source : Source_Id; Source : Source_Id;
Add_Src : Boolean;
Src_Ind : Source_File_Index; Src_Ind : Source_File_Index;
Unit : Name_Id; Unit : Name_Id;
Source_To_Replace : Source_Id := No_Source;
Display_Language_Name : Name_Id; Display_Language_Name : Name_Id;
Lang_Kind : Language_Kind; Lang_Kind : Language_Kind;
Kind : Source_Kind := Spec; Kind : Source_Kind := Spec;
Iter : Source_Iterator;
begin begin
if Name_Loc = No_Name_Location then if Name_Loc = No_Name_Location then
...@@ -7403,6 +7146,8 @@ package body Prj.Nmsc is ...@@ -7403,6 +7146,8 @@ package body Prj.Nmsc is
Override_Kind (Name_Loc.Source, Sep); Override_Kind (Name_Loc.Source, Sep);
end if; end if;
end if; end if;
Files_Htable.Set (File_To_Source, File_Name, Name_Loc.Source);
end if; end if;
end if; end if;
end if; end if;
...@@ -7423,126 +7168,34 @@ package body Prj.Nmsc is ...@@ -7423,126 +7168,34 @@ package body Prj.Nmsc is
-- A file name in a list must be a source of a language -- A file name in a list must be a source of a language
if Name_Loc.Found then if Get_Mode = Multi_Language then
Error_Msg_File_1 := File_Name; if Name_Loc.Found then
Error_Msg Error_Msg_File_1 := File_Name;
(Project, Error_Msg
In_Tree, (Project,
"language unknown for {", In_Tree,
Name_Loc.Location); "language unknown for {",
Name_Loc.Location);
end if;
end if; end if;
else else
-- Check if the same file name or unit is used in the prj tree Add_Source
(Id => Source,
Iter := For_Each_Source (In_Tree); In_Tree => In_Tree,
Add_Src := True; File_To_Source => File_To_Source,
loop Project => Project,
Source := Prj.Element (Iter); Lang_Id => Language,
exit when Source = No_Source; Kind => Kind,
Allow_Duplicate_Basenames => Allow_Duplicate_Basenames,
if Unit /= No_Name Alternate_Languages => Alternate_Languages,
and then Source.Unit /= No_Unit_Index File_Name => File_Name,
and then Source.Unit.Name = Unit Display_File => Display_File_Name,
and then Unit => Unit,
((Source.Kind = Spec and then Kind = Impl) Path => (Canonical_Path, Path));
or else
(Source.Kind = Impl and then Kind = Spec)) if Source /= No_Source then
then Source.Locally_Removed := Locally_Removed;
-- We found the "other_part (source)"
null;
elsif (Unit /= No_Name
and then Source.Unit /= No_Unit_Index
and then Source.Unit.Name = Unit
and then
(Source.Kind = Kind
or else
(Source.Kind = Sep and then Kind = Impl)
or else
(Source.Kind = Impl and then Kind = Sep)))
or else
(Unit = No_Name and then Source.File = File_Name)
then
-- Duplication of file/unit in same project is only allowed
-- if order of source directories is known.
if Project = Source.Project then
if Unit = No_Name then
if Allow_Duplicate_Basenames then
Add_Src := True;
elsif Project.Known_Order_Of_Source_Dirs then
Add_Src := False;
else
Error_Msg_File_1 := File_Name;
Error_Msg
(Project, In_Tree, "duplicate source file name {",
No_Location);
Add_Src := False;
end if;
else
if Project.Known_Order_Of_Source_Dirs then
Add_Src := False;
else
Error_Msg_Name_1 := Unit;
Error_Msg
(Project, In_Tree, "duplicate unit %%",
No_Location);
Add_Src := False;
end if;
end if;
-- Do not allow the same unit name in different projects,
-- except if one is extending the other.
-- For a file based language, the same file name replaces
-- a file in a project being extended, but it is allowed
-- to have the same file name in unrelated projects.
elsif Is_Extending (Project, Source.Project) then
Source_To_Replace := Source;
elsif Unit /= No_Name
and then not Source.Locally_Removed
then
Error_Msg_Name_1 := Unit;
Error_Msg
(Project, In_Tree,
"unit %% cannot belong to several projects",
No_Location);
Error_Msg_Name_1 := Project.Name;
Error_Msg_Name_2 := Name_Id (Path);
Error_Msg
(Project, In_Tree, "\ project %%, %%", No_Location);
Error_Msg_Name_1 := Source.Project.Name;
Error_Msg_Name_2 := Name_Id (Source.Path.Display_Name);
Error_Msg
(Project, In_Tree, "\ project %%, %%", No_Location);
Add_Src := False;
end if;
end if;
Next (Iter);
end loop;
if Add_Src then
Add_Source
(Id => Source,
In_Tree => In_Tree,
Project => Project,
Lang_Id => Language,
Kind => Kind,
Alternate_Languages => Alternate_Languages,
File_Name => File_Name,
Display_File => Display_File_Name,
Unit => Unit,
Path => (Canonical_Path, Path),
Source_To_Replace => Source_To_Replace);
end if; end if;
end if; end if;
end if; end if;
...@@ -7555,6 +7208,7 @@ package body Prj.Nmsc is ...@@ -7555,6 +7208,7 @@ package body Prj.Nmsc is
procedure Search_Directories procedure Search_Directories
(Project : Project_Id; (Project : Project_Id;
In_Tree : Project_Tree_Ref; In_Tree : Project_Tree_Ref;
File_To_Source : in out Files_Htable.Instance;
For_All_Sources : Boolean; For_All_Sources : Boolean;
Allow_Duplicate_Basenames : Boolean; Allow_Duplicate_Basenames : Boolean;
Excluded : in out Excluded_Sources_Htable.Instance) Excluded : in out Excluded_Sources_Htable.Instance)
...@@ -7644,6 +7298,7 @@ package body Prj.Nmsc is ...@@ -7644,6 +7298,7 @@ package body Prj.Nmsc is
Path : Path_Name_Type; Path : Path_Name_Type;
FF : File_Found := Excluded_Sources_Htable.Get FF : File_Found := Excluded_Sources_Htable.Get
(Excluded, File_Name); (Excluded, File_Name);
To_Remove : Boolean := False;
begin begin
Name_Len := Path_Name'Length; Name_Len := Path_Name'Length;
...@@ -7661,20 +7316,29 @@ package body Prj.Nmsc is ...@@ -7661,20 +7316,29 @@ package body Prj.Nmsc is
Write_Str (Get_Name_String (File_Name)); Write_Str (Get_Name_String (File_Name));
Write_Line (""""); Write_Line ("""");
end if; end if;
end if;
else -- Will mark the file as removed, but we
Check_File -- still need to add it to the list: if we
(Project => Project, -- don't, the file will not appear in the
In_Tree => In_Tree, -- mapping file and will cause the compiler
Path => Path, -- to fail
File_Name => File_Name,
Display_File_Name => To_Remove := True;
Display_File_Name, end if;
For_All_Sources => For_All_Sources,
Allow_Duplicate_Basenames =>
Allow_Duplicate_Basenames);
end if; end if;
Check_File
(Project => Project,
In_Tree => In_Tree,
File_To_Source => File_To_Source,
Path => Path,
File_Name => File_Name,
Locally_Removed => To_Remove,
Display_File_Name =>
Display_File_Name,
For_All_Sources => For_All_Sources,
Allow_Duplicate_Basenames =>
Allow_Duplicate_Basenames);
end; end;
end if; end if;
end loop; end loop;
...@@ -7881,7 +7545,6 @@ package body Prj.Nmsc is ...@@ -7881,7 +7545,6 @@ package body Prj.Nmsc is
Check_Object_File_Names : declare Check_Object_File_Names : declare
Src_Id : Source_Id; Src_Id : Source_Id;
Source_Name : File_Name_Type;
procedure Check_Object (Src : Source_Id); procedure Check_Object (Src : Source_Id);
-- Check if object file name of the current source is already in -- Check if object file name of the current source is already in
...@@ -7893,12 +7556,15 @@ package body Prj.Nmsc is ...@@ -7893,12 +7556,15 @@ package body Prj.Nmsc is
------------------ ------------------
procedure Check_Object (Src : Source_Id) is procedure Check_Object (Src : Source_Id) is
Source : Source_Id;
begin begin
Source_Name := Object_File_Names.Get (Src.Object); Source := Object_File_Names.Get (Src.Object);
if Source_Name /= No_File then if Source /= No_Source
and then Source = Src
then
Error_Msg_File_1 := Src.File; Error_Msg_File_1 := Src.File;
Error_Msg_File_2 := Source_Name; Error_Msg_File_2 := Source.File;
Error_Msg Error_Msg
(Project, (Project,
In_Tree, In_Tree,
...@@ -7906,7 +7572,7 @@ package body Prj.Nmsc is ...@@ -7906,7 +7572,7 @@ package body Prj.Nmsc is
No_Location); No_Location);
else else
Object_File_Names.Set (Src.Object, Src.File); Object_File_Names.Set (Src.Object, Src);
end if; end if;
end Check_Object; end Check_Object;
...@@ -7979,18 +7645,14 @@ package body Prj.Nmsc is ...@@ -7979,18 +7645,14 @@ package body Prj.Nmsc is
or else (Get_Mode = Multi_Language or else (Get_Mode = Multi_Language
and then Project.Languages /= No_Language_Index) and then Project.Languages /= No_Language_Index)
then then
if Get_Mode = Multi_Language then Load_Naming_Exceptions (Project, In_Tree, Excluded_Sources);
Load_Naming_Exceptions (Project, In_Tree, Excluded_Sources);
end if;
Find_Sources Find_Sources
(Project, In_Tree, Proc_Data, Allow_Duplicate_Basenames, (Project, In_Tree, Proc_Data.Units, Allow_Duplicate_Basenames,
Excluded => Excluded_Sources); Excluded => Excluded_Sources);
Mark_Excluded_Sources; Mark_Excluded_Sources;
if Get_Mode = Multi_Language then Process_Sources_In_Multi_Language_Mode;
Process_Sources_In_Multi_Language_Mode;
end if;
end if; end if;
end Look_For_Sources; end Look_For_Sources;
...@@ -8025,280 +7687,6 @@ package body Prj.Nmsc is ...@@ -8025,280 +7687,6 @@ package body Prj.Nmsc is
end if; end if;
end Path_Name_Of; 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;
Element : Array_Element;
Unit : Unit_Info;
begin
-- Traverse the list
Current := 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 (File_Name_Type (Element.Value.Value));
Ada_Naming_Exception_Table.Increment_Last;
Ada_Naming_Exception_Table.Table
(Ada_Naming_Exception_Table.Last) := Unit;
Ada_Naming_Exceptions.Set
(File_Name_Type (Element.Value.Value),
Ada_Naming_Exception_Table.Last);
end if;
Current := Element.Next;
end loop;
end Prepare_Ada_Naming_Exceptions;
-----------------------
-- Record_Ada_Source --
-----------------------
procedure Record_Ada_Source
(File_Name : File_Name_Type;
Path_Name : Path_Name_Type;
Project : Project_Id;
In_Tree : Project_Tree_Ref;
Proc_Data : in out Processing_Data;
Ada_Language : Language_Ptr;
Location : Source_Ptr;
Source_Recorded : in out Boolean)
is
Canonical_File : File_Name_Type;
Canonical_Path : Path_Name_Type;
File_Recorded : Boolean := False;
-- True when at least one file has been recorded
procedure Record_Unit
(Unit_Name : Name_Id;
Unit_Ind : Int := 0;
Unit_Kind : Spec_Or_Body;
Needs_Pragma : Boolean);
-- Register of the units contained in the source file (there is in
-- general a single such unit except when exceptions to the naming
-- scheme indicate there are several such units)
-----------------
-- Record_Unit --
-----------------
procedure Record_Unit
(Unit_Name : Name_Id;
Unit_Ind : Int := 0;
Unit_Kind : Spec_Or_Body;
Needs_Pragma : Boolean)
is
UData : constant Unit_Index :=
Units_Htable.Get (In_Tree.Units_HT, Unit_Name);
-- ??? Add_Source will look it up again, can we do that only once ?
Source : Source_Id;
To_Record : Boolean := False;
The_Location : Source_Ptr := Location;
Unit_Prj : Project_Id;
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 UData /= No_Unit_Index then
if UData.File_Names (Unit_Kind) = null
or else
(UData.File_Names (Unit_Kind).File = Canonical_File
and then UData.File_Names (Unit_Kind).Locally_Removed)
or else Is_Extending
(Project.Extends, UData.File_Names (Unit_Kind).Project)
then
To_Record := True;
-- If the same file is already in the list, do not add it again
elsif UData.File_Names (Unit_Kind).Project = Project
and then
(Project.Known_Order_Of_Source_Dirs
or else
UData.File_Names (Unit_Kind).Path.Name = Canonical_Path)
then
To_Record := False;
-- Else, same unit but not same file => It is an error to have two
-- units with the same name and the same kind (spec or body).
else
if The_Location = No_Location then
The_Location := Project.Location;
end if;
Err_Vars.Error_Msg_Name_1 := Unit_Name;
Error_Msg
(Project, In_Tree, "duplicate unit %%", The_Location);
Err_Vars.Error_Msg_Name_1 :=
UData.File_Names (Unit_Kind).Project.Name;
Err_Vars.Error_Msg_File_1 :=
File_Name_Type (UData.File_Names (Unit_Kind).Path.Name);
Error_Msg
(Project, In_Tree, "\ project file %%, {", The_Location);
Err_Vars.Error_Msg_Name_1 := Project.Name;
Err_Vars.Error_Msg_File_1 := File_Name_Type (Canonical_Path);
Error_Msg
(Project, In_Tree, "\ project file %%, {", The_Location);
To_Record := False;
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 error but note we do that
-- only for the first unit in the source file.
Unit_Prj := Files_Htable.Get (Proc_Data.Units, Canonical_File);
if not File_Recorded
and then Unit_Prj /= No_Project
then
Error_Msg_File_1 := File_Name;
Error_Msg_Name_1 := Unit_Prj.Name;
Error_Msg
(Project, In_Tree,
"{ is already a source of project %%",
Location);
else
To_Record := True;
end if;
end if;
if To_Record then
Files_Htable.Set (Proc_Data.Units, Canonical_File, Project);
Add_Source
(Id => Source,
In_Tree => In_Tree,
Project => Project,
Lang_Id => Ada_Language,
File_Name => Canonical_File,
Display_File => File_Name,
Unit => Unit_Name,
Path => (Canonical_Path, Path_Name),
Naming_Exception => Needs_Pragma,
Kind => Unit_Kind,
Index => Unit_Ind);
Source_Recorded := True;
end if;
end Record_Unit;
Exception_Id : Ada_Naming_Exception_Id;
Unit_Name : Name_Id;
Unit_Kind : Spec_Or_Body;
Unit_Ind : Int := 0;
Info : Unit_Info;
Name_Index : Name_And_Index;
Except_Name : Name_And_Index := No_Name_And_Index;
Needs_Pragma : Boolean;
begin
Canonical_File := Canonical_Case_File_Name (Name_Id (File_Name));
Canonical_Path :=
Path_Name_Type (Canonical_Case_File_Name (Name_Id (Path_Name)));
-- Check the naming scheme to get extra file properties
Get_Unit
(In_Tree => In_Tree,
Canonical_File_Name => Canonical_File,
Project => Project,
Exception_Id => Exception_Id,
Unit_Name => Unit_Name,
Unit_Kind => Unit_Kind);
Needs_Pragma := Exception_Id /= No_Ada_Naming_Exception;
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));
Write_Line (""" is not a valid source file name (ignored).");
end if;
return;
end if;
-- 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));
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 since it
-- is hidden by the exception. So, nothing else to do.
return;
end if;
end if;
-- The following loop registers the unit in the appropriate table. It
-- will be executed multiple times when the file is a multi-unit file,
-- in which case Exception_Id initially points to the first file and
-- then to each other unit in the file.
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_Ind := Name_Index.Index;
Unit_Kind := Info.Kind;
end if;
Record_Unit (Unit_Name, Unit_Ind, Unit_Kind, Needs_Pragma);
File_Recorded := True;
exit when Exception_Id = No_Ada_Naming_Exception;
end loop;
end Record_Ada_Source;
------------------- -------------------
-- Remove_Source -- -- Remove_Source --
------------------- -------------------
...@@ -8312,7 +7700,7 @@ package body Prj.Nmsc is ...@@ -8312,7 +7700,7 @@ package body Prj.Nmsc is
begin begin
if Current_Verbosity = High then if Current_Verbosity = High then
Write_Str ("Removing source "); Write_Str ("Removing source ");
Write_Line (Get_Name_String (Id.File)); Write_Line (Get_Name_String (Id.File) & " at" & Id.Index'Img);
end if; end if;
if Replaced_By /= No_Source then if Replaced_By /= No_Source then
......
...@@ -83,6 +83,6 @@ private package Prj.Nmsc is ...@@ -83,6 +83,6 @@ private package Prj.Nmsc is
private private
type Processing_Data is record type Processing_Data is record
Units : Files_Htable.Instance; Units : Files_Htable.Instance;
-- Mapping from file base name to the project containing the file -- Mapping from file base name to the Source_Id of the file
end record; end record;
end Prj.Nmsc; end Prj.Nmsc;
...@@ -27,9 +27,9 @@ with Ada.Exceptions; use Ada.Exceptions; ...@@ -27,9 +27,9 @@ with Ada.Exceptions; use Ada.Exceptions;
with GNAT.Directory_Operations; use GNAT.Directory_Operations; with GNAT.Directory_Operations; use GNAT.Directory_Operations;
with Output; use Output; with Output; use Output;
with Prj.Conf; use Prj.Conf;
with Prj.Err; use Prj.Err; with Prj.Err; use Prj.Err;
with Prj.Part; with Prj.Part;
with Prj.Proc;
with Prj.Tree; use Prj.Tree; with Prj.Tree; use Prj.Tree;
with Sinput.P; with Sinput.P;
...@@ -46,15 +46,15 @@ package body Prj.Pars is ...@@ -46,15 +46,15 @@ package body Prj.Pars is
Packages_To_Check : String_List_Access := All_Packages; Packages_To_Check : String_List_Access := All_Packages;
When_No_Sources : Error_Warning := Error; When_No_Sources : Error_Warning := Error;
Report_Error : Put_Line_Access := null; Report_Error : Put_Line_Access := null;
Reset_Tree : Boolean := True; Reset_Tree : Boolean := True)
Is_Config_File : Boolean := False)
is is
Project_Node : Project_Node_Id := Empty_Node; Project_Node : Project_Node_Id := Empty_Node;
The_Project : Project_Id := No_Project; The_Project : Project_Id := No_Project;
Success : Boolean := True; Success : Boolean := True;
Current_Dir : constant String := Get_Current_Dir; Current_Dir : constant String := Get_Current_Dir;
Project_Node_Tree : Prj.Tree.Project_Node_Tree_Ref; Project_Node_Tree : Prj.Tree.Project_Node_Tree_Ref;
Automatically_Generated : Boolean;
Config_File_Path : String_Access;
begin begin
Project_Node_Tree := new Project_Node_Tree_Data; Project_Node_Tree := new Project_Node_Tree_Data;
Prj.Tree.Initialize (Project_Node_Tree); Prj.Tree.Initialize (Project_Node_Tree);
...@@ -69,22 +69,42 @@ package body Prj.Pars is ...@@ -69,22 +69,42 @@ package body Prj.Pars is
Always_Errout_Finalize => False, Always_Errout_Finalize => False,
Packages_To_Check => Packages_To_Check, Packages_To_Check => Packages_To_Check,
Current_Directory => Current_Dir, Current_Directory => Current_Dir,
Is_Config_File => Is_Config_File); Is_Config_File => False);
-- If there were no error, process the tree -- If there were no error, process the tree
if Project_Node /= Empty_Node then if Project_Node /= Empty_Node then
Prj.Proc.Process begin
(In_Tree => In_Tree, -- No config file should be read from the disk for gnatmake.
Project => The_Project, -- However, we will simulate one that only contains the
Success => Success, -- default GNAT naming scheme.
From_Project_Node => Project_Node,
From_Project_Node_Tree => Project_Node_Tree, Process_Project_And_Apply_Config
Report_Error => Report_Error, (Main_Project => The_Project,
Reset_Tree => Reset_Tree, User_Project_Node => Project_Node,
When_No_Sources => When_No_Sources, Config_File_Name => "",
Current_Dir => Current_Dir, Autoconf_Specified => False,
Is_Config_File => Is_Config_File); Project_Tree => In_Tree,
Project_Node_Tree => Project_Node_Tree,
Packages_To_Check => null,
Allow_Automatic_Generation => False,
Automatically_Generated => Automatically_Generated,
Config_File_Path => Config_File_Path,
Report_Error => Report_Error,
Normalized_Hostname => "",
Compiler_Driver_Mandatory => False,
Allow_Duplicate_Basenames => False,
On_Load_Config =>
Add_Default_GNAT_Naming_Scheme'Access,
Reset_Tree => Reset_Tree,
When_No_Sources => When_No_Sources);
Success := The_Project /= No_Project;
exception
when Invalid_Config =>
Success := False;
end;
Prj.Err.Finalize; Prj.Err.Finalize;
......
...@@ -37,8 +37,7 @@ package Prj.Pars is ...@@ -37,8 +37,7 @@ package Prj.Pars is
Packages_To_Check : String_List_Access := All_Packages; Packages_To_Check : String_List_Access := All_Packages;
When_No_Sources : Error_Warning := Error; When_No_Sources : Error_Warning := Error;
Report_Error : Prj.Put_Line_Access := null; Report_Error : Prj.Put_Line_Access := null;
Reset_Tree : Boolean := True; Reset_Tree : Boolean := True);
Is_Config_File : Boolean := False);
-- Parse and process a project files and all its imported project files, in -- Parse and process a project files and all its imported project files, in
-- the project tree In_Tree. -- the project tree In_Tree.
-- All the project files are parsed (through Prj.Tree) to create a tree in -- All the project files are parsed (through Prj.Tree) to create a tree in
...@@ -62,8 +61,5 @@ package Prj.Pars is ...@@ -62,8 +61,5 @@ package Prj.Pars is
-- --
-- When Reset_Tree is True, all the project data are removed from the -- When Reset_Tree is True, all the project data are removed from the
-- project table before processing. -- project table before processing.
--
-- Is_Config_File should be set to True if the project represents a config
-- file (.cgpr) since some specific checks apply.
end Prj.Pars; end Prj.Pars;
...@@ -214,12 +214,6 @@ package body Prj.Part is ...@@ -214,12 +214,6 @@ package body Prj.Part is
-- Returns the path name of a project file. Returns an empty string -- Returns the path name of a project file. Returns an empty string
-- if project file cannot be found. -- if project file cannot be found.
function Immediate_Directory_Of
(Path_Name : Path_Name_Type) return Path_Name_Type;
-- Get the directory of the file with the specified path name.
-- This includes the directory separator as the last character.
-- Returns "./" if Path_Name contains no directory separator.
function Project_Name_From function Project_Name_From
(Path_Name : String; (Path_Name : String;
Is_Config_File : Boolean) return Name_Id; Is_Config_File : Boolean) return Name_Id;
...@@ -249,10 +243,6 @@ package body Prj.Part is ...@@ -249,10 +243,6 @@ package body Prj.Part is
-- Fake path name of the virtual extending project. The directory is -- Fake path name of the virtual extending project. The directory is
-- the same directory as the extending all project. -- the same directory as the extending all project.
Virtual_Dir_Id : constant Path_Name_Type :=
Immediate_Directory_Of (Path_Name_Of (Main_Project, In_Tree));
-- The directory of the extending all project
-- The source of the virtual extending project is something like: -- The source of the virtual extending project is something like:
-- project V$<project name> extends <project path> is -- project V$<project name> extends <project path> is
...@@ -266,15 +256,11 @@ package body Prj.Part is ...@@ -266,15 +256,11 @@ package body Prj.Part is
-- Nodes that made up the virtual extending project -- Nodes that made up the virtual extending project
Virtual_Project : constant Project_Node_Id := Virtual_Project : Project_Node_Id;
Default_Project_Node
(In_Tree, N_Project);
With_Clause : constant Project_Node_Id := With_Clause : constant Project_Node_Id :=
Default_Project_Node Default_Project_Node
(In_Tree, N_With_Clause); (In_Tree, N_With_Clause);
Project_Declaration : constant Project_Node_Id := Project_Declaration : Project_Node_Id;
Default_Project_Node
(In_Tree, N_Project_Declaration);
Source_Dirs_Declaration : constant Project_Node_Id := Source_Dirs_Declaration : constant Project_Node_Id :=
Default_Project_Node Default_Project_Node
(In_Tree, N_Declarative_Item); (In_Tree, N_Declarative_Item);
...@@ -292,12 +278,6 @@ package body Prj.Part is ...@@ -292,12 +278,6 @@ package body Prj.Part is
(In_Tree, N_Literal_String_List, List); (In_Tree, N_Literal_String_List, List);
begin begin
-- Get the virtual name id
Name_Len := Virtual_Name'Length;
Name_Buffer (1 .. Name_Len) := Virtual_Name;
Virtual_Name_Id := Name_Find;
-- Get the virtual path name -- Get the virtual path name
Get_Name_String (Path_Name_Of (Main_Project, In_Tree)); Get_Name_String (Path_Name_Of (Main_Project, In_Tree));
...@@ -314,6 +294,20 @@ package body Prj.Part is ...@@ -314,6 +294,20 @@ package body Prj.Part is
Name_Len := Name_Len + Virtual_Name'Length; Name_Len := Name_Len + Virtual_Name'Length;
Virtual_Path_Id := Name_Find; Virtual_Path_Id := Name_Find;
-- Get the virtual name id
Name_Len := Virtual_Name'Length;
Name_Buffer (1 .. Name_Len) := Virtual_Name;
Virtual_Name_Id := Name_Find;
Virtual_Project := Create_Project
(In_Tree => In_Tree,
Name => Virtual_Name_Id,
Full_Path => Virtual_Path_Id,
Is_Config_File => False);
Project_Declaration := Project_Declaration_Of (Virtual_Project, In_Tree);
-- With clause -- With clause
Set_Name_Of (With_Clause, In_Tree, Virtual_Name_Id); Set_Name_Of (With_Clause, In_Tree, Virtual_Name_Id);
...@@ -325,13 +319,8 @@ package body Prj.Part is ...@@ -325,13 +319,8 @@ package body Prj.Part is
-- Virtual project node -- Virtual project node
Set_Name_Of (Virtual_Project, In_Tree, Virtual_Name_Id);
Set_Path_Name_Of (Virtual_Project, In_Tree, Virtual_Path_Id);
Set_Location_Of Set_Location_Of
(Virtual_Project, In_Tree, Location_Of (Main_Project, In_Tree)); (Virtual_Project, In_Tree, Location_Of (Main_Project, In_Tree));
Set_Directory_Of (Virtual_Project, In_Tree, Virtual_Dir_Id);
Set_Project_Declaration_Of
(Virtual_Project, In_Tree, Project_Declaration);
Set_Extended_Project_Path_Of Set_Extended_Project_Path_Of
(Virtual_Project, In_Tree, Path_Name_Of (For_Project, In_Tree)); (Virtual_Project, In_Tree, Path_Name_Of (For_Project, In_Tree));
...@@ -361,54 +350,8 @@ package body Prj.Part is ...@@ -361,54 +350,8 @@ package body Prj.Part is
Set_Current_Term (Source_Dirs_Term, In_Tree, Source_Dirs_List); Set_Current_Term (Source_Dirs_Term, In_Tree, Source_Dirs_List);
-- Source_Dirs empty list: nothing to do -- Source_Dirs empty list: nothing to do
-- Put virtual project into Projects_Htable
Prj.Tree.Tree_Private_Part.Projects_Htable.Set
(T => In_Tree.Projects_HT,
K => Virtual_Name_Id,
E => (Name => Virtual_Name_Id,
Node => Virtual_Project,
Canonical_Path => No_Path,
Extended => False,
Proj_Qualifier => Unspecified));
end Create_Virtual_Extending_Project; end Create_Virtual_Extending_Project;
----------------------------
-- Immediate_Directory_Of --
----------------------------
function Immediate_Directory_Of
(Path_Name : Path_Name_Type) return Path_Name_Type
is
begin
Get_Name_String (Path_Name);
for Index in reverse 1 .. Name_Len loop
if Name_Buffer (Index) = '/'
or else Name_Buffer (Index) = Dir_Sep
then
-- Remove all chars after last directory separator from name
if Index > 1 then
Name_Len := Index - 1;
else
Name_Len := Index;
end if;
return Name_Find;
end if;
end loop;
-- There is no directory separator in name. Return "./" or ".\"
Name_Len := 2;
Name_Buffer (1) := '.';
Name_Buffer (2) := Dir_Sep;
return Name_Find;
end Immediate_Directory_Of;
----------------------------------- -----------------------------------
-- Look_For_Virtual_Projects_For -- -- Look_For_Virtual_Projects_For --
----------------------------------- -----------------------------------
...@@ -1167,7 +1110,8 @@ package body Prj.Part is ...@@ -1167,7 +1110,8 @@ package body Prj.Part is
Write_Eol; Write_Eol;
end if; end if;
Project_Directory := Immediate_Directory_Of (Normed_Path_Name); Project_Directory := Path_Name_Type
(Get_Directory (File_Name_Type (Normed_Path_Name)));
-- Is there any imported project? -- Is there any imported project?
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- B o d y -- -- B o d y --
-- -- -- --
-- Copyright (C) 2001-2008, Free Software Foundation, Inc. -- -- Copyright (C) 2001-2009, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- 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- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
with Ada.Unchecked_Deallocation; with Ada.Unchecked_Deallocation;
with Osint; use Osint;
with Prj.Err; with Prj.Err;
package body Prj.Tree is package body Prj.Tree is
...@@ -2820,4 +2821,45 @@ package body Prj.Tree is ...@@ -2820,4 +2821,45 @@ package body Prj.Tree is
return Unkept_Comments; return Unkept_Comments;
end There_Are_Unkept_Comments; end There_Are_Unkept_Comments;
--------------------
-- Create_Project --
--------------------
function Create_Project
(In_Tree : Project_Node_Tree_Ref;
Name : Name_Id;
Full_Path : Path_Name_Type;
Is_Config_File : Boolean := False) return Project_Node_Id
is
Project : Project_Node_Id;
Qualifier : Project_Qualifier := Unspecified;
begin
Project := Default_Project_Node (In_Tree, N_Project);
Set_Name_Of (Project, In_Tree, Name);
Set_Directory_Of
(Project, In_Tree,
Path_Name_Type (Get_Directory (File_Name_Type (Full_Path))));
Set_Path_Name_Of (Project, In_Tree, Full_Path);
Set_Project_Declaration_Of
(Project, In_Tree,
Default_Project_Node (In_Tree, N_Project_Declaration));
if Is_Config_File then
Qualifier := Configuration;
end if;
Prj.Tree.Tree_Private_Part.Projects_Htable.Set
(In_Tree.Projects_HT,
Name,
Prj.Tree.Tree_Private_Part.Project_Name_And_Node'
(Name => Name,
Canonical_Path => No_Path, -- ??? in GPS: Path_Name_Type (Name),
Node => Project,
Extended => False,
Proj_Qualifier => Qualifier));
return Project;
end Create_Project;
end Prj.Tree; end Prj.Tree;
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- S p e c -- -- S p e c --
-- -- -- --
-- Copyright (C) 2001-2008, Free Software Foundation, Inc. -- -- Copyright (C) 2001-2009, Free Software Foundation, Inc. --
-- -- -- --
-- GNAT is free software; you can redistribute it and/or modify it under -- -- 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- -- -- terms of the GNU General Public License as published by the Free Soft- --
...@@ -92,11 +92,11 @@ package Prj.Tree is ...@@ -92,11 +92,11 @@ package Prj.Tree is
function Present (Node : Project_Node_Id) return Boolean; function Present (Node : Project_Node_Id) return Boolean;
pragma Inline (Present); pragma Inline (Present);
-- Return True iff Node /= Empty_Node -- Return True if Node /= Empty_Node
function No (Node : Project_Node_Id) return Boolean; function No (Node : Project_Node_Id) return Boolean;
pragma Inline (No); pragma Inline (No);
-- Return True iff Node = Empty_Node -- Return True if Node = Empty_Node
procedure Initialize (Tree : Project_Node_Tree_Ref); procedure Initialize (Tree : Project_Node_Tree_Ref);
-- Initialize the Project File tree: empty the Project_Nodes table -- Initialize the Project File tree: empty the Project_Nodes table
...@@ -108,6 +108,15 @@ package Prj.Tree is ...@@ -108,6 +108,15 @@ package Prj.Tree is
And_Expr_Kind : Variable_Kind := Undefined) return Project_Node_Id; And_Expr_Kind : Variable_Kind := Undefined) return Project_Node_Id;
-- Returns a Project_Node_Record with the specified Kind and Expr_Kind. All -- Returns a Project_Node_Record with the specified Kind and Expr_Kind. All
-- the other components have default nil values. -- the other components have default nil values.
-- To create a node for a project itself, see Create_Project below instead
function Create_Project
(In_Tree : Project_Node_Tree_Ref;
Name : Name_Id;
Full_Path : Path_Name_Type;
Is_Config_File : Boolean := False) return Project_Node_Id;
-- Create a new node for a project and register it in the tree so that it
-- can be retrieved later on
function Hash (N : Project_Node_Id) return Header_Num; function Hash (N : Project_Node_Id) return Header_Num;
-- Used for hash tables where the key is a Project_Node_Id -- Used for hash tables where the key is a Project_Node_Id
...@@ -285,7 +294,9 @@ package Prj.Tree is ...@@ -285,7 +294,9 @@ package Prj.Tree is
(Node : Project_Node_Id; (Node : Project_Node_Id;
In_Tree : Project_Node_Tree_Ref) return Path_Name_Type; In_Tree : Project_Node_Tree_Ref) return Path_Name_Type;
pragma Inline (Directory_Of); pragma Inline (Directory_Of);
-- Only valid for N_Project nodes -- Only valid for N_Project nodes.
-- Returns the directory that contains the project file. This always
-- ends with a directory separator
function Expression_Kind_Of function Expression_Kind_Of
(Node : Project_Node_Id; (Node : Project_Node_Id;
......
...@@ -476,7 +476,8 @@ package body Prj is ...@@ -476,7 +476,8 @@ package body Prj is
function Find_Source function Find_Source
(In_Tree : Project_Tree_Ref; (In_Tree : Project_Tree_Ref;
Project : Project_Id; Project : Project_Id;
In_Imported_Only : Boolean; In_Imported_Only : Boolean := False;
In_Extended_Only : Boolean := False;
Base_Name : File_Name_Type) return Source_Id Base_Name : File_Name_Type) return Source_Id
is is
Result : Source_Id := No_Source; Result : Source_Id := No_Source;
...@@ -506,10 +507,21 @@ package body Prj is ...@@ -506,10 +507,21 @@ package body Prj is
procedure For_Imported_Projects is new For_Every_Project_Imported procedure For_Imported_Projects is new For_Every_Project_Imported
(State => Source_Id, Action => Look_For_Sources); (State => Source_Id, Action => Look_For_Sources);
Proj : Project_Id;
-- Start of processing for Find_Source -- Start of processing for Find_Source
begin begin
if In_Imported_Only then if In_Extended_Only then
Proj := Project;
while Proj /= No_Project loop
Look_For_Sources (Proj, Result);
exit when Result /= No_Source;
Proj := Proj.Extends;
end loop;
elsif In_Imported_Only then
Look_For_Sources (Project, Result); Look_For_Sources (Project, Result);
if Result = No_Source then if Result = No_Source then
......
...@@ -145,6 +145,7 @@ package Prj is ...@@ -145,6 +145,7 @@ package Prj is
Name : Path_Name_Type := No_Path; Name : Path_Name_Type := No_Path;
Display_Name : Path_Name_Type := No_Path; Display_Name : Path_Name_Type := No_Path;
end record; end record;
-- Directory names always end with a directory separator
No_Path_Information : constant Path_Information := (No_Path, No_Path); No_Path_Information : constant Path_Information := (No_Path, No_Path);
...@@ -1269,8 +1270,8 @@ package Prj is ...@@ -1269,8 +1270,8 @@ package Prj is
package Files_Htable is new Simple_HTable package Files_Htable is new Simple_HTable
(Header_Num => Header_Num, (Header_Num => Header_Num,
Element => Project_Id, Element => Source_Id,
No_Element => No_Project, No_Element => No_Source,
Key => File_Name_Type, Key => File_Name_Type,
Hash => Hash, Hash => Hash,
Equal => "="); Equal => "=");
...@@ -1298,11 +1299,13 @@ package Prj is ...@@ -1298,11 +1299,13 @@ package Prj is
function Find_Source function Find_Source
(In_Tree : Project_Tree_Ref; (In_Tree : Project_Tree_Ref;
Project : Project_Id; Project : Project_Id;
In_Imported_Only : Boolean; In_Imported_Only : Boolean := False;
In_Extended_Only : Boolean := False;
Base_Name : File_Name_Type) return Source_Id; Base_Name : File_Name_Type) return Source_Id;
-- Find the first source file with the given name either in the whole tree -- Find the first source file with the given name either in the whole tree
-- (if In_Imported_Only is False) or in the projects imported or extended -- (if In_Imported_Only is False) or in the projects imported or extended
-- by Project otherwise. -- by Project otherwise. In_Extended_Only implies In_Imported_Only, and
-- will only look in Project and the projects it extends
----------------------- -----------------------
-- Project_Tree_Data -- -- Project_Tree_Data --
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment