------------------------------------------------------------------------------
--                                                                          --
--                     ASIS UTILITY LIBRARY COMPONENTS                      --
--                                                                          --
--                 A S I S _ U L . S O U R C E _ T A B L E                  --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--                     Copyright (C) 2004-2007, 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.                         --
--                                                                          --
-- ASIS UL is maintained by AdaCore (http://www.adacore.com).               --
--                                                                          --
------------------------------------------------------------------------------

--  This package defines the source file table - the table containing the
--  information about the source files to be processed and the state of their
--  processing

with Asis;

package ASIS_UL.Source_Table is

   Low_SF_Bound  : constant := 0;
   High_SF_Bound : constant := 999_999;
   --  Almost 1_000_000 source files for one run of the tool

   type SF_Id is range Low_SF_Bound .. High_SF_Bound;

   No_SF_Id    : constant SF_Id := Low_SF_Bound;
   First_SF_Id : constant SF_Id := No_SF_Id + 1;

   Total_Sources : Natural;
   Sources_Left  : Natural;
   --  Counters used to form and output progress information.

   type SF_Status is (
      Waiting,
      --  Waiting for processing
      Not_A_Legal_Source,
      --  The file does not contain the compilable source

      Error_Detected,
      --  Some tool problem has been detected when processing this source
      --  so the results of processing may not be safe

      Out_File_Problem,
      --  The out file was not successfully created or opened

      ASIS_Processed,

      Non_ASIS_Processed,

      Processed);
      --  The source file has been successfully processed

   type SF_Info is new Integer;
   --  The type to be used for the integer values associate with each source in
   --  the source file table. The use of this value is client-specific

   function Present (SF : SF_Id) return Boolean;
   --  Checks that SF is not is equal to No_SF_Id

   function File_Find
     (SF_Name        : String;
      Use_Short_Name : Boolean := False)
      return           SF_Id;
   --  Returns the Id of the file with name SF_Name stored in the
   --  files table. Returns No_SF_Id if the table does not contain such file.
   --  In case if ASIS_UL.Common.Use_Project_File is set ON, or Use_Short_Name
   --  parameter is set ON, the short file name is used to locate the file, if
   --  the argument contains a directory information it is stripped out.
   --  Otherwise this function tries to locate the name with the full
   --  normalized name equal to SF_Name.

   function File_Find (El : Asis.Element) return SF_Id;
   --  Returns the Id of the file containing the argument Element enclosing
   --  compilation unit. Returns No_SF_Id if the argument is Nil_Element or
   --  if the source file table does not contain the given file.

   procedure Add_Source_To_Process
     (Fname       : String;
      No_Argument : out Boolean);
   --  Fname is treated as the name of the file to process by the tool.
   --  If it is an empty string, this procedure set No_Argument ON (to stop
   --  iteration through tool parameters) and does nothing more. Otherwise it
   --  tries to add this file to the table of files to process. The following
   --  checks are performed:
   --
   --  If ASIS_UL.Common.Use_Project_File is set ON:
   --
   --  - this routine checks if we have already stored a file with the same
   --    short(!) name. If we already have such a file, it generates a
   --    warning message and does nothing else.
   --
   --  If ASIS_UL.Common.Use_Project_File is set OFF:
   --
   --  - first, this routine checks if Fname is the name of some existing file,
   --    and if it is not, generates the corresponding diagnosis and does
   --    nothing more;
   --
   --  - then, it checks if we already have stored a file with the same name.
   --    If we have the file with the same name, but from a different
   --    directory, the corresponding warning is generated, but the file is
   --    added to the file table (the situation when the metric tool is called
   --    to process files with the same name but from different directories
   --    looks strange, but this may be quite legal and reasonable). But if we
   --    have already stored in the list the name of exactly the same file, we
   --    generate the error message and do not change anything in the list of
   --    files.
   --
   --  At this stage we do not know if Fname denotes a compilable Ada source
   --  file.
   --
   --  It is supposed to be used as a part of the tool parameter processing
   --  in the following way:
   --
   --      loop
   --         Add_Source_To_Process
   --           (Get_Argument (Do_Expansion => True), No_More_Args);
   --         exit when No_More_Args;
   --      end loop;

   procedure Read_Args_From_File (Par_File_Name : String);
   --  Reads argument files from the file. Performs the same checks as when
   --  file names are read from the command line. This procedure assumes that
   --  the file named by Par_File_Name contains argument file names separated
   --  by one or more white space (space character or HT), CR or LF.

   function Add_Needed_Source (Fname : String) return SF_Id;
   --  This function unconditionally stores the file with the name Fname in the
   --  source file table and returns the corresponding Id. Fname should be a
   --  full (???) name of existing file. This procedure is supposed to be
   --  called to store the name of the file that is not the argument of the
   --  tool, but that is detected as a file that is needed because of any
   --  reason for some argument file. For example, it may be a file containing
   --  a unit needed to be analyzed to build a full call graph. The caller is
   --  responsible for the fact that this source has not been already stored in
   --  the file table.

   function Last_Source return SF_Id;
   --  Returns the Id of the last source stored in the source table. Returns
   --  No_SF_Id if there is no source file stored

   function Last_Argument_Source return SF_Id;
   --  Returns the Id of the last argument source stored in the source table.
   --  An argument source is the source set as the argument of the tool call.

   function Is_Argument_Source (SF : SF_Id) return Boolean;
   --  Checks if SF is from tool argument sources

   function Is_Needed_Source (SF : SF_Id) return Boolean;
   --  Checks if SF is a source that has been added as a needed source for some
   --  argument source

   function Already_Processed
     (Include_Needed_Sources : Boolean)
      return                   Natural;
   --  Returns the number of the currently processed sources (that is, sources
   --  having the status different from Waiting). If Include_Needed_Sources is
   --  set ON, all the sources are counted, otherwise - only argument sources

   procedure Reset_Source_Iterator;

   function Next_Non_Processed_Source
     (Only_Bodies            : Boolean := False;
      Include_Needed_Sources : Boolean := False)
      return                   SF_Id;
   --  These two routines provide the iterator through the sources stored in
   --  the sources table. Reset_Source_Iterator resets the iterator to the
   --  ID of the first source stored in the table. Next_Non_Processed_Source
   --  returns the Id if the next source file stored in the file table which
   --  has not been processed yet. If Only_Bodies parameter is set ON, only
   --  body files are considered. We are not 100% sure that this file indeed
   --  is an Ada body file, at this stage we consider any file which name has
   --  ".adb" suffix as a body file. No_SF_Id is returned if there is no such
   --  file in the file table. The idea behind is to process first all the body
   --  files and for each body to process as much specs as possible using this
   --  body tree file, to minimize a set of trees needed to be created to
   --  process all the sources.
   --  If Include_Needed_Sources parameter is set on, all the source files are
   --  considered, both argument files of the tool and the files added as a
   --  result of analyzing the global state of the program. Otherwise only
   --  argument sources are considered.

   procedure Init;
   --  Initializes the internal data structures for the source table

   procedure Create_Tree
     (SF           : SF_Id;
      Success      : out Boolean;
      Compiler_Out : String := "");
   --  Tries to create a tree file for SF. Sets Success ON if this attempt is
   --  successful. Otherwise sets Success OFF, generates the diagnostic
   --  information, sets the file status for SF to Not_A_Legal_Source and
   --  decreases the counter of the sources which have to be processed
   --  (Sources_Left)
   --  If Compiler_Out is a name of an existing file, this file is used
   --  to redirect the compiler output into. Otherwise the compiler output is
   --  sent to Stderr

   procedure Output_Source (SF : SF_Id);
   --  Depending on the options set generates the trace of the units/sources
   --  processing. If Verbose_Mode is ON, outputs into Stderr the number of the
   --  units left and the name of the source being processed. Otherwise, if
   --  Quiet_Mode is OFF, outputs only the number of units left. If
   --  Progress_Indicator_Mode is ON, generates the output to be used for GPS
   --  progress indicator. (Unconditionally) decreases the counter of the
   --  sources which have to be processed (Sources_Left)

   procedure Source_Clean_Up (SF : SF_Id);
   --  Minimal clean-up needed for one source (closing and dissociating the
   --  Context, removing the tree and ALI files created for this source in
   --  the temporary directory).

   ----------------------------------------
   -- Source file access/update routines --
   ----------------------------------------

   function Source_Name (SF : SF_Id) return String;
   --  If ASIS_UL.Common.Use_Project_File is set OFF, this function returns
   --  the full source file name in absolute normalized form, otherwise it
   --  result is the same as returned by Short_Source_Name for the same
   --  argument.

   function Short_Source_Name (SF : SF_Id) return String;
   --  Short file name with no directory information

   function Suffixless_Name   (SF : SF_Id) return String;
   --  Returns the file name with no directory information and with
   --  no suffix (if any). Can be used to create the name of the tree and
   --  ALI file that correspond to SF.

   function  Source_Status     (SF : SF_Id) return SF_Status;
   procedure Set_Source_Status (SF : SF_Id; S : SF_Status);
   --  Queries and updates the source status.

   function  Source_Info     (SF : SF_Id) return SF_Info;
   procedure Set_Source_Info (SF : SF_Id; Info : SF_Info);
   --  Queries and updates the source Info value. The use of this value is up
   --  to the client of the source file table. You can store some integer-coded
   --  information or you can use this value as an index value in some other
   --  structure.

   procedure Source_Table_Debug_Image;
   --  Prints into Stdout the debug image of the current state of source table

   ----------------------
   -- Problem counters --
   ----------------------

   Illegal_Sources   : Natural := 0;
   Out_File_Problems : Natural := 0;

end ASIS_UL.Source_Table;
