<commit_before>-----------------------------------------------------------------------
--  mat-frames - Representation of stack frames
--  Copyright (C) 2014 <NAME>
--  Written by <NAME> (<EMAIL>)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Unchecked_Deallocation;
with Ada.Text_IO;

with Util.Log.Loggers;
with MAT.Frames.Print;
package body MAT.Frames is

   use type MAT.Types.Target_Addr;

   procedure Free is
     new Ada.Unchecked_Deallocation (Frame, Frame_Type);

   --  The logger
   Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("MAT.Frames.Targets");

   procedure Split (F     : in out Frame_Type;
                    Pos   : in Positive);

   procedure Add_Frame (F      : in Frame_Type;
                        Pc     : in Frame_Table;
                        Result : out Frame_Type);

   function Check (Frame : in Frame_Type) return Boolean is
      Parent : Frame_Type;
      Child  : Frame_Type;
      Result : Boolean := True;
   begin
      if Frame = null then
         return False;
      end if;
      Child := Frame.Children;
      while Child /= null loop
         if Child.Parent /= Frame then
            Log.Error ("Invalid parent link");
            Result := False;
         end if;
         if Child.Children /= null and then not Check (Child) then
            Log.Error ("A child is now invalid");
            Result := False;
         end if;
         Child := Child.Next;
      end loop;
      return Result;
   end Check;

   --  ------------------------------
   --  Return the parent frame.
   --  ------------------------------
   function Parent (Frame : in Frame_Type) return Frame_Type is
   begin
      if Frame = null then
         return null;
      else
         return Frame.Parent;
      end if;
   end Parent;

   --  ------------------------------
   --  Get the root frame object.
   --  ------------------------------
   function Get_Root (Frame : in Frame_Type) return Frame_Type is
      Parent : Frame_Type := Frame;
   begin
      loop
         if Parent.Parent = null then
            return Parent;
         end if;
         Parent := Parent.Parent;
      end loop;
   end Get_Root;

   --  ------------------------------
   --  Returns the backtrace of the current frame (up to the root).
   --  When <tt>Max_Level</tt> is positive, limit the number of PC frames to the value.
   --  ------------------------------
   function Backtrace (Frame     : in Frame_Type;
                       Max_Level : in Natural := 0) return Frame_Table is
      Length  : Natural;
   begin
      if Max_Level > 0 and Max_Level < Frame.Depth then
         Length := Max_Level;
      else
         Length := Frame.Depth;
      end if;
      declare
         Current : Frame_Type := Frame;
         Pos     : Natural    := Length;
         New_Pos : Natural;
         Pc      : Frame_Table (1 .. Length);
      begin
         while Current /= null and Pos /= 0 loop
            if Pos >= Current.Local_Depth then
               New_Pos := Pos - Current.Local_Depth + 1;
               Pc (New_Pos .. Pos) := Current.Calls (1 .. Current.Local_Depth);
               Pos     := New_Pos - 1;
            else
               Pc (1 .. Pos) := Current.Calls (Current.Local_Depth - Pos - 1 .. Current.Local_Depth);
               Pos := 0;
            end if;
            Current := Current.Parent;
         end loop;
         return Pc;
      end;
   end Backtrace;

   --  ------------------------------
   --  Returns the number of children in the frame.
   --  When recursive is true, compute in the sub-tree.
   --  ------------------------------
   function Count_Children (Frame     : in Frame_Type;<commit_msg>Fix Backtrace operation to return a subset of the backtrace<commit_after>-----------------------------------------------------------------------
--  mat-frames - Representation of stack frames
--  Copyright (C) 2014 <NAME>
--  Written by <NAME> (<EMAIL>)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Unchecked_Deallocation;
with Ada.Text_IO;

with Util.Log.Loggers;
with MAT.Frames.Print;
package body MAT.Frames is

   use type MAT.Types.Target_Addr;

   procedure Free is
     new Ada.Unchecked_Deallocation (Frame, Frame_Type);

   --  The logger
   Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("MAT.Frames.Targets");

   procedure Split (F     : in out Frame_Type;
                    Pos   : in Positive);

   procedure Add_Frame (F      : in Frame_Type;
                        Pc     : in Frame_Table;
                        Result : out Frame_Type);

   function Check (Frame : in Frame_Type) return Boolean is
      Parent : Frame_Type;
      Child  : Frame_Type;
      Result : Boolean := True;
   begin
      if Frame = null then
         return False;
      end if;
      Child := Frame.Children;
      while Child /= null loop
         if Child.Parent /= Frame then
            Log.Error ("Invalid parent link");
            Result := False;
         end if;
         if Child.Children /= null and then not Check (Child) then
            Log.Error ("A child is now invalid");
            Result := False;
         end if;
         Child := Child.Next;
      end loop;
      return Result;
   end Check;

   --  ------------------------------
   --  Return the parent frame.
   --  ------------------------------
   function Parent (Frame : in Frame_Type) return Frame_Type is
   begin
      if Frame = null then
         return null;
      else
         return Frame.Parent;
      end if;
   end Parent;

   --  ------------------------------
   --  Get the root frame object.
   --  ------------------------------
   function Get_Root (Frame : in Frame_Type) return Frame_Type is
      Parent : Frame_Type := Frame;
   begin
      loop
         if Parent.Parent = null then
            return Parent;
         end if;
         Parent := Parent.Parent;
      end loop;
   end Get_Root;

   --  ------------------------------
   --  Returns the backtrace of the current frame (up to the root).
   --  When <tt>Max_Level</tt> is positive, limit the number of PC frames to the value.
   --  ------------------------------
   function Backtrace (Frame     : in Frame_Type;
                       Max_Level : in Natural := 0) return Frame_Table is
      Length  : Natural;
   begin
      if Max_Level > 0 and Max_Level < Frame.Depth then
         Length := Max_Level;
      else
         Length := Frame.Depth;
      end if;
      declare
         Current : Frame_Type := Frame;
         Pos     : Natural    := Length;
         New_Pos : Natural;
         Pc      : Frame_Table (1 .. Length);
      begin
         while Current /= null and Pos /= 0 loop
            if Pos >= Current.Local_Depth then
               New_Pos := Pos - Current.Local_Depth + 1;
               Pc (New_Pos .. Pos) := Current.Calls (1 .. Current.Local_Depth);
               Pos     := New_Pos - 1;
            else
               Pc (1 .. Pos) := Current.Calls (Current.Local_Depth - Pos + 1 .. Current.Local_Depth);
               Pos := 0;
            end if;
            Current := Current.Parent;
         end loop;
         return Pc;
      end;
   end Backtrace;

   --  ------------------------------
   --  Returns the number of children in the frame.
   --  When recursive is true, compute in the sub-tree.
   --  ------------------------------
   function Count_Children (Frame     : in Frame_Type;
{'fraction_non_alphanumeric': 0.16841125843219354, 'fraction_numerical': 0.00418702023726448, 'mean_word_length': 1.3892747985551541, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '791001', 'n_tokens_mistral': 2252, 'n_tokens_neox': 2174, 'n_words': 812}