-- --
-- B o d y --
-- --
--- Copyright (C) 1996-2007, Free Software Foundation, Inc. --
+-- Copyright (C) 1996-2008, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
--- ware Foundation; either version 2, or (at your option) any later ver- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
--- Public License distributed with GNAT; see file COPYING. If not, write --
--- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
--- Boston, MA 02110-1301, USA. --
+-- Public License distributed with GNAT; see file COPYING3. If not, go to --
+-- http://www.gnu.org/licenses for a complete copy of the license. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
with Sinput.P;
with Snames; use Snames;
with Table;
+with Targparm;
with Tempdir;
with Types; use Types;
with Hostparm; use Hostparm;
Old_Project_File_Used : Boolean := False;
-- This flag indicates a switch -p (for gnatxref and gnatfind) for
- -- an old fashioned project file. -p cannot be used in conjonction
+ -- an old fashioned project file. -p cannot be used in conjunction
-- with -P.
Max_Files_On_The_Command_Line : constant := 30; -- Arbitrary
-- tool. We allocate objects because we cannot declare aliased objects
-- as we are in a procedure, not a library level package.
- Naming_String : constant String_Access := new String'("naming");
- Binder_String : constant String_Access := new String'("binder");
- Compiler_String : constant String_Access := new String'("compiler");
- Check_String : constant String_Access := new String'("check");
- Eliminate_String : constant String_Access := new String'("eliminate");
- Finder_String : constant String_Access := new String'("finder");
- Linker_String : constant String_Access := new String'("linker");
- Gnatls_String : constant String_Access := new String'("gnatls");
- Pretty_String : constant String_Access := new String'("pretty_printer");
- Stack_String : constant String_Access := new String'("stack");
- Gnatstub_String : constant String_Access := new String'("gnatstub");
- Metric_String : constant String_Access := new String'("metrics");
- Xref_String : constant String_Access := new String'("cross_reference");
+ subtype SA is String_Access;
+
+ Naming_String : constant SA := new String'("naming");
+ Binder_String : constant SA := new String'("binder");
+ Compiler_String : constant SA := new String'("compiler");
+ Check_String : constant SA := new String'("check");
+ Synchronize_String : constant SA := new String'("synchronize");
+ Eliminate_String : constant SA := new String'("eliminate");
+ Finder_String : constant SA := new String'("finder");
+ Linker_String : constant SA := new String'("linker");
+ Gnatls_String : constant SA := new String'("gnatls");
+ Pretty_String : constant SA := new String'("pretty_printer");
+ Stack_String : constant SA := new String'("stack");
+ Gnatstub_String : constant SA := new String'("gnatstub");
+ Metric_String : constant SA := new String'("metrics");
+ Xref_String : constant SA := new String'("cross_reference");
Packages_To_Check_By_Binder : constant String_List_Access :=
new String_List'((Naming_String, Binder_String));
Packages_To_Check_By_Check : constant String_List_Access :=
new String_List'((Naming_String, Check_String, Compiler_String));
+ Packages_To_Check_By_Sync : constant String_List_Access :=
+ new String_List'((Naming_String, Synchronize_String, Compiler_String));
+
Packages_To_Check_By_Eliminate : constant String_List_Access :=
new String_List'((Naming_String, Eliminate_String, Compiler_String));
-- METRIC).
procedure Delete_Temp_Config_Files;
- -- Delete all temporary config files
+ -- Delete all temporary config files. The caller is responsible for
+ -- ensuring that Keep_Temporary_Files is False.
procedure Get_Closure;
-- Get the sources in the closure of the ASIS_Main and add them to the
declare
Current_Last : constant Integer := Last_Switches.Last;
begin
- -- Gnatstack needs to add the the .ci file for the binder
+ -- Gnatstack needs to add the .ci file for the binder
-- generated files corresponding to all of the library projects
-- and main units belonging to the application.
while Main /= Nil_String loop
File :=
new String'
- (Get_Name_String (Data.Object_Directory) &
- Directory_Separator &
- B_Start.all &
+ (Get_Name_String (Data.Object_Directory.Name) &
+ Directory_Separator &
+ B_Start.all &
MLib.Fil.Ext_To
(Get_Name_String
(Project_Tree.String_Elements.Table
File :=
new String'
- (Get_Name_String (Data.Object_Directory) &
- Directory_Separator &
- B_Start.all &
- Get_Name_String (Data.Library_Name) &
+ (Get_Name_String (Data.Object_Directory.Name) &
+ Directory_Separator &
+ B_Start.all &
+ Get_Name_String (Data.Library_Name) &
".ci");
if Is_Regular_File (File.all) then
if The_Command = List then
if
Unit_Data.File_Names (Body_Part).Name /= No_File
+ and then
+ Unit_Data.File_Names (Body_Part).Path.Name /= Slash
then
-- There is a body, check if it is for this project
if
Unit_Data.File_Names (Specification).Name = No_File
+ or else
+ Unit_Data.File_Names
+ (Specification).Path.Name = Slash
then
-- We have a body with no spec: we need to check if
-- this is a subunit, because gnatls will complain
Src_Ind := Sinput.P.Load_Project_File
(Get_Name_String
(Unit_Data.File_Names
- (Body_Part).Path));
+ (Body_Part).Path.Name));
Subunit :=
Sinput.P.Source_File_Is_Subunit
elsif
Unit_Data.File_Names (Specification).Name /= No_File
+ and then
+ Unit_Data.File_Names (Specification).Path.Name /= Slash
then
-- We have a spec with no body; check if it is for this
-- project.
elsif The_Command = Stack then
if
Unit_Data.File_Names (Body_Part).Name /= No_File
+ and then
+ Unit_Data.File_Names (Body_Part).Path.Name /= Slash
then
-- There is a body. Check if .ci files for this project
-- must be added.
if
Unit_Data.File_Names (Specification).Name = No_File
+ or else
+ Unit_Data.File_Names
+ (Specification).Path.Name = Slash
then
-- We have a body with no spec: we need to check
-- if this is a subunit, because .ci files are not
begin
Src_Ind := Sinput.P.Load_Project_File
(Get_Name_String
- (Unit_Data.File_Names (Body_Part).Path));
+ (Unit_Data.File_Names
+ (Body_Part).Path.Name));
Subunit :=
Sinput.P.Source_File_Is_Subunit (Src_Ind);
(Project_Tree.Projects.Table
(Unit_Data.File_Names
(Body_Part).Project).
- Object_Directory) &
+ Object_Directory.Name) &
Directory_Separator &
MLib.Fil.Ext_To
(Get_Name_String
elsif
Unit_Data.File_Names (Specification).Name /= No_File
+ and then
+ Unit_Data.File_Names (Specification).Path.Name /= Slash
then
-- We have a spec with no body. Check if it is for this
-- project.
(Project_Tree.Projects.Table
(Unit_Data.File_Names
(Specification).Project).
- Object_Directory) &
+ Object_Directory.Name) &
Dir_Separator &
MLib.Fil.Ext_To
(Get_Name_String
end if;
else
- -- For gnatcheck, gnatpp and gnatmetric, put all sources
- -- of the project, or of all projects if -U was specified.
+ -- For gnatcheck, gnatsync, gnatpp and gnatmetric, put all
+ -- sources of the project, or of all projects if -U was
+ -- specified.
for Kind in Spec_Or_Body loop
-
- -- Put only sources that belong to the main project
-
if Check_Project
(Unit_Data.File_Names (Kind).Project, Project)
+ and then Unit_Data.File_Names (Kind).Name /= No_File
+ and then Unit_Data.File_Names (Kind).Path.Name /= Slash
then
Last_Switches.Increment_Last;
Last_Switches.Table (Last_Switches.Last) :=
new String'
(Get_Name_String
- (Unit_Data.File_Names
- (Kind).Display_Path));
+ (Unit_Data.File_Names
+ (Kind).Path.Display_Name));
end if;
end loop;
end if;
end loop;
Get_Name_String (Project_Tree.Projects.Table
- (Project).Exec_Directory);
+ (Project).Exec_Directory.Name);
if Name_Buffer (Name_Len) /= Directory_Separator then
Name_Len := Name_Len + 1;
procedure Delete_Temp_Config_Files is
Success : Boolean;
+ pragma Warnings (Off, Success);
begin
- if not Keep_Temporary_Files then
- if Project /= No_Project then
- for Prj in Project_Table.First ..
- Project_Table.Last (Project_Tree.Projects)
- loop
- if
- Project_Tree.Projects.Table (Prj).Config_File_Temp
- then
- if Verbose_Mode then
- Output.Write_Str ("Deleting temp configuration file """);
- Output.Write_Str
- (Get_Name_String
- (Project_Tree.Projects.Table
- (Prj).Config_File_Name));
- Output.Write_Line ("""");
- end if;
+ -- This should only be called if Keep_Temporary_Files is False
- Delete_File
- (Name => Get_Name_String
+ pragma Assert (not Keep_Temporary_Files);
+
+ if Project /= No_Project then
+ for Prj in Project_Table.First ..
+ Project_Table.Last (Project_Tree.Projects)
+ loop
+ if
+ Project_Tree.Projects.Table (Prj).Config_File_Temp
+ then
+ if Verbose_Mode then
+ Output.Write_Str ("Deleting temp configuration file """);
+ Output.Write_Str
+ (Get_Name_String
(Project_Tree.Projects.Table
- (Prj).Config_File_Name),
- Success => Success);
+ (Prj).Config_File_Name));
+ Output.Write_Line ("""");
end if;
- end loop;
- end if;
- -- If a temporary text file that contains a list of files for a tool
- -- has been created, delete this temporary file.
+ Delete_File
+ (Name =>
+ Get_Name_String
+ (Project_Tree.Projects.Table (Prj).Config_File_Name),
+ Success => Success);
+ end if;
+ end loop;
+ end if;
+
+ -- If a temporary text file that contains a list of files for a tool
+ -- has been created, delete this temporary file.
- if Temp_File_Name /= null then
- Delete_File (Temp_File_Name.all, Success);
- end if;
+ if Temp_File_Name /= null then
+ Delete_File (Temp_File_Name.all, Success);
end if;
end Delete_Temp_Config_Files;
6 => new String'("-bargs"),
7 => new String'("-R"),
8 => new String'("-Z"));
- -- Arguments of the invocation of gnatmake to get the list of
+ -- Arguments for the invocation of gnatmake which are added to the
+ -- Last_Arguments list by this procedure.
FD : File_Descriptor;
-- File descriptor for the temp file that will get the output of the
Name : Path_Name_Type;
-- Path of the file FD
- GN_Name : constant String := Program_Name ("gnatmake").all;
+ GN_Name : constant String := Program_Name ("gnatmake", "gnat").all;
-- Name for gnatmake
GN_Path : constant String_Access := Locate_Exec_On_Path (GN_Name);
File : Ada.Text_IO.File_Type;
Line : String (1 .. 250);
Last : Natural;
+ -- Used to read file if there is an error, it is good enough to display
+ -- just 250 characters if the first line of the file is very long.
Udata : Unit_Data;
Path : Path_Name_Type;
raise Error_Exit;
else
- -- Get each file name in the file, find its path and add it the the
+ -- Get each file name in the file, find its path and add it the
-- list of arguments.
while not End_Of_File (File) loop
Get_Name_String (Udata.File_Names (Specification).Name) =
Line (1 .. Last)
then
- Path := Udata.File_Names (Specification).Path;
+ Path := Udata.File_Names (Specification).Path.Name;
exit;
elsif Udata.File_Names (Body_Part).Name /= No_File
Get_Name_String (Udata.File_Names (Body_Part).Name) =
Line (1 .. Last)
then
- Path := Udata.File_Names (Body_Part).Path;
+ Path := Udata.File_Names (Body_Part).Path.Name;
exit;
end if;
end loop;
if not Keep_Temporary_Files then
Delete (File);
-
else
Close (File);
end if;
Dir : constant String :=
Get_Name_String
(Project_Tree.Projects.Table
- (Prj).Object_Directory);
+ (Prj).Object_Directory.Name);
begin
if Is_Regular_File
(Dir &
new String'("-o");
Get_Name_String
(Project_Tree.Projects.Table
- (Project).Exec_Directory);
+ (Project).Exec_Directory.Name);
Last_Switches.Increment_Last;
Last_Switches.Table (Last_Switches.Last) :=
new String'(Name_Buffer (1 .. Name_Len) &
new String'("-L" &
Get_Name_String
(Project_Tree.Projects.Table
- (Project).Library_Dir));
+ (Project).Library_Dir.Name));
-- Add the -l switch
Library_Paths.Table (Library_Paths.Last) :=
new String'(Get_Name_String
(Project_Tree.Projects.Table
- (Project).Library_Dir));
+ (Project).Library_Dir.Name));
end if;
end if;
end Set_Library_For;
for C in Command_List'Range loop
if not Command_List (C).VMS_Only then
- Put ("gnat " & To_Lower (Command_List (C).Cname.all));
+ if Targparm.AAMP_On_Target then
+ Put ("gnaampcmd ");
+ else
+ Put ("gnat ");
+ end if;
+
+ Put (To_Lower (Command_List (C).Cname.all));
Set_Col (25);
- Put (Command_List (C).Unixcmd.all);
+
+ -- Never call gnatstack with a prefix
+
+ if C = Stack then
+ Put (Command_List (C).Unixcmd.all);
+ else
+ Put (Program_Name (Command_List (C).Unixcmd.all, "gnat").all);
+ end if;
declare
Sws : Argument_List_Access renames Command_List (C).Unixsws;
Set_Mode (Ada_Only);
+ -- Add the default search directories, to be able to find system.ads in the
+ -- subsequent call to Targparm.Get_Target_Parameters.
+
+ Add_Default_Search_Dirs;
+
+ -- Get target parameters so that AAMP_On_Target will be set, for testing in
+ -- Osint.Program_Name to handle the mapping of GNAAMP tool names.
+
+ Targparm.Get_Target_Parameters;
+
-- Add the directory where the GNAT driver is invoked in front of the path,
-- if the GNAT driver is invoked with directory information. Do not do this
-- for VMS, where the notion of path does not really exist.
end if;
declare
- Program : constant String :=
- Program_Name (Command_List (The_Command).Unixcmd.all).all;
-
+ Program : String_Access;
Exec_Path : String_Access;
begin
+ if The_Command = Stack then
+ -- Never call gnatstack with a prefix
+
+ Program := new String'(Command_List (The_Command).Unixcmd.all);
+
+ else
+ Program :=
+ Program_Name (Command_List (The_Command).Unixcmd.all, "gnat");
+ end if;
+
-- Locate the executable for the command
- Exec_Path := Locate_Exec_On_Path (Program);
+ Exec_Path := Locate_Exec_On_Path (Program.all);
if Exec_Path = null then
- Put_Line (Standard_Error, "could not locate " & Program);
+ Put_Line (Standard_Error, "could not locate " & Program.all);
raise Error_Exit;
end if;
if The_Command = Bind
or else The_Command = Check
+ or else The_Command = Sync
or else The_Command = Elim
or else The_Command = Find
or else The_Command = Link
when Check =>
Tool_Package_Name := Name_Check;
Packages_To_Check := Packages_To_Check_By_Check;
+ when Sync =>
+ Tool_Package_Name := Name_Synchronize;
+ Packages_To_Check := Packages_To_Check_By_Sync;
when Elim =>
Tool_Package_Name := Name_Eliminate;
Packages_To_Check := Packages_To_Check_By_Eliminate;
end if;
end if;
+ -- --subdirs=... Specify Subdirs
+
+ if Argv'Length > Subdirs_Option'Length and then
+ Argv
+ (Argv'First .. Argv'First + Subdirs_Option'Length - 1) =
+ Subdirs_Option
+ then
+ Subdirs :=
+ new String'
+ (Argv
+ (Argv'First + Subdirs_Option'Length .. Argv'Last));
+
+ Remove_Switch (Arg_Num);
+
-- -aPdir Add dir to the project search path
- if Argv'Length > 3
+ elsif Argv'Length > 3
and then Argv (Argv'First + 1 .. Argv'First + 2) = "aP"
then
Add_Search_Project_Directory
Remove_Switch (Arg_Num);
+ -- -eL Follow links for files
+
+ elsif Argv.all = "-eL" then
+ Follow_Links_For_Files := True;
+
+ Remove_Switch (Arg_Num);
+
-- -vPx Specify verbosity while parsing project files
elsif Argv'Length = 4
elsif
(The_Command = Check or else
+ The_Command = Sync or else
The_Command = Pretty or else
The_Command = Metric or else
The_Command = Stack or else
end if;
elsif ((The_Command = Check and then Argv (Argv'First) /= '+')
+ or else The_Command = Sync
or else The_Command = Metric
or else The_Command = Pretty)
and then Project_File /= null
Change_Dir
(Get_Name_String
(Project_Tree.Projects.Table
- (Project).Object_Directory));
+ (Project).Object_Directory.Name));
end if;
-- Set up the env vars for project path files
or else The_Command = Stub
or else The_Command = Elim
or else The_Command = Check
+ or else The_Command = Sync
then
-- If there are switches in package Compiler, put them in the
-- Carg_Switches table.
for J in 1 .. First_Switches.Last loop
if First_Switches.Table (J).all = "-cargs" then
- for K in J + 1 .. First_Switches.Last loop
- Add_To_Carg_Switches (First_Switches.Table (K));
- end loop;
- First_Switches.Set_Last (J - 1);
+ declare
+ K : Positive;
+ Last : Natural;
+
+ begin
+ -- Move the switches that are before -rules when the
+ -- command is CHECK.
+
+ K := J + 1;
+ while K <= First_Switches.Last
+ and then
+ (The_Command /= Check
+ or else First_Switches.Table (K).all /= "-rules")
+ loop
+ Add_To_Carg_Switches (First_Switches.Table (K));
+ K := K + 1;
+ end loop;
+
+ if K > First_Switches.Last then
+ First_Switches.Set_Last (J - 1);
+
+ else
+ Last := J - 1;
+ while K <= First_Switches.Last loop
+ Last := Last + 1;
+ First_Switches.Table (Last) :=
+ First_Switches.Table (K);
+ K := K + 1;
+ end loop;
+
+ First_Switches.Set_Last (Last);
+ end if;
+ end;
+
exit;
end if;
end loop;
for J in 1 .. Last_Switches.Last loop
if Last_Switches.Table (J).all = "-cargs" then
- for K in J + 1 .. Last_Switches.Last loop
- Add_To_Carg_Switches (Last_Switches.Table (K));
- end loop;
- Last_Switches.Set_Last (J - 1);
+ declare
+ K : Positive;
+ Last : Natural;
+
+ begin
+ -- Move the switches that are before -rules when the
+ -- command is CHECK.
+
+ K := J + 1;
+ while K <= Last_Switches.Last
+ and then
+ (The_Command /= Check
+ or else
+ Last_Switches.Table (K).all /= "-rules")
+ loop
+ Add_To_Carg_Switches (Last_Switches.Table (K));
+ K := K + 1;
+ end loop;
+
+ if K > Last_Switches.Last then
+ Last_Switches.Set_Last (J - 1);
+
+ else
+ Last := J - 1;
+ while K <= Last_Switches.Last loop
+ Last := Last + 1;
+ Last_Switches.Table (Last) :=
+ Last_Switches.Table (K);
+ K := K + 1;
+ end loop;
+
+ Last_Switches.Set_Last (Last);
+ end if;
+ end;
+
exit;
end if;
end loop;
end loop;
Get_Name_String
- (Project_Tree.Projects.Table (Project).Directory);
+ (Project_Tree.Projects.Table (Project).Directory.Name);
declare
Project_Dir : constant String := Name_Buffer (1 .. Name_Len);
elsif The_Command = Stub then
declare
- Data : constant Prj.Project_Data :=
- Project_Tree.Projects.Table (Project);
+ Data : constant Prj.Project_Data :=
+ Project_Tree.Projects.Table (Project);
File_Index : Integer := 0;
Dir_Index : Integer := 0;
Last : constant Integer := Last_Switches.Last;
if Spec'Length > Name_Len
and then Spec (Last - Name_Len + 1 .. Last) =
- Name_Buffer (1 .. Name_Len)
+ Name_Buffer (1 .. Name_Len)
then
Last := Last - Name_Len;
Get_Name_String
if File_Index /= 0 then
for Index in File_Index + 1 .. Last loop
if Last_Switches.Table (Index)
- (Last_Switches.Table (Index)'First) /= '-'
+ (Last_Switches.Table (Index)'First) /= '-'
then
Dir_Index := Index;
exit;
-- For gnatmetric, the generated files should be put in the object
-- directory. This must be the first switch, because it may be
- -- overriden by a switch in package Metrics in the project file or by
- -- a command line option.
-
- if The_Command = Metric then
+ -- overridden by a switch in package Metrics in the project file or
+ -- by a command line option. Note that we don't add the -d= switch
+ -- if there is no object directory available.
+
+ if The_Command = Metric
+ and then
+ Project_Tree.Projects.Table (Project).Object_Directory /=
+ No_Path_Information
+ then
First_Switches.Increment_Last;
First_Switches.Table (2 .. First_Switches.Last) :=
First_Switches.Table (1 .. First_Switches.Last - 1);
new String'("-d=" &
Get_Name_String
(Project_Tree.Projects.Table
- (Project).Object_Directory));
+ (Project).Object_Directory.Name));
end if;
-- For gnat check, -rules and the following switches need to be the
if The_Command = Check then
declare
- New_Last : Natural;
+ New_Last : Natural;
-- Set to rank of options preceding "-rules"
In_Rules_Switches : Boolean;
end;
end if;
- -- For gnat check, metric or pretty with -U + a main, get the list
- -- of sources from the closure and add them to the arguments.
+ -- For gnat check, sync, metric or pretty with -U + a main, get the
+ -- list of sources from the closure and add them to the arguments.
if ASIS_Main /= null then
Get_Closure;
- -- On VMS, set up again the env var for source dirs file. This is
+ -- On VMS, set up the env var again for source dirs file. This is
-- because the call to gnatmake has set this env var to another
-- file that has now been deleted.
if Hostparm.OpenVMS then
- Setenv
- (Project_Include_Path_File,
- Prj.Env.Ada_Include_Path
- (Project, Project_Tree, Recursive => True));
+
+ -- First make sure that the recorded file names are empty
+
+ Prj.Env.Initialize;
+
+ Prj.Env.Set_Ada_Paths
+ (Project, Project_Tree, Including_Libraries => False);
end if;
- -- For gnat check, gnat pretty, gnat metric, gnat list, and gnat
- -- stack, if no file has been put on the command line, call tool
- -- with all the sources of the main project.
+ -- For gnat check, gnat sync, gnat pretty, gnat metric, gnat list,
+ -- and gnat stack, if no file has been put on the command line, call
+ -- tool with all the sources of the main project.
elsif The_Command = Check or else
- The_Command = Pretty or else
- The_Command = Metric or else
- The_Command = List or else
- The_Command = Stack
+ The_Command = Sync or else
+ The_Command = Pretty or else
+ The_Command = Metric or else
+ The_Command = List or else
+ The_Command = Stack
then
Check_Files;
end if;