------------------------------------------------------------------------------
--                                                                          --
--                          GNATCHECK COMPONENTS                            --
--                                                                          --
--                  G N A T C H E C K . E X E M P T I O N                   --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
--                     Copyright (C) 2009-2010, AdaCore                     --
--                                                                          --
-- GNATCHECK  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.  GNATCHECK  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.                                       --
--                                                                          --
-- GNATCHECK is maintained by AdaCore (http://www.adacore.com).             --
--                                                                          --
------------------------------------------------------------------------------

--  This package contains resources needed for rule exemption.

with Asis;                 use Asis;

with ASIS_UL.Source_Table; use ASIS_UL.Source_Table;
with ASIS_UL.Strings;      use ASIS_UL.Strings;

package Gnatcheck.Exemption is

   Exemption_On : Boolean := True;
   --  If this flag is OFF, all the rule exemption mechanism is disabled.
   --  ???

   Print_Exemption_Section : Boolean := False;
   --  If this flag is OFF, the generated report file does not contain the
   --  section for exempted rules diagnosis.

   function Is_Exemption_Pragma (El : Asis.Element) return Boolean;
   --  Checks if the argument Element is Annotate pragma with first parameter
   --  equal to gnatcheck.

   procedure Process_Exemption_Pragma (El : Asis.Element);
   --  Provided that Is_Exemption_Pragma (El), analyses the argument element
   --  and sets the exemption mode for the corresponding rule if the pargma
   --  is correct and the rule is active

   procedure Init_Compiler_Check_Exemptions_Storage;
   --  Performs general initializations for database that stores information
   --  about exemption sections for compiler checks.

   procedure Init_Compiler_Check_Exemptions (SF : SF_Id);
   --  Prepares the internal data structures for storing information about
   --  compiler check excemption sections in SF. Should be called in the very
   --  beginning of analysing SF.

   procedure Check_Unclosed_Rule_Exemptions
     (SF   : SF_Id;
      Unit : Asis.Element);
   --  Is supposed to be called in the very end of processing of the source
   --  corresponding to SF. Checks if there exist some exemted rules. For each
   --  such rule, a warning is issued and exemption is turned OFF. Unit
   --  parameter is used to compute the end of non-closed exemption sections
   --  for compiler checks, if any.

   type Exemption_Info is private;
   --  Contains information about rule exempion that are of interest for rule
   --  checkings.

   procedure Clean_Exemption (Exemp : in out Exemption_Info);
   --  Sets the argument to the state corresponding to the absense of any
   --  exemption, the number of generated diagnoses is set to 0.

   function Present (Exemp : Exemption_Info) return Boolean;
   --  Checks if the argument represents some existing exemption

   function Exemption_Violations (Exemp : Exemption_Info) return Natural;
   --  returns the number of violations detected fpr exempted rule.

   function Exemption_Line (Exemp : Exemption_Info) return Natural;
   function Exemption_Col  (Exemp : Exemption_Info) return Natural;
   --  Returns the line/column number of the corresponding exemption pragma.
   --  Returns 0 if there is no such pragma.

   function Exemption_Justification (Exemp : Exemption_Info) return String_Loc;
   --  Returns the justification string exemption pragma. Returns
   --  Nil_String_Loc if there is no such pragma.

   procedure Set_Exemption_Info
     (Line          :     Natural := 0;
      Col           :     Natural := 0;
      Justification :     String_Loc := Nil_String_Loc;
      Value         : out Exemption_Info);
   --  Sets the Exemption_Info value for Value. The defaults corresponds to the
   --  situation when there is no exemption. Does not affect the number of
   --  diagnoses for exempted rule.

   procedure Increase_Violation_Counter (Exemp : in out Exemption_Info);
   --  Add 1 tro the number of violation detected for the corresponding
   --  exempted rule.

private

   type Exemption_Info is record
      Line : Natural;
      Col  : Natural;
      --  Location of exemption pragma that turns exemption ON

      Justification : String_Loc;
      --  Exemption justification

      Detected : Natural;
      --  Number of the diagnoses generated for exempted rule
   end record;

end Gnatcheck.Exemption;
