libgpr2_24.0.0_eda3c693/src/lib/gpr2-log.ads

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
--
--  Copyright (C) 2019-2023, AdaCore
--
--  SPDX-License-Identifier: Apache-2.0 WITH LLVM-Exception
--

--  This package is used to store the log messages (error/warning/information)
--  coming from the parser.

with Ada.Iterator_Interfaces;

with GPR2.Containers;
with GPR2.Message;

private with Ada.Containers.Vectors;

package GPR2.Log is

   use type Containers.Count_Type;
   use type Message.Object;

   type Object is tagged private
     with Constant_Indexing => Constant_Reference,
          Variable_Indexing => Reference,
          Default_Iterator  => Iterate,
          Iterator_Element  => Message.Object;

   Undefined : constant Object;

   function Is_Defined (Self : Object) return Boolean;
   --  Returns true if Self is defined

   function Contains
     (Self : Object; Message : GPR2.Message.Object) return Boolean;

   procedure Append (Self : in out Object; Message : GPR2.Message.Object)
     with Post =>
       Self.Count'Old + (if Self.Contains (Message)'Old then 0 else 1)
         = Self.Count;
   --  Insert a log message only if not already present

   function Count (Self : Object) return Containers.Count_Type
     with Post =>
       (if Self.Has_Element then Count'Result > 0 else Count'Result = 0);
   --  Returns the number of message in the log object

   function Is_Empty (Self : Object) return Boolean
     with Post => Self.Count > 0 xor Is_Empty'Result;
   --  Returns True if the log contains no message

   procedure Clear (Self : in out Object)
     with Post => Self.Count = 0;
   --  Removes all message from the log

   function Has_Element
     (Self        : Object;
      Information : Boolean := True;
      Warning     : Boolean := True;
      Error       : Boolean := True;
      Lint        : Boolean := True;
      Read        : Boolean := True;
      Unread      : Boolean := True) return Boolean;
   --  Returns True if the log contains some information/warning/error
   --  depending on the value specified.

   function Has_Error (Self : Object) return Boolean;
   --  Returns True if the log contains unread errors

   --  Iterator

   type Cursor is private;

   function Element (Position : Cursor) return Message.Object
     with Post =>
       (if Has_Element (Position)
        then Element'Result.Is_Defined
        else not Element'Result.Is_Defined);

   function Has_Element (Position : Cursor) return Boolean;

   package Log_Iterator is new Ada.Iterator_Interfaces (Cursor, Has_Element);

   type Constant_Reference_Type
     (Message : not null access constant GPR2.Message.Object) is private
     with Implicit_Dereference => Message;

   function Constant_Reference
     (Self     : aliased Object;
      Position : Cursor) return Constant_Reference_Type;

   type Reference_Type
     (Message : not null access GPR2.Message.Object) is private
     with Implicit_Dereference => Message;

   function Reference
     (Self     : aliased in out Object;
      Position : Cursor) return Reference_Type;

   function Iterate
     (Self        : Object;
      Information : Boolean := True;
      Warning     : Boolean := True;
      Error       : Boolean := True;
      Lint        : Boolean := False;
      Read        : Boolean := True;
      Unread      : Boolean := True)
      return Log_Iterator.Forward_Iterator'Class;
   --  Iterates over all log messages corresponding to the given Filter. The
   --  Unread messages are marked as Read after this call (either explicit call
   --  or using a for-of iterator). Using the Unread flag it is possible to
   --  keep all messages into the list (no need to call Clear) and yet be able
   --  to check for new Unread messages.

   procedure Output_Messages
     (Log            : GPR2.Log.Object;
      Information    : Boolean := True;
      Warning        : Boolean := True;
      Error          : Boolean := True;
      Lint           : Boolean := False;
      Full_Path_Name : Boolean := False;
      Output_Levels  : GPR2.Message.Level_Output :=
                         (GPR2.Message.Long,
                          GPR2.Message.Long,
                          GPR2.Message.Long,
                          GPR2.Message.Long));
   --  Print Log selected messages using format parameters
private

   package Message_Set is
     new Ada.Containers.Vectors (Positive, Message.Object);

   type Object is tagged record
      Store   : aliased Message_Set.Vector;
      Index   : Containers.Value_Set;
      Defined : Boolean := True;
   end record;

   type Cursor is record
      Store : not null access Message_Set.Vector;
      P     : Natural;
   end record;

   type Constant_Reference_Type
     (Message : not null access constant GPR2.Message.Object) is record
      --  We need to keep the underlying reference so that it is not cleared
      --  upon return of the getter, and so that the container has the proper
      --  busy state
      Ref : Message_Set.Constant_Reference_Type (Message);
   end record;

   type Reference_Type
     (Message : not null access GPR2.Message.Object) is record
      --  We need to keep the underlying reference so that it is not cleared
      --  upon return of the getter, and so that the container has the proper
      --  busy state
      Ref : Message_Set.Reference_Type (Message);
   end record;

   function Contains
     (Self : Object; Message : GPR2.Message.Object) return Boolean
   is
     (Self.Index.Contains
        (Message.Format (Levels => (others => GPR2.Message.Short))));

   function Has_Error (Self : Object) return Boolean is
     (Self.Has_Element
        (Information => False,
         Warning     => False,
         Error       => True,
         Lint        => False,
         Read        => False,
         Unread      => True));

   Undefined : constant Object :=
                 (Store   => Message_Set.Empty_Vector,
                  Index   => Containers.Value_Type_Set.Empty_Set,
                  Defined => False);

   function Is_Defined (Self : Object) return Boolean is (Self.Defined);

end GPR2.Log;