----------------------------------------------------------------------
--  Analyzer.Table_Manager package body                             --
--  Copyright (C) 2002 Adalog                                       --
--  Author: J-P. Rosen                                              --
--                                                                  --
--  ADALOG   is   providing   training,   consultancy,   expertise, --
--  assistance and custom developments  in Ada and related software --
--  engineering techniques.  For more info about our services:      --
--  ADALOG                   Tel: +33 1 41 24 31 40                 --
--  19-21 rue du 8 mai 1945  Fax: +33 1 41 24 07 36                 --
--  94110 ARCUEIL            E-m: info@adalog.fr                    --
--  FRANCE                   URL: http://www.adalog.fr              --
--                                                                  --
--  This  unit 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.  This  unit 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 this program; see file --
--  COPYING.   If not, write  to the  Free Software  Foundation, 59 --
--  Temple Place - Suite 330, Boston, MA 02111-1307, USA.           --
--                                                                  --
--  As  a special  exception, if  other files  instantiate generics --
--  from  this unit,  or you  link this  unit with  other  files to --
--  produce an executable,  this unit does not by  itself cause the --
--  resulting executable  to be covered  by the GNU  General Public --
--  License.  This exception does  not however invalidate any other --
--  reasons why  the executable  file might be  covered by  the GNU --
--  Public License.                                                 --
----------------------------------------------------------------------

with   -- Ada standard units
  Ada.Strings.Wide_Fixed,
  Ada.Unchecked_Deallocation;
package body Analyzer.Table_Manager is
   procedure Free is new Ada.Unchecked_Deallocation (Node, Table);

   ---------------
   -- Is_Before --
   ---------------

   -- Defines ordering int the table.
   -- We do not want normal lexical order, because we want the list sorted
   -- by prefix first, then by selector
   function Is_Before (Left, Right : Wide_String) return Boolean is
      use Ada.Strings, Ada.Strings.Wide_Fixed;

      Pos_Left  : constant Natural := Index (Left,  ".", Going => Backward);
      Pos_Right : constant Natural := Index (Right, ".", Going => Backward);
   begin
      if Left (Left'First .. Pos_Left-1) = Right (Right'First .. Pos_Right-1) then
         -- This includes the case where both strings are null, i.e. Pos_* = 0
         -- In this case, the lower bound is XX'first, not necessarily 0+1!
         return
           Left  (Natural'Max (Pos_Left +1, Left'First ) .. Left'Last) <
           Right (Natural'Max (Pos_Right+1, Right'First) .. Right'Last);
      else
         return Left (Left'First .. Pos_Left-1) < Right (Right'First .. Pos_Right-1);
      end if;
   end Is_Before;

   ---------
   -- Add --
   ---------

   procedure Add (Key     : in     Wide_String;
                  To      : in out Table;
                  Comment : in     Wide_String := "") is
   begin
      if To = null then
         To := new Node'(K_Length     => Key'Length,
                         C_Length     => Comment'Length,
                         Key          => Key,
                         Comment      => Comment,
                         Count        => 1,
                         Left | Right => null);
      else
         if Is_Before (Key, To.Key) then
            Add (Key, To => To.Left, Comment => Comment);
         elsif Key = To.Key then
            To.Count := To.Count + 1;
         else
            Add (Key, To => To.Right, Comment => Comment);
         end if;
      end if;
   end Add;

   --------------
   -- Is_Empty --
   --------------

   function Is_Empty (The_Table : Table) return Boolean is
   begin
      return The_Table = null;
   end Is_Empty;

   -------------
   -- Iterate --
   -------------

   procedure Iterate (Over : Table) is
   begin
      if Over = null then
         return;
      end if;

      Iterate(Over.Left);
      Action(Over.Key, Over.Comment, Over.Count);
      Iterate(Over.Right);
   end Iterate;

   -----------
   -- Reset --
   -----------

   procedure Reset (The_Table : in out Table) is
   begin
      if The_Table = null then
         return;
      end if;

      Reset (The_Table.Left);
      Reset (The_Table.Right);
      Free (The_Table);
   end Reset;

end Analyzer.Table_Manager;

