------------------------------------------------------------------------------
--                                                                          --
--                     ASIS UTILITY LIBRARY COMPONENTS                      --
--                                                                          --
--                       A S I S _ U L . C O M M O N                        --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--                    Copyright (C) 2004-2010, 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 2, 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 --
-- COPYING. If not,  write  to the  Free Software Foundation,  51 Franklin --
-- Street, Fifth Floor, Boston, MA 02110-1301, USA.                         --
--                                                                          --
-- GNATCHECK is maintained by AdaCore (http://www.adacore.com).             --
--                                                                          --
------------------------------------------------------------------------------

--  This package defines entities that are of general interest and can be used
--  in more then one component of the tool

--  When using this package, keep in mind that it computes the name of the
--  tool as a part of its elaboration, and if the tool name contains a path
--  information, the full absolute name of the directory the tool is located in
--  is added to the beginning of the PATH environment variable. This is done
--  to make it possible to use a tool belonging (or related)) to a particular
--  version  GNAT compiler in case when more then one GNAT version is
--  installed - the idea is that when a tool calls a compiler to create a tree
--  file, this compiler should be from the same GNAT version as the tool
--  itself. See the body (Set_Tool_Name_And_Path routine) for all details.
--
--  Note, that on Windows the system implicitly adds a full path to a command
--  name even if the real tool invocation does not contain any path information
--  for the tool name, so in case Windows the directory where the tool
--  executable is located will allways be prepended to the path.

with GNAT.OS_Lib; use GNAT.OS_Lib;

with Asis;

