------------------------------------------------------------------------------
--                                                                          --
--                     ASIS UTILITY LIBRARY COMPONENTS                      --
--                                                                          --
--                       A S I S _ U L . C O M M O N                        --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--                    Copyright (C) 2004-2014, AdaCore                      --
--                                                                          --
-- Asis Utility Library (ASIS UL) is free software; you can redistribute it --
-- and/or  modify  it  under  terms  of  the  GNU General Public License as --
-- published by the Free Software Foundation; either version 3, or (at your --
-- option)  any later version.  ASIS UL  is distributed in the hope that it --
-- will  be  useful,  but  WITHOUT  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 --
-- COPYING3. If not,  go to http://www.gnu.org/licenses for a complete copy --
-- of the license.                                                          --
--                                                                          --
-- GNATCHECK is maintained by AdaCore (http://www.adacore.com).             --
--                                                                          --
------------------------------------------------------------------------------

pragma Ada_2012;

with Ada.Characters.Handling;    use Ada.Characters.Handling;
with Ada.Command_Line;           use Ada.Command_Line;
with Ada.Strings.Fixed;          use Ada.Strings.Fixed;

with GNAT.Directory_Operations;

with Hostparm;
with A4G.A_Types;                use A4G.A_Types;

with ASIS_UL.Output;             use ASIS_UL.Output;
with ASIS_UL.Compiler_Options;   use ASIS_UL.Compiler_Options;

package body ASIS_UL.Common is

   -----------------------
   -- Local subprograms --
   -----------------------

   function Detect_Target return String;
   --  Detects if this is a cross version of the tool by analyzing its name.
   --  In case if it is a cross version, returns the prefix of the name
   --  detecting the specific cross version, otherwise returns an empty
   --  string  (in case if the tool name starts with "gnaamp", returns "AAMP")

   procedure Set_Tool_Name_And_Path;
   --  Reads the tool name from the command line and sets Tool_Name. If the
   --  tool name contains the directory information, adds (on non-VMS
   --  platforms) the directory to the path.

   Global_Report_Dir : String_Access;
   --  The name of the directory to place the global results into

   function Compiler_To_Call
     (Gnatmake_Call : Boolean := False)
      return          String;
   --  Detects the name of the compiler to call. If Gnatmake_Call is ON, looks
   --  for gnatmake ('gnatmake -f -c -u' is used to create the tree in this
   --  case), otherwise looks for the GNAT compiler (gcc)

   ----------------------
   -- Compiler_To_Call --
   ----------------------

   function Compiler_To_Call
     (Gnatmake_Call : Boolean := False)
      return          String
   is
      Target : constant String := Detect_Target;
   begin

      if Target = "AAMP" then

         if Gnatmake_Call then
            return "gnaampmake";
         else
            return "gnaamp";
         end if;

      else

         if Gnatmake_Call then
            return Target & "gnatmake";
         else
            return Target & "gcc";
         end if;

      end if;

   end Compiler_To_Call;

   -------------------
   -- Detect_Target --
   -------------------

   function Detect_Target return String is
      use GNAT.Directory_Operations;

      Tgt_Last : constant Natural :=
        Index (Tool_Name.all, "-", Ada.Strings.Backward);
      AAMP_Idx : constant Natural := Index (Tool_Name.all, "gnaamp");
   begin

      if AAMP_Idx = Tool_Name'First then
         return "AAMP";
      elsif Tgt_Last > 0 and then not Hostparm.OpenVMS then
         return Tool_Name (Tool_Name'First .. Tgt_Last);
      else
         return "";
      end if;

   exception
      when others =>
         return "";

   end Detect_Target;

   ---------------------------
   -- Get_Global_Report_Dir --
   ---------------------------

   function Get_Global_Report_Dir return String is
   begin
      return (if Global_Report_Dir = null
              then ""
              else Global_Report_Dir.all & Directory_Separator);
   end Get_Global_Report_Dir;

   --------------------------
   -- Process_Project_File --
   --------------------------

   procedure Process_Project_File (Project_File_Name : String) is
   begin

      if Is_Regular_File (Project_File_Name) then
         Project_File := new String'(Normalize_Pathname (Project_File_Name));

         if Project_Support_Type = No_Tmp_Project_File then
            Store_Option ("-P" & Project_File.all);
         end if;

      else
         Error ("the project file " & Project_File_Name & " not found");
         raise Parameter_Error;
      end if;

      Gcc_To_Call := Gnatmake_To_Call;

      if Gcc_To_Call /= null then
         Use_Gnatmake_To_Compile := True;
      else
         Error ("can not locate gnatmake to compile with a project file");
         raise Parameter_Error;
      end if;

      Use_Project_File := True;

   end Process_Project_File;

   ---------------------------
   -- Set_Global_Report_Dir --
   ---------------------------

   procedure Set_Global_Report_Dir (Dir : String) is
   begin
      Free (Global_Report_Dir);
      Global_Report_Dir := new String'(Dir);
   end Set_Global_Report_Dir;

   -------------------
   -- Set_Tool_Name --
   -------------------

   procedure Set_Tool_Name (To_This : String) is
   begin
      Free (Tool_Name);
      Tool_Name := new String'(To_This);
   end Set_Tool_Name;

   ----------------------------
   -- Set_Tool_Name_And_Path --
   ----------------------------

   procedure Set_Tool_Name_And_Path is
      Full_Tool_Name : constant String := Ada.Command_Line.Command_Name;
      Exe_Suffix     : String_Access   := Get_Executable_Suffix;
   begin
      Tool_Name :=
        new String'(To_Lower
                      (GNAT.Directory_Operations.Base_Name
                         (Full_Tool_Name, Suffix => Exe_Suffix.all)));

      if not Hostparm.OpenVMS then

         for Index in reverse Full_Tool_Name'Range loop
            if Full_Tool_Name (Index) = Directory_Separator then
               declare
                  Absolute_Dir : constant String :=
                                    Normalize_Pathname
                                     (Full_Tool_Name
                                        (Full_Tool_Name'First .. Index));

                  PATH : constant String :=
                                   Absolute_Dir &
                                   A4G.A_Types.ASIS_Path_Separator &
                                   Getenv ("PATH").all;

               begin
                  Setenv ("PATH", PATH);
               end;

               exit;
            end if;
         end loop;

      end if;

      Free (Exe_Suffix);
   end Set_Tool_Name_And_Path;

begin
   Set_Tool_Name_And_Path;

   Gcc_To_Call      := GNAT.OS_Lib.Locate_Exec_On_Path (Compiler_To_Call);
   Gnatmake_To_Call := GNAT.OS_Lib.Locate_Exec_On_Path
     (Compiler_To_Call (Gnatmake_Call => True));
end ASIS_UL.Common;
