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

pragma Ada_2012;

--  This package provides simple utilities and data structures for processing
--  and storing the ASIS tool arguments that have to be passed to the compiler
--  when the compiler is called to create the tree file for ASIS

with GNAT.Command_Line; use GNAT.Command_Line;
with GNAT.OS_Lib;       use GNAT.OS_Lib;

package ASIS_UL.Compiler_Options is

   --  To use the resources provided by this package, the tool is supposed to
   --  use the following way of parameter processing and creating the trees
   --  for ASIS:
   --
   --  ..._Environment.Initialize.Scan_Parameters should contain the following
   --  sequence of statements (provided that GNAT.Command_Line is used):
   --
   --       Initialize_Option_Scan
   --        (Stop_At_First_Non_Switch => False,
   --         Section_Delimiters       => "cargs");
   --      loop
   --         case
   --            GNAT.Command_Line.Getopt
   --              (<tool-specific options, may include compiler options>)
   --         is
   --            ...
   --            when 'I' | 'g' =>
   --               if Full_Switch = "gnatec" then
   --                  Store_gnatec_Option (Parameter);
   --               elsif Full_Switch = "I"
   --                  Store_I_Option (Parameter);
   --               ...
   --               end if;
   --            ...
   --         end case;
   --      end loop;
   --
   --      ...
   --
   --      Read_Tool_Arguments; -- Any procedure or operator sequence that
   --                           --  reads tool argument(s)
   --
   --      ...
   --
   --      Process_cargs_Section;
   --
   --  Calls to Asis.Extensions.Compile should use
   --  ASIS_UL.Compiler_Options.Arg_List as an actual for Args parameter.
   --
   --  The call to Initialize_Option_Scan may define other option sections,
   --  if so, the processing for these sections should be provided along with
   --  the call to Process_cargs_Section.

   Arg_List : Argument_List_Access;
   --  This variable should contain a full list of compilation options to be
   --  passed to gcc when gcc is called from the tool to create the tree for
   --  ASIS. This list does not have to contain the following options
   --  '-c -gnatc -gnatt -gnatws -x ada', they are always set by the
   --  Asis.Extensions.Compile routine. The options that are supposed to be
   --  represented by this variable include Ada version option, reference
   --  to configuration file etc. Note, that this list should NOT contain -Idir
   --  options, all these options are supposed to be converted to the
   --  corresponding directory names included in the file pointed by the
   --  ADA_PRJ_INCLUDE_FILE environment variable. But '-I-' option can be in
   --  this list.
   --
   --  Note that you should NOT call the Free procedure for this variable,
   --  because if this variable is set, Free will erase all the compiler
   --  options being stored in its value.

   Source_Search_Path : String_Access;
   --  This variable should contain a path (in the format suitable for passing
   --  to Locate_Regular_File procedure) to look for the source files specified
   --  as tool arguments or searched as sources that are needed by the tool to
   --  complete the processing.

   procedure Add_To_Source_Search_Path (Dir : String);
   --   Appends Dir to Source_Search_Path

   Custom_RTS : String_Access;
   --  If --RTS option is specified, contains the parameter of this option

   ADA_PRJ_INCLUDE_FILE_Full_Name : String_Access;
   --  Is supposed to contain the full normalized name of the file pointed by
   --  the ADA_PRJ_INCLUDE_FILE environment variable

   Need_Tmp_ADA_PRJ_INCLUDE_FILE : Boolean := False;
   --  This flag is set ON by Process_ADA_PRJ_INCLUDE_FILE procedure if it
   --  detects that there is no existing file pointed by the value of
   --  ADA_PRJ_INCLUDE_FILE environment variable. If it is ON, this means that
   --  a new file should be created if I_Options_Specified is ON and we have to
   --  put the corresponding directories in the file.

   I_Options_Specified : Boolean := False;
   --  If this flag is ON this means that '-Idir' options have been specified
   --  as tool arguments, so the corresponding directories should be added
   --  in the file pointed by the ADA_PRJ_INCLUDE_FILE environment variable

   procedure Store_Path_Option
     (Switch : String;
      Path   : String);
   --  Stores the switch that contains a path as a parameter. A switch can be
   --  any switch other than -I and -gnatec. (For these options two specific
   --  procedures - Store_I_Option and Store_gnatec_Option should be used
   --  respectively. A path is converted into absolute normalized form. The
   --  actual for Switch should represent the needed switch in the form that
   --  allows to get the right form of the switch by concatenating the path.
   --  ???No such thing as Store_gnatec_Option.

   procedure Store_I_Option (Path : String);
   --  Similar to Store_Path_Option, but takes into account -I- option as well.
   --  In case if -I- it is stored as is, because if "-" is passed as a
   --  parameter of path normalization, the result is an empty string.

   procedure Store_GNAT_Option_With_Path (Option : String; Path : String);
   --  Similar to Store_Path_Option, but takes into account that for the
   --  Option the path parameter may or may not be separated by the space
   --  character or '='

   procedure Store_Option (Switch : String);
   --  Stores the option as is.

   procedure Set_Arg_List;
   --  Assigns the value to Arg_List variable.
   --
   --  Note, that '-I' options are NOT placed to Arg_List, because it may
   --  result in a very long list that may exceed command line length
   --  limitation on some platforms, in particular on Windows. Instead, each
   --  directory that is an argument of '-Idir' option is added to the file
   --  pointed by ADA_PRJ_INCLUDE_FILE environment variable.

   procedure PAL;
   --  Print_Arg_List. Print out the content of the Arg_List variable, to be
   --  used for debugging purposes.

   Add_I_Options_To_Source_Search_Path : Boolean := False;
   --  If this flag is ON, -I options that are explicitly specified for the
   --  tool are added to the value of Source_Search_Path. This is up to the
   --  tool to set this flag ON

   procedure Store_I_Options;
   --  This is supposed to be the last procedure called to process and to store
   --  compiler options. If '-Idir' options are specified, it either adds them
   --  in the beginning of the file pointed by the ADA_PRJ_INCLUDE_FILE
   --  environment variable or, if this variable does not point to any
   --  existing file, creates a temporary file, stores the (normalized)
   --  directory names provided as parameters of '-Idir' in this file and sets
   --  it as the value of ADA_PRJ_INCLUDE_FILE environment variable. This
   --  procedure also generates the debug info containing the source search
   --  path and the content of ADA_PRJ_INCLUDE_FILE file.

   procedure Process_cargs_Section
     (Parser           : Opt_Parser := Command_Line_Parser;
      No_Preprocessing : Boolean    := False);
   --  Implements the processing of all the options in -cargs section. Note
   --  that this procedure does NOT call Initialize_Option_Scan to define
   --  'cargs' section. The actual for Parser parameter should be the option
   --  parser created by the appropriate call to Initialize_Option_Scan.
   --  If No_Preprocessing is set ON, then this procedure raises
   --  Parameter_Error with the corresponding error message for the
   --  preprocessor options ('-gnatep', '-gnateD'). This prevents a tool
   --  from calling the preprocessor for an argument source before processing
   --  the source.
   --  If -cargs section contains '-gnata' option, this option is just skipped.
   --  '-gnata' should not be passed to the compiler call that creates the tree
   --  because it may cause tree transformations that are not good for ASIS.

   procedure Process_ADA_PRJ_INCLUDE_FILE;
   --  If ADA_PRJ_INCLUDE_FILE points to an existing file, scans this file
   --  and stores the directories listed in it as source search path for the
   --  tool argument files.

   ---------------------------------
   -- Source search path iterator --
   ---------------------------------

   --  This iterator allows to go through the source search path set by
   --  '-I' options.

   --  This iterator is NOT used at the moment. If some tool decides to use it,
   --  the implementation shall be revised!!!

   procedure Reset_Search_Path_Iterator;
   --  Resets the iterator into initial state

   function No_More_Source_Dir return Boolean;
   --  Checks if there are more source dir(s) to iterate through. As a side
   --  effect, makes the iterator prepared to return the next source dir

   function Next_Source_Dir return String;
   --  Returns the (full normalized) name of the next source dir. Should be
   --  called after the call to No_More_Source_Dir

   --  The correct way of using this iterator is:

   --  Reset_Search_Path_Iterator;
   --
   --  while not No_More_Source_Dir loop
   --     Do_Something_With (Next_Source_Dir);
   --  end loop;

end ASIS_UL.Compiler_Options;
