-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset 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. The SPARK toolset 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 the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

with E_Strings;
with ExaminerConstants;

--# inherit ExaminerConstants,
--#         E_Strings,
--#         FileSystem,
--#         SPARK_IO,
--#         Version,
--#         XMLReport;

package CommandLineData
--# own Content : Command_Line_Contents;
is
   Meta_File_Extension       : constant String := "smf";
   Default_Index_Extension   : constant String := "idx";
   Default_Warning_Extension : constant String := "wrn";
   Default_Data_Extension    : constant String := "dat";
   Default_Config_Extension  : constant String := "cfg";

   type Source_File_Entry is record
      Source_File_Name  : E_Strings.T;
      Listing           : Boolean;
      Listing_File_Name : E_Strings.T;
   end record;

   subtype Source_File_Counts is Integer range 0 .. ExaminerConstants.MaxFilesOnCommandLine;
   subtype Source_File_Positions is Integer range 0 .. ExaminerConstants.MaxFilesOnCommandLine;
   type Source_File_Lists is array (Source_File_Positions) of Source_File_Entry;

   ---------------------------------------------------------------------
   -- To Add a new debug flag:
   --
   -- 1. Add a Boolean field to this record, and supply an initial value
   --    for it in the body of CommandLineData.Initialize, and add a
   --    constant Option_Debug_XXX below for the new option.
   --
   -- 2. Update CommandLineHandler.Parse_Command_Options.Process_D to
   --    recognize and set the new flag.
   --
   -- 3. Document the new flag in the Examiner's help output in
   --    examiner.adb
   --
   -- 4. Document the new flag in the Examiner User Manual
   --
   -- 5. Test and use the flag to produce the output required
   ---------------------------------------------------------------------
   type Debug_State is record
      Enabled      : Boolean;  -- any -debug flag is enabled.
      Expressions  : Boolean;  -- -debug=e - expression walk debugging
      HTML         : Boolean;  -- -debug=h - HTML generation debugging
      Lookup_Trace : Boolean;  -- -debug=l - Dictionary look up call tracing
      File_Names   : Boolean;  -- -debug=f - Trace filename storage/open/create
      Units        : Boolean;  -- -debug=u - Trace required units and index lookup
      Invariants   : Boolean;  -- -debug=i - Print default loop invariants
      Components   : Boolean;  -- -debug=c - print state of component manager when adding subcomponents
      Rho          : Boolean;  -- -debug=r - Print computed Rho relation for subprograms
      Parser       : Boolean;  -- -debug=p - Print parser state on detection of syntax error
      FDL_Ranking  : Boolean;  -- -debug=k - trace ranking and printing of FDL declarations
      VCG          : Boolean;  -- -debug=v - print VCG state after DAG.BuildGraph
      VCG_All      : Boolean;  -- -debug=V - as VCG, but also print VCG state during each iteration of Graph.GenVCs
      DAG          : Boolean;  -- -debug=d - print FDL DAG following BuildExpnDAG
      SLI          : Boolean;  -- -debug=x - Print cross-reference debug
      Extra_Stats  : Boolean;  -- -debug=t - Print extra detail when -statistics is on
   end record;

   type Concurrency_Profiles is (Sequential, Ravenscar);

   type Language_Profiles is (SPARK83, SPARK95, SPARK2005, KCG);

   -- Useful subtypes of language profiles
   subtype SPARK95_Onwards is Language_Profiles range SPARK95 .. Language_Profiles'Last;
   -- KCG profile is identical to SPARK2005 profile except for accept statements.
   subtype SPARK2005_Profiles is Language_Profiles range SPARK2005 .. KCG;
   subtype Auto_Code_Generators is Language_Profiles range KCG .. KCG;

   type Info_Flow_Policies is (None, Safety, Security);

   -- A subtype of the above excluding "None"
   subtype Defined_Info_Flow_Policies is Info_Flow_Policies range Safety .. Info_Flow_Policies'Last;

   type Justification_Options is (Ignore, Full, Brief);

   type Brief_Options is (No_Path, Full_Path);

   type Flow_Analysis_Options is (Data_Flow, Info_Flow, Auto_Flow);

   -------------------------------------------------------------------------------------
   -- Proof rule generation policies for composite constants.  If this type
   -- changes, then the error message in CommandLineHandler.OutputError must be updated.
   --
   -- Whether a proof rule gets generated or not for a particular constant depends on
   -- the seeting of this switch, and the presence (or absence) of an object_assertion
   -- annotation for that constant.
   --
   -- The policies are as follows:
   --   No_Rules  - NEVER  generate composite proof rules, regardless of annotations
   --   All_Rules - ALWAYS generate composite proof rules, regardless of annotations
   --   Lazy      - Generate rules for constants where an annotation requests it.
   --               If no annotation is given then no rule is generated.
   --   Keen      - Generate rules for constants where an annotation requests it.
   --               If no annotation is given then a rule IS generated.
   -------------------------------------------------------------------------------------
   type Rule_Generation_Policies is (No_Rules, Lazy, Keen, All_Rules);

   type Error_Explanations is (Off, First_Occurrence, Every_Occurrence);

   type Command_Line_Contents is record
      Valid : Boolean;

      Index           : Boolean;
      Index_File_Name : E_Strings.T;

      Warning           : Boolean;
      Warning_File_Name : E_Strings.T;

      Target_Data      : Boolean;
      Target_Data_File : E_Strings.T;

      Target_Config      : Boolean;
      Target_Config_File : E_Strings.T;

      Source_Extension : E_Strings.T;
      Number_Source    : Source_File_Counts;
      Source_File_List : Source_File_Lists;

      Listing_Extension : E_Strings.T;
      No_Listings       : Boolean;

      Report           : Boolean;
      Report_File_Name : E_Strings.T;

      Write_Dict     : Boolean;
      Dict_File_Name : E_Strings.T;

      FDL_Reserved : Boolean;
      FDL_Mangle   : E_Strings.T;

      HTML           : Boolean;
      HTML_Directory : E_Strings.T;

      Output_Directory      : Boolean;
      Output_Directory_Name : E_Strings.T;

      VCG : Boolean; -- Generate Verification Conditions
      DPC : Boolean; -- Generate Dead-Path Conjectures

      Anno_Char : Character;

      Concurrency_Profile : Concurrency_Profiles;
      Language_Profile    : Language_Profiles;

      Info_Flow_Policy     : Info_Flow_Policies;
      Constant_Rules       : Rule_Generation_Policies;
      Error_Explanation    : Error_Explanations;
      Justification_Option : Justification_Options;
      Debug                : Debug_State;

      Echo                : Boolean;
      Makefile_Mode       : Boolean;
      Syntax_Only         : Boolean;
      Write_Statistics    : Boolean;
      Flow_Option         : Flow_Analysis_Options;
      Default_Switch_File : Boolean;
      Plain_Output        : Boolean;
      Version_Requested   : Boolean;
      Help_Requested      : Boolean;
      VC_Finger_Prints    : Boolean;
      No_Duration         : Boolean;
      Brief               : Boolean;
      Brief_Option        : Brief_Options;
      XML                 : Boolean;
      Legacy_Errors       : Boolean;
      Generate_SLI        : Boolean;

      Casing_Standard   : Boolean;
      Casing_Identifier : Boolean;

      SPARK_Lib : Boolean;

      Distribution_Is_Pro : Boolean;
      GPL_Switch          : Boolean;
   end record;

   --  Keep this sorted. In emacs M-x sort-lines may be useful.
   Option_Annotation_Character                : constant String    := "annotation_character";
   Option_Brief                               : constant String    := "brief";
   Option_Brief_Full_Path                     : constant String    := "fullpath";
   Option_Brief_No_Path                       : constant String    := "nopath";
   Option_Casing                              : constant String    := "casing";
   Option_Casing_Identifier                   : constant Character := 'i';
   Option_Casing_Standard                     : constant Character := 's';
   Option_Config_File                         : constant String    := "config_file";
   Option_Debug                               : constant String    := "debug";
   Option_Debug_C                             : constant Character := 'c';
   Option_Debug_D                             : constant Character := 'd';
   Option_Debug_E                             : constant Character := 'e';
   Option_Debug_F                             : constant Character := 'f';
   Option_Debug_H                             : constant Character := 'h';
   Option_Debug_I                             : constant Character := 'i';
   Option_Debug_K                             : constant Character := 'k';
   Option_Debug_L                             : constant Character := 'l';
   Option_Debug_P                             : constant Character := 'p';
   Option_Debug_R                             : constant Character := 'r';
   Option_Debug_T                             : constant Character := 't';
   Option_Debug_U                             : constant Character := 'u';
   Option_Debug_V                             : constant Character := 'v';
   Option_Debug_V_Upper                       : constant Character := 'V';
   Option_Debug_X                             : constant Character := 'x';
   Option_Dictionary_File                     : constant String    := "dictionary_file";
   Option_Dpc                                 : constant String    := "dpc";
   Option_Error_Explanations                  : constant String    := "error_explanations";
   Option_Error_Explanations_Every_Occurrence : constant String    := "every_occurrence";
   Option_Error_Explanations_First_Occurrence : constant String    := "first_occurrence";
   Option_Error_Explanations_Off              : constant String    := "off";
   Option_Fdl_Identifiers                     : constant String    := "fdl_identifiers";
   Option_Fdl_Identifiers_Accept              : constant String    := "accept";
   Option_Fdl_Identifiers_Reject              : constant String    := "reject";
   Option_Flow_Analysis                       : constant String    := "flow_analysis";
   Option_Flow_Analysis_Auto                  : constant String    := "auto";
   Option_Flow_Analysis_Data                  : constant String    := "data";
   Option_Flow_Analysis_Information           : constant String    := "information";
   Option_GPL                                 : constant String    := "gpl";
   Option_Help                                : constant String    := "help";
   Option_Html                                : constant String    := "html";
   Option_Index_File                          : constant String    := "index_file";
   Option_Justification_Option                : constant String    := "justification_option";
   Option_Justification_Option_Brief          : constant String    := "brief";
   Option_Justification_Option_Full           : constant String    := "full";
   Option_Justification_Option_Ignore         : constant String    := "ignore";
   Option_Language                            : constant String    := "language";
   Option_Language_2005                       : constant String    := "2005";
   Option_Language_83                         : constant String    := "83";
   Option_Language_95                         : constant String    := "95";
   Option_Language_KCG                        : constant String    := "KCG";
   Option_Listing_Extension                   : constant String    := "listing_extension";
   Option_Listing_File                        : constant String    := "listing_file";
   Option_Makefile_Mode                       : constant String    := "makefile";
   Option_No_Dictionary                       : constant String    := "nodictionary";
   Option_No_Duration                         : constant String    := "noduration";
   Option_No_Echo                             : constant String    := "noecho";
   Option_No_Listing_File                     : constant String    := "nolisting_file";
   Option_No_Listings                         : constant String    := "nolistings";
   Option_No_Sli                              : constant String    := "nosli";
   Option_No_Switch                           : constant String    := "noswitch";
   Option_Original_Flow_Errors                : constant String    := "original_flow_errors";
   Option_Output_Directory                    : constant String    := "output_directory";
   Option_Plain_Output                        : constant String    := "plain_output";
   Option_Policy                              : constant String    := "policy";
   Option_Policy_Safety                       : constant String    := "safety";
   Option_Policy_Security                     : constant String    := "security";
   Option_Profile                             : constant String    := "profile";
   Option_Profile_Ravenscar                   : constant String    := "ravenscar";
   Option_Profile_Sequential                  : constant String    := "sequential";
   Option_Report_File                         : constant String    := "report_file";
   Option_Rules                               : constant String    := "rules";
   Option_Rules_All                           : constant String    := "all";
   Option_Rules_Keen                          : constant String    := "keen";
   Option_Rules_Lazy                          : constant String    := "lazy";
   Option_Rules_None                          : constant String    := "none";
   Option_SPARK_Lib                           : constant String    := "sparklib";
   Option_Source_Extension                    : constant String    := "source_extension";
   Option_Statistics                          : constant String    := "statistics";
   Option_Syntax_Check                        : constant String    := "syntax_check";
   Option_Target_Compiler_Data                : constant String    := "target_compiler_data";
   Option_Vcg                                 : constant String    := "vcg";
   Option_Version                             : constant String    := "version";
   Option_Warning_File                        : constant String    := "warning_file";
   Option_Xml                                 : constant String    := "xml";

   Content : Command_Line_Contents;

   procedure Initialize;
   --# global out Content;
   --# derives Content from ;

   -- If Content.Output_Directory is set, then interpret and return F relative
   -- to the specified output directory
   procedure Normalize_File_Name_To_Output_Directory (F : in out E_Strings.T);
   --# global in Content;
   --# derives F from *,
   --#                Content;

   -- Echoes the various filenames in Content to the terminal,
   -- iff Content.Debug.File_Names has been selected.
   procedure Dump_File_Names;
   --# global in Content;
   --# derives null from Content;

   procedure Output_Command_Line (Prefix     : in     String;
                                  XML        : in     Boolean;
                                  Option_Str :    out E_Strings.T);
   --# global in     Content;
   --#        in     SPARK_IO.File_Sys;
   --#        in out XMLReport.State;
   --# derives Option_Str      from Content,
   --#                              Prefix,
   --#                              SPARK_IO.File_Sys,
   --#                              XML,
   --#                              XMLReport.State &
   --#         XMLReport.State from *,
   --#                              Content,
   --#                              XML;

   function Ravenscar_Selected return Boolean;
   --# global in Content;

end CommandLineData;
