libgpr2_24.0.0_eda3c693/src/lib/gpr2-project-attr_values.adb

  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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
--
--  Copyright (C) 2019-2023, AdaCore
--
--  SPDX-License-Identifier: Apache-2.0 WITH LLVM-Exception
--

with Ada.Characters.Handling;
with Ada.Strings.Equal_Case_Insensitive;

package body GPR2.Project.Attr_Values is

   function Build_Map
     (Values         : Containers.Source_Value_List;
      Case_Sensitive : Boolean) return Containers.Value_Source_Reference;
   --  Returns a set with the value in values

   ---------------
   -- Build_Set --
   ---------------

   function Build_Map
     (Values         : Containers.Source_Value_List;
      Case_Sensitive : Boolean) return Containers.Value_Source_Reference is
   begin
      return R : Containers.Value_Source_Reference do
         for V of Values loop
            if Case_Sensitive then
               R.Include (V.Text, V);

            else
               R.Include (Characters.Handling.To_Lower (V.Text), V);
            end if;
         end loop;
      end return;
   end Build_Map;

   ------------------
   -- Count_Values --
   ------------------

   function Count_Values (Self : Object) return Containers.Count_Type is
   begin
      return Self.Values.Length;
   end Count_Values;

   ------------
   -- Create --
   ------------

   function Create
     (Name  : Source_Reference.Attribute.Object;
      Value : Source_Reference.Value.Object) return Object
   is
      Values : constant Containers.Source_Value_List :=
                 Containers.Source_Value_Type_List.To_Vector
                   (Value, 1);
   begin
      return Object'
        (Name
         with Single,
              Values, True, Build_Map (Values, True));
   end Create;

   function Create
     (Name   : Source_Reference.Attribute.Object;
      Values : Containers.Source_Value_List) return Object is
   begin
      return Object'
        (Name
         with List,
         Values, True, Build_Map (Values, True));
   end Create;

   ----------------
   -- Ensure_Set --
   ----------------

   procedure Ensure_Set (Self : in out Object)
   is
      V2    : Containers.Source_Value_List;
      VMap2 : Containers.Value_Source_Reference;
      C     : Containers.Source_Value_Type_List.Cursor;
   begin
      if Self.Kind = Single then
         return;
      end if;

      for V of Self.Values loop
         declare
            Text     : constant String :=
                         (if Self.Value_Case_Sensitive
                          then V.Text
                          else Characters.Handling.To_Lower (V.Text));
            Cmap     : Containers.Value_Source_Reference_Package.Cursor;
            Inserted : Boolean;
         begin
            VMap2.Insert (Text, V, Cmap, Inserted);

            if not Inserted then
               --  Replace with the newer value
               C := V2.Find (VMap2.Element (Text));
               V2.Delete (C);

               VMap2.Replace_Element (Cmap, V);
            end if;

            V2.Append (V);
         end;
      end loop;

      Self.Values := V2;
      Self.V_Map  := VMap2;
   end Ensure_Set;

   ---------------
   -- Has_Value --
   ---------------

   function Has_Value (Self : Object; Value : Value_Type) return Boolean is
   begin
      return Self.V_Map.Contains
        (if Self.Value_Case_Sensitive
         then Value
         else Characters.Handling.To_Lower (Value));
   end Has_Value;

   ----------
   -- Kind --
   ----------

   function Kind (Self : Object'Class) return Registry.Attribute.Value_Kind is
   begin
      return Self.Kind;
   end Kind;

   ----------
   -- Name --
   ----------

   function Name (Self : Object) return Source_Reference.Attribute.Object is
   begin
      return Source_Reference.Attribute.Object (Self);
   end Name;

   --------------------
   -- Prepend_Vector --
   --------------------

   procedure Prepend_Vector
     (Self : in out Object; Other : Object) is
   begin
      Self.Values.Prepend_Vector (Other.Values);
      for C in Other.V_Map.Iterate loop
         Self.V_Map.Include
           (GPR2.Containers.Value_Source_Reference_Package.Key (C),
            Containers.Value_Source_Reference_Package.Element (C));
      end loop;
   end Prepend_Vector;

   ------------
   -- Rename --
   ------------

   function Rename
     (Self : Object;
      Name : Source_Reference.Attribute.Object) return Object
   is
   begin
      return Object'
        (Name with
           Kind                 => Self.Kind,
           Values               => Self.Values,
           Value_Case_Sensitive => Self.Value_Case_Sensitive,
           V_Map                => Self.V_Map);
   end Rename;

   --------------
   -- Set_Case --
   --------------

   procedure Set_Case
     (Self                    : in out Object;
      Value_Is_Case_Sensitive : Boolean) is
   begin
      --  Are we changing the casing

      if Value_Is_Case_Sensitive /= Self.Value_Case_Sensitive then
         Self.Value_Case_Sensitive := Value_Is_Case_Sensitive;
         Self.V_Map := Build_Map (Self.Values, Value_Is_Case_Sensitive);
      end if;
   end Set_Case;

   -----------
   -- Value --
   -----------

   function Value (Self : Object) return Source_Reference.Value.Object is
   begin
      return Self.Values.First_Element;
   end Value;

   -----------------
   -- Value_Equal --
   -----------------

   function Value_Equal (Self : Object; Value : Value_Type) return Boolean is
      use Ada.Strings;
   begin
      if Self.Value_Case_Sensitive then
         return Self.Value.Text = String (Value);
      else
         return Equal_Case_Insensitive (Self.Value.Text, String (Value));
      end if;
   end Value_Equal;

   ------------
   -- Values --
   ------------

   function Values (Self : Object) return Containers.Source_Value_List is
   begin
      return Self.Values;
   end Values;
end GPR2.Project.Attr_Values;