-------------------------------------------------------------------------------
-- (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.
--
--=============================================================================

separate (ErrorHandler.Conversions.ToString)
procedure UncondFlowErr (Err_Num          : in     Error_Types.NumericError;
                         With_Explanation : in     Boolean;
                         E_Str            : in out E_Strings.T) is
   Err_Type : ErrorHandler.Data_Flow_Err_Type;

   procedure UncondFlowErrExpl (E_Str : in out E_Strings.T)
   --# global in Err_Type;
   --# derives E_Str from *,
   --#                    Err_Type;
      is separate;
   -- Note that the parameter names for this subunit are chosen to make it as easy as
   --      possible to auto-generate the subunit from this, its parent, file.  The
   --      generation requires copying the case statement below, stripping out the
   --      current Append'Thing' statements and adding an Append_String for the
   --      explanatory text that is delineated by --! comments.

   procedure Append_Explanation
   --# global in     Err_Type;
   --#        in     With_Explanation;
   --#        in out E_Str;
   --# derives E_Str from *,
   --#                    Err_Type,
   --#                    With_Explanation;
   is
      Explanation_String : E_Strings.T := E_Strings.Empty_String;
   begin
      if With_Explanation then
         -- we need to at least look for an explanation
         UncondFlowErrExpl (E_Str => Explanation_String);
         if E_Strings.Get_Length (E_Str => Explanation_String) > 0 then
            -- there actually is one
            E_Strings.Append_String (E_Str => E_Str,
                                     Str   => ErrorHandler.Explanation_Prefix);
            E_Strings.Append_Examiner_String (E_Str1 => E_Str,
                                              E_Str2 => Explanation_String);
            E_Strings.Append_String (E_Str => E_Str,
                                     Str   => ErrorHandler.Explanation_Postfix);
         end if;
      end if;
   end Append_Explanation;

begin
   Err_Type := ErrorHandler.Data_Flow_Err_Type'Val (Err_Num.ErrorNum - Error_Types.UncondFlowErrorOffset);
   case Err_Type is

      -- HTML Directives
      --! <NameFormat> <"flow-"><Name>
      --! <ErrorFormat> <"!!! Flow Error : "><Name><" : "><Error>

      when ErrorHandler.Expn_Undefined =>
         --! <Name> 20
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => "Expression contains reference(s) to variable ");
         Append_Name (E_Str => E_Str,
                      Name  => Err_Num.Name1,
                      Scope => Err_Num.Scope);
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => " which has an undefined value");
         --! The expression may be that in an assignment or return statement,
         --! an actual parameter,
         --! or a condition occurring in an if or case statement, an iteration
         --! scheme or exit statement.  NOTE:  the presence of random and possibly invalid values
         --! introduced by data flow errors invalidates proof of exception freedom for the
         --! subprogram body which contains them.  All unconditional data flow errors must be
         --! eliminated before attempting exception freedom proofs.  See the manual
         --! &quot;SPARK Proof Manual&quot; for full details.

      when ErrorHandler.Stmt_Undefined =>
         --! <Name> 23
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => "Statement contains reference(s) to variable ");
         Append_Name (E_Str => E_Str,
                      Name  => Err_Num.Name1,
                      Scope => Err_Num.Scope);
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => " which has an undefined value");
         --! The statement here is a procedure call or an assignment to an array element, and the variable XXX may
         --! appear in an actual parameter, whose value is imported when the
         --! procedure is executed. If the variable XXX
         --! does not occur in the actual parameter list, it is an imported
         --! global variable of the procedure (named in its global definition).
         --! NOTE:  the presence of random and possibly invalid values
         --! introduced by data flow errors invalidates proof of exception freedom for the
         --! subprogram body which contains them.  All unconditional data flow errors must be
         --! eliminated before attempting exception freedom proofs.  See the manual
         --! &quot;SPARK Proof Manual&quot; for full details.
      when ErrorHandler.Invariant_Exp =>
         --! <Name> 22
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => "Value of expression is invariant");
         --! The expression is either a case expression or a condition
         --! (Boolean-valued expression) associated with an if-statement, not
         --! contained in a loop statement. The message indicates
         --! that the expression takes the same value whenever it is evaluated,
         --! in all program executions.  Note that if the expression depends on values obtained
         --! by a call to another other subprogram then a possible source for its invariance
         --! might be an incorrect annotation on the called subprogram.

      when others =>
         E_Strings.Append_String (E_Str => E_Str,
                                  Str   => "UNKNOWN ERROR NUMBER PASSED TO Dep_Semantic_Err");
   end case;
   Append_Explanation;
   E_Strings.Append_String (E_Str => E_Str,
                            Str   => ".");
end UncondFlowErr;
