OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / ada / gnatcmd.adb
index a9c9b15..c75931a 100644 (file)
@@ -6,18 +6,17 @@
 --                                                                          --
 --                                 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.      --
@@ -42,6 +41,7 @@ with Prj.Util; use Prj.Util;
 with Sinput.P;
 with Snames;   use Snames;
 with Table;
+with Targparm;
 with Tempdir;
 with Types;    use Types;
 with Hostparm; use Hostparm;
@@ -67,7 +67,7 @@ procedure GNATCmd is
 
    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
@@ -119,19 +119,22 @@ procedure GNATCmd is
    --  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));
@@ -139,6 +142,9 @@ procedure GNATCmd is
    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));
 
@@ -228,7 +234,8 @@ procedure GNATCmd is
    --  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
@@ -321,7 +328,7 @@ procedure GNATCmd is
          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.
 
@@ -342,9 +349,9 @@ procedure GNATCmd is
                         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
@@ -368,10 +375,10 @@ procedure GNATCmd is
 
                            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
@@ -395,6 +402,8 @@ procedure GNATCmd is
                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
 
@@ -405,6 +414,9 @@ procedure GNATCmd is
 
                         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
@@ -417,7 +429,7 @@ procedure GNATCmd is
                               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
@@ -437,6 +449,8 @@ procedure GNATCmd is
 
                   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.
@@ -461,6 +475,8 @@ procedure GNATCmd is
                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.
@@ -473,6 +489,9 @@ procedure GNATCmd is
 
                         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
@@ -484,7 +503,8 @@ procedure GNATCmd is
                            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);
@@ -499,7 +519,7 @@ procedure GNATCmd is
                                     (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
@@ -511,6 +531,8 @@ procedure GNATCmd is
 
                   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.
@@ -527,7 +549,7 @@ procedure GNATCmd is
                                  (Project_Tree.Projects.Table
                                       (Unit_Data.File_Names
                                            (Specification).Project).
-                                      Object_Directory)              &
+                                      Object_Directory.Name)         &
                              Dir_Separator                           &
                              MLib.Fil.Ext_To
                                (Get_Name_String
@@ -538,22 +560,22 @@ procedure GNATCmd is
                   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;
@@ -669,7 +691,7 @@ procedure GNATCmd is
          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;
@@ -701,40 +723,43 @@ procedure GNATCmd is
 
    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;
 
@@ -752,7 +777,8 @@ procedure GNATCmd is
                 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
@@ -761,7 +787,7 @@ procedure GNATCmd is
       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);
@@ -775,6 +801,8 @@ procedure GNATCmd is
       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;
@@ -828,7 +856,7 @@ procedure GNATCmd is
          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
@@ -845,7 +873,7 @@ procedure GNATCmd is
                    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
@@ -853,7 +881,7 @@ procedure GNATCmd is
                    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;
@@ -872,7 +900,6 @@ procedure GNATCmd is
 
          if not Keep_Temporary_Files then
             Delete (File);
-
          else
             Close (File);
          end if;
@@ -1079,7 +1106,7 @@ procedure GNATCmd is
                            Dir : constant String :=
                                    Get_Name_String
                                      (Project_Tree.Projects.Table
-                                        (Prj).Object_Directory);
+                                        (Prj).Object_Directory.Name);
                         begin
                            if Is_Regular_File
                                 (Dir &
@@ -1160,7 +1187,7 @@ procedure GNATCmd is
                     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) &
@@ -1198,7 +1225,7 @@ procedure GNATCmd is
            new String'("-L" &
                        Get_Name_String
                          (Project_Tree.Projects.Table
-                            (Project).Library_Dir));
+                            (Project).Library_Dir.Name));
 
          --  Add the -l switch
 
@@ -1220,7 +1247,7 @@ procedure GNATCmd is
             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;
@@ -1304,9 +1331,22 @@ procedure GNATCmd is
 
       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;
@@ -1357,6 +1397,16 @@ begin
 
    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.
@@ -1520,18 +1570,26 @@ begin
    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;
 
@@ -1550,6 +1608,7 @@ begin
 
       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
@@ -1567,6 +1626,9 @@ begin
             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;
@@ -1644,9 +1706,23 @@ begin
                      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
@@ -1654,6 +1730,13 @@ begin
 
                      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
@@ -1750,6 +1833,7 @@ begin
 
                   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
@@ -1765,6 +1849,7 @@ begin
                   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
@@ -1911,7 +1996,7 @@ begin
             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
@@ -1927,6 +2012,7 @@ begin
            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.
@@ -2007,20 +2093,81 @@ begin
 
             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;
@@ -2062,7 +2209,7 @@ begin
             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);
@@ -2075,8 +2222,8 @@ begin
 
          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;
@@ -2112,7 +2259,7 @@ begin
 
                         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
@@ -2137,7 +2284,7 @@ begin
                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;
@@ -2156,10 +2303,15 @@ begin
 
          --  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);
@@ -2167,7 +2319,7 @@ begin
               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
@@ -2176,7 +2328,7 @@ begin
 
          if The_Command = Check then
             declare
-               New_Last          : Natural;
+               New_Last : Natural;
                --  Set to rank of options preceding "-rules"
 
                In_Rules_Switches : Boolean;
@@ -2219,32 +2371,36 @@ begin
             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;