File : a-strmap.adb


     ------------------------------------------------------------------------------
     --                                                                          --
     --                         GNAT RUNTIME COMPONENTS                          --
     --                                                                          --
   5 --                     A D A . S T R I N G S . M A P S                      --
     --                                                                          --
     --                                 B o d y                                  --
     --                                                                          --
     --                            $Revision: 1.19 $
  10 --                                                                          --
     --          Copyright (C) 1992-2001 Free Software Foundation, Inc.          --
     --                                                                          --
     -- GNAT is free software;  you can  redistribute it  and/or modify it under --
     -- terms of the  GNU General Public License as published  by the Free Soft- --
  15 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
     -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
     -- OUT 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 --
  20 -- Public License  distributed with GNAT;  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 --
  25 -- 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.                                      --
  30 --                                                                          --
     -- GNAT was originally developed  by the GNAT team at  New York University. --
     -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
     --                                                                          --
     ------------------------------------------------------------------------------
  35 
     --  Note: parts of this code are derived from the ADAR.CSH public domain
     --  Ada 83 versions of the Appendix C string handling packages. The main
     --  differences are that we avoid the use of the minimize function which
     --  is bit-by-bit or character-by-character and therefore rather slow.
  40 --  Generally for character sets we favor the full 32-byte representation.
     
     package body Ada.Strings.Maps is
     
        use Ada.Characters.Latin_1;
  45 
        ---------
        -- "-" --
        ---------
     
  50    function "-" (Left, Right : Character_Set) return Character_Set is
        begin
           return Left and not Right;
        end "-";
     
  55    ---------
        -- "=" --
        ---------
     
        function "=" (Left, Right : in Character_Set) return Boolean is
  60    begin
           return Character_Set_Internal (Left) = Character_Set_Internal (Right);
        end "=";
     
        -----------
  65    -- "and" --
        -----------
     
        function "and" (Left, Right : in Character_Set) return Character_Set is
        begin
  70       return Character_Set
             (Character_Set_Internal (Left) and Character_Set_Internal (Right));
        end "and";
     
        -----------
  75    -- "not" --
        -----------
     
        function "not" (Right : in Character_Set) return Character_Set is
        begin
  80       return Character_Set (not Character_Set_Internal (Right));
        end "not";
     
        ----------
        -- "or" --
  85    ----------
     
        function "or" (Left, Right : in Character_Set) return Character_Set is
        begin
           return Character_Set
  90         (Character_Set_Internal (Left) or Character_Set_Internal (Right));
        end "or";
     
        -----------
        -- "xor" --
  95    -----------
     
        function "xor" (Left, Right : in Character_Set) return Character_Set is
        begin
           return Character_Set
 100         (Character_Set_Internal (Left) xor Character_Set_Internal (Right));
        end "xor";
     
        -----------
        -- Is_In --
 105    -----------
     
        function Is_In
          (Element : Character;
           Set     : Character_Set)
 110       return    Boolean
        is
        begin
           return Set (Element);
        end Is_In;
 115 
        ---------------
        -- Is_Subset --
        ---------------
     
 120    function Is_Subset
          (Elements : Character_Set;
           Set      : Character_Set)
           return     Boolean
        is
 125    begin
           return (Elements and Set) = Elements;
        end Is_Subset;
     
        ---------------
 130    -- To_Domain --
        ---------------
     
        function To_Domain (Map : in Character_Mapping) return Character_Sequence
        is
 135       Result : String (1 .. Map'Length);
           J      : Natural;
     
        begin
           J := 0;
 140       for C in Map'Range loop
              if Map (C) /= C then
                 J := J + 1;
                 Result (J) := C;
              end if;
 145       end loop;
     
           return Result (1 .. J);
        end To_Domain;
     
 150    ----------------
        -- To_Mapping --
        ----------------
     
        function To_Mapping
 155      (From, To : in Character_Sequence)
           return     Character_Mapping
        is
           Result   : Character_Mapping;
           Inserted : Character_Set := Null_Set;
 160       From_Len : constant Natural := From'Length;
           To_Len   : constant Natural := To'Length;
     
        begin
           if From_Len /= To_Len then
 165          raise Strings.Translation_Error;
           end if;
     
           for Char in Character loop
              Result (Char) := Char;
 170       end loop;
     
           for J in From'Range loop
              if Inserted (From (J)) then
                 raise Strings.Translation_Error;
 175          end if;
     
              Result   (From (J)) := To (J - From'First + To'First);
              Inserted (From (J)) := True;
           end loop;
 180 
           return Result;
        end To_Mapping;
     
        --------------
 185    -- To_Range --
        --------------
     
        function To_Range (Map : in Character_Mapping) return Character_Sequence
        is
 190       Result : String (1 .. Map'Length);
           J      : Natural;
     
        begin
           J := 0;
 195       for C in Map'Range loop
              if Map (C) /= C then
                 J := J + 1;
                 Result (J) := Map (C);
              end if;
 200       end loop;
     
           return Result (1 .. J);
        end To_Range;
     
 205    ---------------
        -- To_Ranges --
        ---------------
     
        function To_Ranges (Set : in Character_Set) return Character_Ranges is
 210       Max_Ranges : Character_Ranges (1 .. Set'Length / 2 + 1);
           Range_Num  : Natural;
           C          : Character;
     
        begin
 215       C := Character'First;
           Range_Num := 0;
     
           loop
              --  Skip gap between subsets.
 220 
              while not Set (C) loop
                 exit when C = Character'Last;
                 C := Character'Succ (C);
              end loop;
 225 
              exit when not Set (C);
     
              Range_Num := Range_Num + 1;
              Max_Ranges (Range_Num).Low := C;
 230 
              --  Span a subset.
     
              loop
                 exit when not Set (C) or else C = Character'Last;
 235             C := Character' Succ (C);
              end loop;
     
              if Set (C) then
                 Max_Ranges (Range_Num). High := C;
 240             exit;
              else
                 Max_Ranges (Range_Num). High := Character'Pred (C);
              end if;
           end loop;
 245 
           return Max_Ranges (1 .. Range_Num);
        end To_Ranges;
     
        -----------------
 250    -- To_Sequence --
        -----------------
     
        function To_Sequence
          (Set  : Character_Set)
 255       return Character_Sequence
        is
           Result : String (1 .. Character'Pos (Character'Last) + 1);
           Count  : Natural := 0;
     
 260    begin
           for Char in Set'Range loop
              if Set (Char) then
                 Count := Count + 1;
                 Result (Count) := Char;
 265          end if;
           end loop;
     
           return Result (1 .. Count);
        end To_Sequence;
 270 
        ------------
        -- To_Set --
        ------------
     
 275    function To_Set (Ranges : in Character_Ranges) return Character_Set is
           Result : Character_Set;
     
        begin
           for C in Result'Range loop
 280          Result (C) := False;
           end loop;
     
           for R in Ranges'Range loop
              for C in Ranges (R).Low .. Ranges (R).High loop
 285             Result (C) := True;
              end loop;
           end loop;
     
           return Result;
 290    end To_Set;
     
        function To_Set (Span   : in Character_Range) return Character_Set is
           Result : Character_Set;
     
 295    begin
           for C in Result'Range loop
              Result (C) := False;
           end loop;
     
 300       for C in Span.Low .. Span.High loop
              Result (C) := True;
           end loop;
     
           return Result;
 305    end To_Set;
     
        function To_Set (Sequence : Character_Sequence) return Character_Set is
           Result : Character_Set := Null_Set;
     
 310    begin
           for J in Sequence'Range loop
              Result (Sequence (J)) := True;
           end loop;
     
 315       return Result;
        end To_Set;
     
        function To_Set (Singleton : Character) return Character_Set is
           Result : Character_Set := Null_Set;
 320 
        begin
           Result (Singleton) := True;
           return Result;
        end To_Set;
 325 
        -----------
        -- Value --
        -----------
     
 330    function Value (Map : in Character_Mapping; Element : in Character)
           return Character is
     
        begin
           return Map (Element);
 335    end Value;
     
     end Ada.Strings.Maps;