-------------------------------------------------------------------------------
-- (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 Ada.Command_Line;
with Ada.Exceptions;
with CommandLineData;
with CommandLineHandler;
with Dictionary;
with ErrorHandler;
with Fatal;
with File_Utils;
with GNAT.Traceback.Symbolic;
with LexTokenManager;
with MainLoop;
with ScreenEcho;
with SPARK_IO;
with Statistics;
with STree;
with Version;

--# inherit CommandLineData,
--#         CommandLineHandler,
--#         ConfigFile,
--#         ContextManager,
--#         ContextManager.Ops,
--#         Declarations,
--#         Dictionary,
--#         ErrorHandler,
--#         File_Utils,
--#         Graph,
--#         IndexManager,
--#         LexTokenManager,
--#         MainLoop,
--#         ScreenEcho,
--#         Sem,
--#         SLI,
--#         SparkHTML,
--#         SparkLex,
--#         SPARK_IO,
--#         Statistics,
--#         StmtStack,
--#         STree,
--#         VCG,
--#         Version,
--#         XMLReport;

--# main_program

procedure Examiner
--# global in out ConfigFile.State;
--#        in out ContextManager.Ops.File_Heap;
--#        in out ContextManager.Ops.Unit_Heap;
--#        in out ContextManager.Ops.Unit_Stack;
--#        in out Declarations.State;
--#        in out ErrorHandler.Error_Context;
--#        in out Graph.Table;
--#        in out IndexManager.State;
--#        in out LexTokenManager.State;
--#        in out SLI.State;
--#        in out SparkHTML.Generate_HTML;
--#        in out SPARK_IO.File_Sys;
--#        in out Statistics.TableUsage;
--#        in out StmtStack.S;
--#        in out STree.Table;
--#        in out VCG.Invoked;
--#           out CommandLineData.Content;
--#           out Dictionary.Dict;
--#           out Sem.State;
--#           out SparkHTML.HTML_Work_Dir;
--#           out SparkHTML.SPARK_Work_Dir;
--#           out SparkLex.Curr_Line;
--#           out XMLReport.State;
--# derives CommandLineData.Content,
--#         Sem.State,
--#         SparkLex.Curr_Line,
--#         XMLReport.State               from ContextManager.Ops.File_Heap,
--#                                            ContextManager.Ops.Unit_Heap,
--#                                            ContextManager.Ops.Unit_Stack,
--#                                            ErrorHandler.Error_Context,
--#                                            IndexManager.State,
--#                                            LexTokenManager.State,
--#                                            SLI.State,
--#                                            SparkHTML.Generate_HTML,
--#                                            SPARK_IO.File_Sys,
--#                                            STree.Table &
--#         ConfigFile.State              from *,
--#                                            ErrorHandler.Error_Context,
--#                                            LexTokenManager.State,
--#                                            SPARK_IO.File_Sys &
--#         ContextManager.Ops.File_Heap,
--#         ContextManager.Ops.Unit_Heap,
--#         ContextManager.Ops.Unit_Stack,
--#         Declarations.State,
--#         ErrorHandler.Error_Context,
--#         Graph.Table,
--#         IndexManager.State,
--#         LexTokenManager.State,
--#         SLI.State,
--#         Statistics.TableUsage,
--#         StmtStack.S,
--#         STree.Table,
--#         VCG.Invoked                   from *,
--#                                            ContextManager.Ops.File_Heap,
--#                                            ContextManager.Ops.Unit_Heap,
--#                                            ContextManager.Ops.Unit_Stack,
--#                                            ErrorHandler.Error_Context,
--#                                            IndexManager.State,
--#                                            LexTokenManager.State,
--#                                            SLI.State,
--#                                            SparkHTML.Generate_HTML,
--#                                            SPARK_IO.File_Sys,
--#                                            STree.Table &
--#         Dictionary.Dict,
--#         SparkHTML.Generate_HTML       from ContextManager.Ops.File_Heap,
--#                                            ContextManager.Ops.Unit_Heap,
--#                                            ContextManager.Ops.Unit_Stack,
--#                                            ErrorHandler.Error_Context,
--#                                            IndexManager.State,
--#                                            LexTokenManager.State,
--#                                            SLI.State,
--#                                            SparkHTML.Generate_HTML,
--#                                            SPARK_IO.File_Sys,
--#                                            Statistics.TableUsage,
--#                                            STree.Table &
--#         SparkHTML.HTML_Work_Dir,
--#         SparkHTML.SPARK_Work_Dir      from LexTokenManager.State,
--#                                            SPARK_IO.File_Sys &
--#         SPARK_IO.File_Sys             from *,
--#                                            ContextManager.Ops.File_Heap,
--#                                            ContextManager.Ops.Unit_Heap,
--#                                            ContextManager.Ops.Unit_Stack,
--#                                            ErrorHandler.Error_Context,
--#                                            IndexManager.State,
--#                                            LexTokenManager.State,
--#                                            SLI.State,
--#                                            SparkHTML.Generate_HTML,
--#                                            Statistics.TableUsage,
--#                                            STree.Table,
--#                                            VCG.Invoked;
is
   procedure Set_Exit_Status (Code : in ErrorHandler.Exit_Code)
   --# derives null from Code;
   is
      --# hide Set_Exit_Status;
   begin
      Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Exit_Status (Code));
   end Set_Exit_Status;

   procedure Execute
   --# global in out CommandLineData.Content;
   --#        in out ConfigFile.State;
   --#        in out ContextManager.Ops.File_Heap;
   --#        in out ContextManager.Ops.Unit_Heap;
   --#        in out ContextManager.Ops.Unit_Stack;
   --#        in out Declarations.State;
   --#        in out ErrorHandler.Error_Context;
   --#        in out Graph.Table;
   --#        in out IndexManager.State;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SparkHTML.Generate_HTML;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out StmtStack.S;
   --#        in out STree.Table;
   --#        in out VCG.Invoked;
   --#           out Dictionary.Dict;
   --#           out Sem.State;
   --#           out SparkHTML.HTML_Work_Dir;
   --#           out SparkHTML.SPARK_Work_Dir;
   --#           out SparkLex.Curr_Line;
   --#           out XMLReport.State;
   --# derives CommandLineData.Content,
   --#         ContextManager.Ops.File_Heap,
   --#         ContextManager.Ops.Unit_Heap,
   --#         ContextManager.Ops.Unit_Stack,
   --#         Declarations.State,
   --#         ErrorHandler.Error_Context,
   --#         Graph.Table,
   --#         IndexManager.State,
   --#         LexTokenManager.State,
   --#         SLI.State,
   --#         Statistics.TableUsage,
   --#         StmtStack.S,
   --#         STree.Table,
   --#         VCG.Invoked                   from *,
   --#                                            CommandLineData.Content,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SLI.State,
   --#                                            SparkHTML.Generate_HTML,
   --#                                            SPARK_IO.File_Sys,
   --#                                            STree.Table &
   --#         ConfigFile.State              from *,
   --#                                            CommandLineData.Content,
   --#                                            ErrorHandler.Error_Context,
   --#                                            LexTokenManager.State,
   --#                                            SPARK_IO.File_Sys &
   --#         Dictionary.Dict,
   --#         SparkHTML.Generate_HTML       from CommandLineData.Content,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SLI.State,
   --#                                            SparkHTML.Generate_HTML,
   --#                                            SPARK_IO.File_Sys,
   --#                                            Statistics.TableUsage,
   --#                                            STree.Table &
   --#         Sem.State,
   --#         SparkLex.Curr_Line,
   --#         XMLReport.State               from CommandLineData.Content,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SLI.State,
   --#                                            SparkHTML.Generate_HTML,
   --#                                            SPARK_IO.File_Sys,
   --#                                            STree.Table &
   --#         SparkHTML.HTML_Work_Dir,
   --#         SparkHTML.SPARK_Work_Dir      from CommandLineData.Content,
   --#                                            LexTokenManager.State,
   --#                                            SPARK_IO.File_Sys &
   --#         SPARK_IO.File_Sys             from *,
   --#                                            CommandLineData.Content,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SLI.State,
   --#                                            SparkHTML.Generate_HTML,
   --#                                            Statistics.TableUsage,
   --#                                            STree.Table,
   --#                                            VCG.Invoked;
   is

      procedure Star_Line
      --# global in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *;
      is
      begin
         ScreenEcho.Put_Line ("*****************************************************************************");
      end Star_Line;

      procedure Support_Details
      --# global in     CommandLineData.Content;
      --#        in out SPARK_IO.File_Sys;
      --# derives SPARK_IO.File_Sys from *,
      --#                                CommandLineData.Content;
      is
      begin
         -- Suppress support details when in plain mode to avoid
         -- spurious diff when testing non SPARK Pro builds
         if CommandLineData.Content.Plain_Output then
            ScreenEcho.Put_Line ("* Support details - Suppressed in plain mode");
         else
            ScreenEcho.Put_Line ("*");
            ScreenEcho.Put_Line ("* " & Version.Toolset_Support_Line1);
            ScreenEcho.Put_Line ("* " & Version.Toolset_Support_Line2);
            ScreenEcho.Put_Line ("* " & Version.Toolset_Support_Line3);
            ScreenEcho.Put_Line ("* " & Version.Toolset_Support_Line4);
         end if;
      end Support_Details;

   begin -- Execute
      if CommandLineData.Content.Valid then
         MainLoop.Process_Files;
      end if;
      --# accept Flow, 602, Dictionary.Dict, Dictionary.Dict, "Defined before use in MainLoop" &
      --#        Flow, 602, Sem.State, Sem.State, "Defined before use in MainLoop" &
      --#        Flow, 602, SparkHTML.HTML_Work_Dir, SparkHTML.HTML_Work_Dir, "Defined before use in MainLoop" &
      --#        Flow, 602, SparkHTML.SPARK_Work_Dir, SparkHTML.SPARK_Work_Dir, "Defined before use in MainLoop" &
      --#        Flow, 602, SparkLex.Curr_Line, SparkLex.Curr_Line, "Defined before use in MainLoop" &
      --#        Flow, 602, XMLReport.State, XMLReport.State, "Defined before use in MainLoop";
   exception
      --# hide Execute;
      when Fatal.Static_Limit =>
         STree.ReportUsage;
         LexTokenManager.Report_Usage;
         Dictionary.ReportUsage;
         Statistics.WriteOutput (SPARK_IO.Standard_Output);
         Support_Details;
         Star_Line;
         raise;

      when Fatal.Operating_System_Limit | Fatal.Internal_Error =>
         Support_Details;
         Star_Line;
         raise;

      when Fatal.Index_Manager =>
         Star_Line;
         raise;

      when Storage_Error =>
         Star_Line;
         ScreenEcho.Put_Line ("* A storage_error has occurred.  You may have too small a system stack limit,");
         ScreenEcho.Put_Line ("* insufficient memory or too many other processes running.");
         Support_Details;
         Star_Line;
         raise;

      when others =>
         Star_Line;
         ScreenEcho.Put_Line ("* An unexpected internal error has occurred.");
         Support_Details;
         Star_Line;
         raise;

   end Execute;

   procedure Print_Help
   --# global in     CommandLineData.Content;
   --#        in out SPARK_IO.File_Sys;
   --# derives SPARK_IO.File_Sys from *,
   --#                                CommandLineData.Content;
   is
      subtype Option_String_Range is Positive range 1 .. 1;
      subtype Option_String_T is String (Option_String_Range);
      Option_String_Casing_Standard   : constant Option_String_T :=
        Option_String_T'(others => CommandLineData.Option_Casing_Standard);
      Option_String_Casing_Identifier : constant Option_String_T :=
        Option_String_T'(others => CommandLineData.Option_Casing_Identifier);
      Option_String_Debug_C           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_C);
      Option_String_Debug_D           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_D);
      Option_String_Debug_E           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_E);
      Option_String_Debug_F           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_F);
      Option_String_Debug_H           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_H);
      Option_String_Debug_I           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_I);
      Option_String_Debug_K           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_K);
      Option_String_Debug_L           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_L);
      Option_String_Debug_P           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_P);
      Option_String_Debug_R           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_R);
      Option_String_Debug_T           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_T);
      Option_String_Debug_U           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_U);
      Option_String_Debug_V           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_V);
      Option_String_Debug_V_Upper     : constant Option_String_T :=
        Option_String_T'(others => CommandLineData.Option_Debug_V_Upper);
      Option_String_Debug_X           : constant Option_String_T := Option_String_T'(others => CommandLineData.Option_Debug_X);
   begin
      ScreenEcho.Put_Line ("Usage: spark {options} Argument-list");
      ScreenEcho.Put_Line ("Argument-list = Argument {"" "" Argument }");
      ScreenEcho.Put_Line ("Argument = ( File-spec [Argument-option] ) | Meta-file-spec");
      ScreenEcho.Put_Line
        ("Argument-option = ( ""-" &
           CommandLineData.Option_Listing_File &
           "="" file-spec | ""-" &
           CommandLineData.Option_No_Listing_File &
           """ )");
      ScreenEcho.Put_Line ("Meta-file-spec = ""@""file-spec");

      ScreenEcho.New_Line (1);
      ScreenEcho.Put_Line ("Options - all may be abbreviated to the shortest unique prefix");
      ScreenEcho.New_Line (1);
      ScreenEcho.Put_Line ("Input File Options");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Source_Extension & "=file-type - specifies source file extension (Default .ada)");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Index_File & "=file-spec       - specifies index file");
      ScreenEcho.Put_Line ("-no" & CommandLineData.Option_Index_File & "               - suppress index file (Default)");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Warning_File & "=file-spec     - specifies warning control file");
      ScreenEcho.Put_Line ("-no" & CommandLineData.Option_Warning_File & "             - all warnings reported (Default)");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Target_Compiler_Data & "=file-spec - specifies target compiler data");
      ScreenEcho.Put_Line ("                                  This option is now deprecated by -config_file");
      ScreenEcho.Put_Line
        ("-no" & CommandLineData.Option_Target_Compiler_Data & "         - suppress target compiler data (Default)");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Config_File & "=file-spec          - specifies Examiner configuration file");
      ScreenEcho.Put_Line
        ("-no" & CommandLineData.Option_Config_File & "                  - suppress configuration file (Default)");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_No_Switch & "                       - ignore spark.sw file");
      ScreenEcho.New_Line (1);
      ScreenEcho.Put_Line ("Output File Options");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Listing_Extension & "=file-type - specifies listing file extension (Default .lst)");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Report_File & "=file-spec       - specifies report file name (default SPARK.REP)");
      ScreenEcho.Put_Line ("-no" & CommandLineData.Option_Report_File & "               - suppress report file");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Html & "[=dir_spec]             - Generate HTML listings and report file");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Output_Directory & "=dir_spec   - Generate report, listing, and proof files");
      ScreenEcho.Put_Line ("                               in specified directory");
      ScreenEcho.Put_Line ("                               Default is in and below current working directory");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_No_Listings & "                  - suppress all listing files");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Plain_Output & "                - No dates, line, or error numbers in output files");
      ScreenEcho.New_Line (1);
      ScreenEcho.Put_Line ("Language and Analysis Options");
      ScreenEcho.Put_String
        ("-" &
           CommandLineData.Option_Language &
           "=choice    - select " &
           CommandLineData.Option_Language_83 &
           ", " &
           CommandLineData.Option_Language_95);
      if CommandLineData.Content.Distribution_Is_Pro then
         ScreenEcho.Put_Line
           (", " & CommandLineData.Option_Language_2005 & ", or " & CommandLineData.Option_Language_KCG & " language rules.");
         ScreenEcho.Put_Line
           ("                      " & CommandLineData.Option_Language_KCG & " rules are only used with SCADE KCG.");
      else
         ScreenEcho.Put_Line (", or " & CommandLineData.Option_Language_2005 & " language rules.");
      end if;

      ScreenEcho.Put_Line ("                      Default is " & CommandLineData.Option_Language_95);

      ScreenEcho.Put_Line
        ("-" &
           CommandLineData.Option_Profile &
           "=language   - select " &
           CommandLineData.Option_Profile_Sequential &
           " or " &
           CommandLineData.Option_Profile_Ravenscar &
           " language profile.");
      ScreenEcho.Put_Line ("                      Default is " & CommandLineData.Option_Profile_Sequential);
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_No_Duration & "         - do not predefine Standard.Duration");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Syntax_Check & "       - syntax check only.  No semantic checks");

      ScreenEcho.Put_Line
        ("-" &
           CommandLineData.Option_Flow_Analysis &
           "=type - select """ &
           CommandLineData.Option_Flow_Analysis_Information &
           """-, """ &
           CommandLineData.Option_Flow_Analysis_Data &
           """- or """ &
           CommandLineData.Option_Flow_Analysis_Auto &
           """-flow analysis");
      ScreenEcho.Put_Line ("                      Default is """ & CommandLineData.Option_Flow_Analysis_Information & """");

      ScreenEcho.Put_Line
        ("-" &
           CommandLineData.Option_Policy &
           "=type -  select """ &
           CommandLineData.Option_Policy_Security &
           """ or """ &
           CommandLineData.Option_Policy_Safety &
           """ policy for flow analysis");

      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Vcg & "          - Generate VCs");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Dpc & "          - Generate DPCs");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Rules & "=type   - Select policy for generation of composite constant proof rules");
      ScreenEcho.Put_Line
        ("              -  valid values: " &
           CommandLineData.Option_Rules_None &
           ", " &
           CommandLineData.Option_Rules_Lazy &
           ", " &
           CommandLineData.Option_Rules_Keen &
           ", " &
           CommandLineData.Option_Rules_All);
      ScreenEcho.Put_Line ("              -  default: " & CommandLineData.Option_Rules_Lazy);

      ScreenEcho.New_Line (1);
      ScreenEcho.Put_Line ("Debugging and Tracing Options");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Debug & "[=choices]           - choices is a sequence of letters, where:");
      ScreenEcho.Put_Line ("                             " & Option_String_Debug_C & " - trace component manager state");
      ScreenEcho.Put_Line ("                             " & Option_String_Debug_D & " - print FDL DAG after BuildExpnDAG");
      ScreenEcho.Put_Line ("                             " & Option_String_Debug_E & " - trace expression walking");
      ScreenEcho.Put_Line ("                             " & Option_String_Debug_F & " - trace file handling");
      ScreenEcho.Put_Line ("                             " & Option_String_Debug_H & " - trace HTML generation");
      ScreenEcho.Put_Line ("                             " & Option_String_Debug_I & " - print default loop invariants in FDL");
      ScreenEcho.Put_Line
        ("                             " & Option_String_Debug_K & " - trace ranking and printing of FDL declarations");
      ScreenEcho.Put_Line ("                             " & Option_String_Debug_L & " - trace entity lookup in dictionary");
      ScreenEcho.Put_Line ("                             " & Option_String_Debug_P & " - print parser state on syntax error");

      ScreenEcho.Put_Line
        ("                             " & Option_String_Debug_R & " - print required and computed flow relations");
      ScreenEcho.Put_Line ("                                 for each subprogram");
      ScreenEcho.Put_Line
        ("                             " & Option_String_Debug_T & " - print extra information when -statistics is on");
      ScreenEcho.Put_Line
        ("                             " & Option_String_Debug_U & " - trace required unit and index file lookups");
      ScreenEcho.Put_Line
        ("                             " & Option_String_Debug_V & " - print VCG State and BPG after DAG.BuildGraph");
      ScreenEcho.Put_Line
        ("                             " & Option_String_Debug_V_Upper & " - as v, but also print BPG during each iteration");
      ScreenEcho.Put_Line ("                                 of VC generation");
      ScreenEcho.Put_Line ("                             " & Option_String_Debug_X & " - print cross-reference");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Dictionary_File & "=file-spec - dump Dictionary into given file");
      ScreenEcho.New_Line (1);
      ScreenEcho.Put_Line ("Other Options");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Annotation_Character & "=char - select alternate annotation character (Default #)");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_No_Echo & "            - suppress screen output");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_No_Sli & "             - don't generate SLI files");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_SPARK_Lib & "          - use the standard SPARK library");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Statistics & "        - append Examiner table usage statistics to report file");
      ScreenEcho.Put_Line ("-no" & CommandLineData.Option_Statistics & "      - no statistics reported (Default)");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Fdl_Identifiers & "=option - Control treatment of FDL identifiers");
      ScreenEcho.Put_Line
        ("                          settings are """ & CommandLineData.Option_Fdl_Identifiers_Reject & """ (Default),");
      ScreenEcho.Put_Line ("                                       """ & CommandLineData.Option_Fdl_Identifiers_Accept & """ or");
      ScreenEcho.Put_Line ("                                       ""<string>""");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Version & "           - print Examiner banner, statistics, then exit");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Brief & "[=choices]   - errors and warnings in brief (gcc-style) format, where:");
      ScreenEcho.Put_Line ("                     " & CommandLineData.Option_Brief_No_Path & "       - omit path (Default)");
      ScreenEcho.Put_Line ("                     " & CommandLineData.Option_Brief_Full_Path & "     - report full path");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Makefile_Mode & "          - only absolutely essential output, useful when using");
      ScreenEcho.Put_Line ("                     the Examiner in a makefile (requires -" & CommandLineData.Option_Brief & ")");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Help & "              - print command line summary and options");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Original_Flow_Errors & "  - print information flow errors in original,");
      ScreenEcho.Put_Line ("                            less compact, format");
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Error_Explanations & "=setting - print explanations after error messages");
      ScreenEcho.Put_Line
        ("                              settings are """ &
           CommandLineData.Option_Error_Explanations_Off &
           """, """ &
           CommandLineData.Option_Error_Explanations_First_Occurrence &
           """");
      ScreenEcho.Put_Line
        ("                                                 or """ &
           CommandLineData.Option_Error_Explanations_Every_Occurrence &
           """");
      ScreenEcho.Put_Line ("                              default is """ & CommandLineData.Option_Error_Explanations_Off & """");
      ScreenEcho.Put_Line
        ("-" & CommandLineData.Option_Justification_Option & "=type - select policy for justification of errors");
      ScreenEcho.Put_Line
        ("                           -  values: " &
           CommandLineData.Option_Justification_Option_Full &
           ", " &
           CommandLineData.Option_Justification_Option_Brief &
           ", " &
           CommandLineData.Option_Justification_Option_Ignore);
      ScreenEcho.Put_Line ("                           -  default: " & CommandLineData.Option_Justification_Option_Full);
      ScreenEcho.Put_Line ("-" & CommandLineData.Option_Casing & "[=choices] - check casing for identifier references and");
      ScreenEcho.Put_Line ("                check casing of package Standard identifiers");
      ScreenEcho.Put_Line ("              - " & Option_String_Casing_Standard & " - check casing of package Standard identifiers");
      ScreenEcho.Put_Line ("              - " & Option_String_Casing_Identifier & " - check casing for identifier references");
      ScreenEcho.New_Line (1);
      ScreenEcho.Put_Line (Version.Toolset_Support_Line1);
      ScreenEcho.Put_Line (Version.Toolset_Support_Line2);
      ScreenEcho.Put_Line (Version.Toolset_Support_Line3);
      ScreenEcho.Put_Line (Version.Toolset_Support_Line4);
   end Print_Help;

   procedure MainProcedure
   --# global in out ConfigFile.State;
   --#        in out ContextManager.Ops.File_Heap;
   --#        in out ContextManager.Ops.Unit_Heap;
   --#        in out ContextManager.Ops.Unit_Stack;
   --#        in out Declarations.State;
   --#        in out ErrorHandler.Error_Context;
   --#        in out Graph.Table;
   --#        in out IndexManager.State;
   --#        in out LexTokenManager.State;
   --#        in out SLI.State;
   --#        in out SparkHTML.Generate_HTML;
   --#        in out SPARK_IO.File_Sys;
   --#        in out Statistics.TableUsage;
   --#        in out StmtStack.S;
   --#        in out STree.Table;
   --#        in out VCG.Invoked;
   --#           out CommandLineData.Content;
   --#           out Dictionary.Dict;
   --#           out Sem.State;
   --#           out SparkHTML.HTML_Work_Dir;
   --#           out SparkHTML.SPARK_Work_Dir;
   --#           out SparkLex.Curr_Line;
   --#           out XMLReport.State;
   --# derives CommandLineData.Content,
   --#         Sem.State,
   --#         SparkLex.Curr_Line,
   --#         XMLReport.State               from ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SLI.State,
   --#                                            SparkHTML.Generate_HTML,
   --#                                            SPARK_IO.File_Sys,
   --#                                            STree.Table &
   --#         ConfigFile.State              from *,
   --#                                            ErrorHandler.Error_Context,
   --#                                            LexTokenManager.State,
   --#                                            SPARK_IO.File_Sys &
   --#         ContextManager.Ops.File_Heap,
   --#         ContextManager.Ops.Unit_Heap,
   --#         ContextManager.Ops.Unit_Stack,
   --#         Declarations.State,
   --#         ErrorHandler.Error_Context,
   --#         Graph.Table,
   --#         IndexManager.State,
   --#         LexTokenManager.State,
   --#         SLI.State,
   --#         Statistics.TableUsage,
   --#         StmtStack.S,
   --#         STree.Table,
   --#         VCG.Invoked                   from *,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SLI.State,
   --#                                            SparkHTML.Generate_HTML,
   --#                                            SPARK_IO.File_Sys,
   --#                                            STree.Table &
   --#         Dictionary.Dict,
   --#         SparkHTML.Generate_HTML       from ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SLI.State,
   --#                                            SparkHTML.Generate_HTML,
   --#                                            SPARK_IO.File_Sys,
   --#                                            Statistics.TableUsage,
   --#                                            STree.Table &
   --#         SparkHTML.HTML_Work_Dir,
   --#         SparkHTML.SPARK_Work_Dir      from LexTokenManager.State,
   --#                                            SPARK_IO.File_Sys &
   --#         SPARK_IO.File_Sys             from *,
   --#                                            ContextManager.Ops.File_Heap,
   --#                                            ContextManager.Ops.Unit_Heap,
   --#                                            ContextManager.Ops.Unit_Stack,
   --#                                            ErrorHandler.Error_Context,
   --#                                            IndexManager.State,
   --#                                            LexTokenManager.State,
   --#                                            SLI.State,
   --#                                            SparkHTML.Generate_HTML,
   --#                                            Statistics.TableUsage,
   --#                                            STree.Table,
   --#                                            VCG.Invoked;
   is
   begin
      CommandLineData.Initialize;

      -- Process the command line before printing the banner, since
      -- the banner depends on the -xxxplain option
      CommandLineHandler.Process;

      if CommandLineData.Content.Version_Requested then
         -- User has requested the Examiner Version banner - we print
         -- this, clean up, and exit with no further action - source
         -- files are not examined.
         File_Utils.Print_A_Header (File        => SPARK_IO.Standard_Output,
                                    Header_Line => "",
                                    File_Type   => File_Utils.Other_File);
         Statistics.WriteOutput (SPARK_IO.Standard_Output);
         Set_Exit_Status (0);
      elsif CommandLineData.Content.Help_Requested then
         -- User has requested help - we print then banner,
         -- a summary of command line options, clean up, and exit
         -- with no further action - source files are not examined.
         File_Utils.Print_A_Header (File        => SPARK_IO.Standard_Output,
                                    Header_Line => "",
                                    File_Type   => File_Utils.Other_File);
         Print_Help;
         Set_Exit_Status (0);
      elsif not CommandLineData.Content.Valid then
         Set_Exit_Status (8);
      else
         CommandLineData.Dump_File_Names;

         if CommandLineData.Content.Valid and then CommandLineData.Content.Echo and then not CommandLineData.Content.Brief then
            File_Utils.Print_A_Header (File        => SPARK_IO.Standard_Output,
                                       Header_Line => "",
                                       File_Type   => File_Utils.Other_File);

            -- The Examiner used to print the banner first,
            -- then process the command line.  To make the -plain option work,
            -- though, we have to process the command line first (since the content
            -- of the banner now depends on the command line), THEN print the banner.
            -- The printing of the following message, therefore, has been moved here
            -- to preserve the old look-and-feel of the Examiner.
            if CommandLineData.Content.Default_Switch_File then
               ScreenEcho.New_Line (1);
               ScreenEcho.Put_Line ("           Reading default switch file ...");
            end if;

         end if;

         Execute;

         Set_Exit_Status (ErrorHandler.Get_Errors_Type);
      end if;
      --# accept Flow, 602, Dictionary.Dict, Dictionary.Dict, "Defined before use in MainLoop" &
      --#        Flow, 602, Sem.State, Sem.State, "Defined before use in MainLoop" &
      --#        Flow, 602, SparkHTML.HTML_Work_Dir, SparkHTML.HTML_Work_Dir, "Defined before use in MainLoop" &
      --#        Flow, 602, SparkHTML.SPARK_Work_Dir, SparkHTML.SPARK_Work_Dir, "Defined before use in MainLoop" &
      --#        Flow, 602, SparkLex.Curr_Line, SparkLex.Curr_Line, "Defined before use in MainLoop" &
      --#        Flow, 602, XMLReport.State, XMLReport.State, "Defined before use in MainLoop";
   end MainProcedure;

begin
   MainProcedure;
exception
   --# hide Examiner;
   when Fatal.Index_Manager =>
      ScreenEcho.New_Line (1);
      ScreenEcho.Put_Line ("The Examiner has encountered an error in an index file and is unable to continue.");
   when E : others =>
      -- Traceback information will vary between different platforms. Thus it
      -- is suppressed where operating in plain mode.
      if CommandLineData.Content.Plain_Output then
         ScreenEcho.New_Line (1);
         ScreenEcho.Put_Line ("Unhandled Exception in Spark.");
         ScreenEcho.Put_Line ("Operating in plain mode: Exception and traceback information suppressed.");
      else
         ScreenEcho.New_Line (1);
         ScreenEcho.Put_Line ("Unhandled Exception in Spark.  Exception information:");
         ScreenEcho.Put_Line (Ada.Exceptions.Exception_Information (E));
         ScreenEcho.Put_Line ("Traceback:");
         ScreenEcho.Put_Line (GNAT.Traceback.Symbolic.Symbolic_Traceback (E));
      end if;

      Ada.Command_Line.Set_Exit_Status (9);

end Examiner;