package ASIS_UL.Common is

   pragma Elaborate_Body (ASIS_UL.Common);

   Tool_Name : String_Access;
   --  Used to generate error messages and to define the compiler to be used
   --  to create the trees. Is set as the name of the tool that is actually
   --  called (that is, as the result of Ada.Command_Line.Command_Name). This
   --  name is used in the diagnostic messages generated by the tool
   --  (preserving the casing of the result returned by
   --  Ada.Command_Line.Command_Name).
   --
   --  The tool name given in the command line should satisfy the following
   --  rules:
   --
   --  - if the name contains the minus sign ('-'), the part of the name before
   --    the rightmost '-' should be the name of the cross platform the tool
   --    is supposed to be used for
   --
   --  - if the name starts from "gnaamp", it is treated as the name of the
   --    tool to be used for AAMP compiler, in this case if the name contains
   --    a '-' sign, this minus is treated as a part of the tool name with
   --    no possible relation to the name of the cross platform.
   --
   --  This variable is initialized during the elaboration of this package, a
   --  tool may change it afterwards. If the tool is invoked with directory
   --  information, this directory information is striped away when setting the
   --  value for Tool_Name, but the directory where the tool is invoked is
   --  added in front of the path (if we are not on VMS). Here we are using the
   --  same approach as gnatmake. See E709-001. Note that the tool name is
   --  always converted to lower case.

   procedure Set_Tool_Name (To_This : String);
   --  Overrides the tool name that is automatically detected from the tool
   --  call

   Gcc_To_Call : String_Access;
   --  This variable is supposed to contain the full path to gcc to be used to
   --  create trees, it is initialized during the elaboration of this package,
   --  a tool may change it afterwards. If this is set to null, the standard
   --  gcc installation is used (if any).
   --  The value of this variable is detected during the elaboration time, just
   --  after detecting Tool_Name

   Gnatmake_To_Call : String_Access;
   --  This variable is supposed to contain the full path to gnatmake to be
   --  used namely as gnatmake, but not the tree creator for ASIS Context.
   --  This is needed by gnatelim and may probably be needed by some other
   --  tools
   --  The value of this variable is detected during the elaboration time, just
   --  after detecting Tool_Name

   Use_Gnatmake_To_Compile : Boolean := False;
   --  This flag indicates that gnatmake (as 'gnatmake -c -u -f ...') should be
   --  used to create the tree instead of gcc.

   Compiler_Output_File_Name : String_Access;
   --  The name of the file used to redirect the compiler diagnostic messages.
   --  Is set by ASIS_UL.Environment.Go_To_Temp_Dir.

   Fatal_Error : exception;
   --  This exception should be raised when there is no sense any more to do
   --  any work in the tool. When raising this exception, one has to generate
   --  the "fatal" diagnostic message.

   Parameter_Error : exception;
   --  Is raised when an error is detected for the parameters supplied for the
   --  tool (includes both wrong parameters and wrong combinations of correct
   --  parameters)

   Non_Implemented_Error : exception;
   --  This exception is raised if the execution comes to some part of the tool
   --  that has not been completely implemented yet.

   Tool_Failures : Natural := 0;
   --  Counter for tool failures a tool has recovered from

   Illegal_File_Detected : Boolean := False;
   --  Flag indicating if there was at least one non-successful compilation
   --  during the tool invocation.

   The_Context : Asis.Context;
   --  The Context for all the ASIS processing made by the tools. May be
   --  associated, opened, closed and dissociated several times during one
   --  tool run

   The_CU : Asis.Compilation_Unit;
   --  The ASIS Compilation Unit corresponding to the unit represented by the
   --  source being processed.

   Arg_File : String_Access;
   --  The name of the source to process. May be set by different ways, but
   --  if it is non-null, it should contain the name of the existing file with
   --  full directory information in the normalized absolute form.

   Tree_File : String_Access;
   --  The name of the tree file created in the temporary directory

   Project_File : String_Access;
   --  The name of the project file used to locate sources and to compile
   --  for the tree. It is supposed that after reading and checking the tool
   --  parameters this variable is either null (in case if no project file is
   --  used) or it points to the full name of the existing project file with
   --  path information in absolute form.

   Multiple_File_Mode : Boolean := True;
   --  This flag may be used by tools that use Source file table to check if
   --  they have several or only one file to process. The tool should itself
   --  set this file if it wants to use it. If this file is OFF, no source
   --  trace is generated in non-verbise mode.

   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)

   -----------------------------------
   -- Project support in ASIS tools --
   -----------------------------------

   --  The basic idea of providing the project support for ASIS tools is to
   --  use not GCC, but GNATMAKE to create the tree for the ASIS part of the
   --  tool and by means of this to use the project support embadded into
   --  GNATMAKE. That is, if the tool has a parameter -Pproject_file, then
   --  to create the tree we use:
   --
   --    $gnatmake -c -f -u -Pproject_file_1 -gnatct ...
   --
   --  The main problem with this approach is that the tree file is placed in
   --  the directory that is defined as an object directory in the project
   --  file, so we have to do something to get the tree created in the
   --  temporarry directory the tool creates for all its compilations. There
   --  are two solutions for this problem:

   --  (1) to add '-cargs -o .' to the gnatmake arguments to redirect the
   --      gnatmake output into the current dir (gnatmake is called from the
   --      temporary dir created by the tool).

   --  (2) to create in the temporary dir a new project file with the following
   --      content:
   --
   --         project Temp extends "full_name_of_project_file" is
   --            for Object_Dir use ".";
   --         end Temp;
   --
   --      and to use this new project file as the argument of the gnatmake
   --      call

   --  The main problem with the first approach is that in case if the argument
   --  file has not been compiled before (with generating the corresponding
   --  ALI file, that call ends up with the diagnostic messages like:
   --
   --    gnatmake: "p.ali" WARNING: ALI or object file not found after compile
   --    gnatmake: "c:\atre-tests\projects\p.ads" compilation error
   --
   --  and no tree file is generated.

   --  At the moment we implement both approaches. The tool can select the
   --  needed approach of the project support by setting the
   --  Project_Support_Type variable below

   type Project_Support_Types is (No_Tmp_Project_File, Use_Tmp_Project_File);

   Project_Support_Type : Project_Support_Types := Use_Tmp_Project_File;

   procedure Process_Project_File (Project_File_Name : String);
   --  This procedure analyzes the parameter of -P tool option. First, it
   --  checks that Project_File_Name really exists, and if it is, stores
   --  the full normalized name of this file as the value of
   --  ASIS_UL.Common.Project_File, otherwise Parameter_Error is raised.
   --  If No_Tmp_Project_File project support mode is set, this procedure
   --  adds '-P<full_proj_file_name> option to the set of compiler/gnatmake
   --  options used to create the tree. This procedure also tries to locate
   --  gnatmake and raises Parameter_Error if this attempt fails.
   --  If all the checks are successful, Use_Project_File is set ON.

   Use_Project_File : Boolean := False;
   --  Flag indicating if a project file is used when compiling sources for
   --  the trees. With a project file, we should not try to check from a
   --  short file name if the file exists and we should not use full file
   --  names

end ASIS_UL.Common;
