home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gnat-2.06-src.tgz / tar.out / fsf / gnat / ada / a-stwifi.adb < prev    next >
Text File  |  1996-09-28  |  17KB  |  614 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT RUNTIME COMPONENTS                          --
  4. --                                                                          --
  5. --               A D A . S T R I N G S . W I D E _ F I X E D                --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.10 $                              --
  10. --                                                                          --
  11. --           Copyright (c) 1992,1993,1994 NYU, All Rights Reserved          --
  12. --                                                                          --
  13. -- The GNAT library is free software; you can redistribute it and/or modify --
  14. -- it under terms of the GNU Library General Public License as published by --
  15. -- the Free Software  Foundation; either version 2, or (at your option) any --
  16. -- later version.  The GNAT library is distributed in the hope that it will --
  17. -- be useful, but WITHOUT ANY WARRANTY;  without even  the implied warranty --
  18. -- of MERCHANTABILITY  or  FITNESS FOR  A PARTICULAR PURPOSE.  See the  GNU --
  19. -- Library  General  Public  License for  more  details.  You  should  have --
  20. -- received  a copy of the GNU  Library  General Public License  along with --
  21. -- the GNAT library;  see the file  COPYING.LIB.  If not, write to the Free --
  22. -- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        --
  23. --                                                                          --
  24. ------------------------------------------------------------------------------
  25.  
  26.  
  27. with Ada.Strings.Wide_Maps; use Ada.Strings.Wide_Maps;
  28. with Ada.Strings.Wide_Search;
  29.  
  30. package body Ada.Strings.Wide_Fixed is
  31.  
  32.    ------------------------
  33.    -- Search Subprograms --
  34.    ------------------------
  35.  
  36.    function Index
  37.      (Source  : in Wide_String;
  38.       Pattern : in Wide_String;
  39.       Going   : in Direction := Forward;
  40.       Mapping : in Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
  41.       return    Natural
  42.    renames Ada.Strings.Wide_Search.Index;
  43.  
  44.    function Index
  45.      (Source  : in Wide_String;
  46.       Pattern : in Wide_String;
  47.       Going   : in Direction := Forward;
  48.       Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
  49.       return    Natural
  50.    renames Ada.Strings.Wide_Search.Index;
  51.  
  52.    function Index
  53.      (Source : in Wide_String;
  54.       Set    : in Wide_Maps.Wide_Character_Set;
  55.       Test   : in Membership := Inside;
  56.       Going  : in Direction  := Forward)
  57.       return   Natural
  58.    renames Ada.Strings.Wide_Search.Index;
  59.  
  60.    function Index_Non_Blank
  61.      (Source : in Wide_String;
  62.       Going  : in Direction := Forward)
  63.       return   Natural
  64.    renames Ada.Strings.Wide_Search.Index_Non_Blank;
  65.  
  66.    function Count
  67.      (Source  : in Wide_String;
  68.       Pattern : in Wide_String;
  69.       Mapping : in Wide_Maps.Wide_Character_Mapping := Wide_Maps.Identity)
  70.       return    Natural
  71.    renames Ada.Strings.Wide_Search.Count;
  72.  
  73.    function Count
  74.      (Source   : in Wide_String;
  75.       Pattern  : in Wide_String;
  76.       Mapping  : in Wide_Maps.Wide_Character_Mapping_Function)
  77.       return     Natural
  78.    renames Ada.Strings.Wide_Search.Count;
  79.  
  80.    function Count
  81.      (Source : in Wide_String;
  82.       Set    : in Wide_Maps.Wide_Character_Set)
  83.       return   Natural
  84.    renames Ada.Strings.Wide_Search.Count;
  85.  
  86.    procedure Find_Token
  87.      (Source : in Wide_String;
  88.       Set    : in Wide_Maps.Wide_Character_Set;
  89.       Test   : in Membership;
  90.       First  : out Positive;
  91.       Last   : out Natural)
  92.    renames Ada.Strings.Wide_Search.Find_Token;
  93.  
  94.    ---------
  95.    -- "*" --
  96.    ---------
  97.  
  98.    function "*" (Left  : in Natural;
  99.                  Right : in Wide_Character) return Wide_String
  100.    is
  101.       Result : Wide_String (1 .. Left);
  102.  
  103.    begin
  104.       for J in Result'Range loop
  105.          Result (J) := Right;
  106.       end loop;
  107.  
  108.       return Result;
  109.    end "*";
  110.  
  111.    function "*"
  112.      (Left  : in Natural;
  113.       Right : in Wide_String)
  114.       return  Wide_String
  115.    is
  116.       Result : Wide_String (1 .. Left * Right'Length);
  117.       Ptr    : Integer := 1;
  118.  
  119.    begin
  120.       for J in 1 .. Left loop
  121.          Result (Ptr .. Ptr + Right'Length - 1) := Right;
  122.          Ptr := Ptr + Right'Length;
  123.       end loop;
  124.  
  125.       return Result;
  126.    end "*";
  127.  
  128.    ------------
  129.    -- Delete --
  130.    ------------
  131.  
  132.    function Delete
  133.      (Source  : in Wide_String;
  134.       From    : in Positive;
  135.       Through : in Natural)
  136.       return    Wide_String
  137.    is
  138.    begin
  139.       if From > Through then
  140.          return Source;
  141.       elsif From > Source'Last + 1 or else Through < Source'First - 1 then
  142.          raise Index_Error;
  143.       else
  144.          declare
  145.             Result : constant Wide_String :=
  146.                        Source (Source'First .. From - 1) &
  147.                        Source (Through + 1 .. Source'Last);
  148.          begin
  149.             return Result;
  150.          end;
  151.       end if;
  152.  
  153.    end Delete;
  154.  
  155.    procedure Delete
  156.      (Source  : in out Wide_String;
  157.       From    : in Positive;
  158.       Through : in Natural;
  159.       Justify : in Alignment := Left;
  160.       Pad     : in Wide_Character := Wide_Space)
  161.    is
  162.    begin
  163.       Move (Source  => Delete (Source, From, Through),
  164.             Target  => Source,
  165.             Justify => Justify,
  166.             Pad     => Pad);
  167.    end Delete;
  168.  
  169.    ----------
  170.    -- Head --
  171.    ----------
  172.  
  173.    function Head
  174.      (Source : in Wide_String;
  175.       Count  : in Natural;
  176.       Pad    : in Wide_Character := Wide_Space)
  177.       return   Wide_String
  178.    is
  179.       Result : Wide_String (1 .. Count);
  180.  
  181.    begin
  182.       if Count <= Source'Length then
  183.          Result := Source (Source'First .. Source'First + Count - 1);
  184.  
  185.       else
  186.          Result (1 .. Source'Length) := Source;
  187.  
  188.          for J in Source'Length + 1 .. Count loop
  189.             Result (J) := Pad;
  190.          end loop;
  191.  
  192.       end if;
  193.  
  194.       return Result;
  195.    end Head;
  196.  
  197.    ------------
  198.    -- Insert --
  199.    ------------
  200.  
  201.    function Insert
  202.      (Source   : in Wide_String;
  203.       Before   : in Positive;
  204.       New_Item : in Wide_String)
  205.       return     Wide_String
  206.    is
  207.       Result : Wide_String (1 .. Source'Length + New_Item'Length);
  208.  
  209.    begin
  210.       if Before < Source'First or else Before > Source'Last + 1 then
  211.          raise Index_Error;
  212.       end if;
  213.  
  214.       Result := Source (Source'First .. Before - 1) & New_Item &
  215.                 Source (Before .. Source'Last);
  216.       return Result;
  217.    end Insert;
  218.  
  219.    procedure Insert
  220.      (Source   : in out Wide_String;
  221.       Before   : in Positive;
  222.       New_Item : in Wide_String;
  223.       Drop     : in Truncation := Error)
  224.    is
  225.    begin
  226.       Move (Source => Insert (Source, Before, New_Item),
  227.             Target => Source,
  228.             Drop   => Drop);
  229.    end Insert;
  230.  
  231.    ----------
  232.    -- Move --
  233.    ----------
  234.  
  235.    procedure Move
  236.      (Source  : in  Wide_String;
  237.       Target  : out Wide_String;
  238.       Drop    : in  Truncation := Error;
  239.       Justify : in  Alignment  := Left;
  240.       Pad     : in  Wide_Character  := Wide_Space)
  241.    is
  242.       Sfirst  : constant Integer := Source'First;
  243.       Slast   : constant Integer := Source'Last;
  244.       Slength : constant Integer := Source'Length;
  245.  
  246.       Tfirst  : constant Integer := Target'First;
  247.       Tlast   : constant Integer := Target'Last;
  248.       Tlength : constant Integer := Target'Length;
  249.  
  250.       function Is_Padding (Item : Wide_String) return Boolean;
  251.       --  Determinbe if all characters in Item are pad characters
  252.  
  253.       function Is_Padding (Item : Wide_String) return Boolean is
  254.       begin
  255.          for J in Item'Range loop
  256.             if Item (J) /= Pad then
  257.                return False;
  258.             end if;
  259.          end loop;
  260.  
  261.          return True;
  262.       end Is_Padding;
  263.  
  264.    --  Start of processing for Move
  265.  
  266.    begin
  267.       if Slength = Tlength then
  268.          Target := Source;
  269.  
  270.       elsif Slength > Tlength then
  271.  
  272.          case Drop is
  273.             when Left =>
  274.                Target := Source (Slast - Tlength + 1 .. Slast);
  275.  
  276.             when Right =>
  277.                Target := Source (Sfirst .. Sfirst + Tlength - 1);
  278.  
  279.             when Error =>
  280.                case Justify is
  281.                   when Left =>
  282.                      if Is_Padding (Source (Sfirst + Tlength .. Slast)) then
  283.                         Target :=
  284.                           Source (Sfirst .. Sfirst + Target'Length - 1);
  285.                      else
  286.                         raise Length_Error;
  287.                      end if;
  288.  
  289.                   when Right =>
  290.                      if Is_Padding (Source (Sfirst .. Slast - Tlength)) then
  291.                         Target := Source (Slast - Tlength + 1 .. Slast);
  292.                      else
  293.                         raise Length_Error;
  294.                      end if;
  295.  
  296.                   when Center =>
  297.                      raise Length_Error;
  298.                end case;
  299.  
  300.          end case;
  301.  
  302.       --  Source'Length < Target'Length
  303.  
  304.       else
  305.          case Justify is
  306.             when Left =>
  307.                Target (Tfirst .. Tfirst + Slength - 1) := Source;
  308.  
  309.                for J in Tfirst + Slength .. Tlast loop
  310.                   Target (J) := Pad;
  311.                end loop;
  312.  
  313.             when Right =>
  314.                for J in Tfirst .. Tlast - Slength loop
  315.                   Target (J) := Pad;
  316.                end loop;
  317.  
  318.                Target (Tlast - Slength + 1 .. Tlast) := Source;
  319.  
  320.             when Center =>
  321.                declare
  322.                   Front_Pad   : constant Integer := (Tlength - Slength) / 2;
  323.                   Tfirst_Fpad : constant Integer := Tfirst + Front_Pad;
  324.  
  325.                begin
  326.                   for J in Tfirst .. Tfirst_Fpad - 1 loop
  327.                      Target (J) := Pad;
  328.                   end loop;
  329.  
  330.                   Target (Tfirst_Fpad .. Tfirst_Fpad + Slength - 1) := Source;
  331.  
  332.                   for J in Tfirst_Fpad + Slength .. Tlast loop
  333.                      Target (J) := Pad;
  334.                   end loop;
  335.                end;
  336.          end case;
  337.       end if;
  338.    end Move;
  339.  
  340.    ---------------
  341.    -- Overwrite --
  342.    ---------------
  343.  
  344.    function Overwrite
  345.      (Source   : in Wide_String;
  346.       Position : in Positive;
  347.       New_Item : in Wide_String)
  348.       return     Wide_String
  349.    is
  350.    begin
  351.       if Position not in Source'First .. Source'Last + 1 then
  352.          raise Index_Error;
  353.       else
  354.          declare
  355.             Result_Length : Natural :=
  356.                 Natural'Max (Source'Length,
  357.                              Position - Source'First + New_Item'Length);
  358.             Result : Wide_String (1 .. Result_Length);
  359.  
  360.          begin
  361.             Result := Source (Source'First .. Position - 1) & New_Item &
  362.                      Source (Position + New_Item'Length .. Source'Last);
  363.             return Result;
  364.          end;
  365.       end if;
  366.    end Overwrite;
  367.  
  368.    procedure Overwrite
  369.      (Source   : in out Wide_String;
  370.       Position : in Positive;
  371.       New_Item : in Wide_String;
  372.       Drop     : in Truncation := Right)
  373.    is
  374.    begin
  375.       Move (Source => Overwrite (Source, Position, New_Item),
  376.             Target => Source,
  377.             Drop   => Drop);
  378.    end Overwrite;
  379.  
  380.    -------------------
  381.    -- Replace_Slice --
  382.    -------------------
  383.  
  384.    function Replace_Slice
  385.      (Source   : in Wide_String;
  386.       Low      : in Positive;
  387.       High     : in Natural;
  388.       By       : in Wide_String)
  389.       return     Wide_String
  390.    is
  391.       Result_Length : Natural;
  392.  
  393.    begin
  394.       if Low > Source'Last + 1 or else High < Source'First - 1 then
  395.          raise Index_Error;
  396.       else
  397.          Result_Length :=
  398.            Source'Length - Natural'Max (High - Low + 1, 0) + By'Length;
  399.  
  400.          declare
  401.             Result : Wide_String (1 .. Result_Length);
  402.  
  403.          begin
  404.             if High >= Low then
  405.                Result :=
  406.                   Source (Source'First .. Low - 1) & By &
  407.                   Source (High + 1 .. Source'Last);
  408.             else
  409.                Result := Source (Source'First .. Low - 1) & By &
  410.                          Source (Low .. Source'Last);
  411.             end if;
  412.             return Result;
  413.          end;
  414.       end if;
  415.    end Replace_Slice;
  416.  
  417.    procedure Replace_Slice
  418.      (Source   : in out Wide_String;
  419.       Low      : in Positive;
  420.       High     : in Natural;
  421.       By       : in Wide_String;
  422.       Drop     : in Truncation := Error;
  423.       Justify  : in Alignment  := Left;
  424.       Pad      : in Wide_Character  := Wide_Space)
  425.    is
  426.    begin
  427.       Move (Replace_Slice (Source, Low, High, By), Source, Drop, Justify, Pad);
  428.    end Replace_Slice;
  429.  
  430.    ----------
  431.    -- Tail --
  432.    ----------
  433.  
  434.    function Tail
  435.      (Source : in Wide_String;
  436.       Count  : in Natural;
  437.       Pad    : in Wide_Character := Wide_Space)
  438.       return   Wide_String
  439.    is
  440.       Result : Wide_String (1 .. Count);
  441.  
  442.    begin
  443.       if Count < Source'Length then
  444.          Result := Source (Source'Last - Count + 1 .. Source'Last);
  445.  
  446.       --  Pad on left
  447.  
  448.       else
  449.          for J in 1 .. Count - Source'Length loop
  450.             Result (J) := Pad;
  451.          end loop;
  452.  
  453.          Result (Count - Source'Length + 1 .. Count) := Source;
  454.       end if;
  455.  
  456.       return Result;
  457.    end Tail;
  458.  
  459.    ---------------
  460.    -- Translate --
  461.    ---------------
  462.  
  463.    function Translate
  464.      (Source  : in Wide_String;
  465.       Mapping : in Wide_Maps.Wide_Character_Mapping)
  466.       return    Wide_String
  467.    is
  468.       Result : Wide_String (1 .. Source'Length);
  469.  
  470.    begin
  471.       for J in Source'Range loop
  472.          Result (J - (Source'First - 1)) := Value (Mapping, Source (J));
  473.       end loop;
  474.  
  475.       return Result;
  476.    end Translate;
  477.  
  478.    procedure Translate
  479.      (Source  : in out Wide_String;
  480.       Mapping : in Wide_Maps.Wide_Character_Mapping)
  481.    is
  482.    begin
  483.       for J in Source'Range loop
  484.          Source (J) := Value (Mapping, Source (J));
  485.       end loop;
  486.    end Translate;
  487.  
  488.    function Translate
  489.      (Source  : in Wide_String;
  490.       Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
  491.       return    Wide_String
  492.    is
  493.       Result : Wide_String (1 .. Source'Length);
  494.  
  495.    begin
  496.       for J in Source'Range loop
  497.          Result (J - (Source'First - 1)) := Mapping (Source (J));
  498.       end loop;
  499.  
  500.       return Result;
  501.    end Translate;
  502.  
  503.    procedure Translate
  504.      (Source  : in out Wide_String;
  505.       Mapping : in Wide_Maps.Wide_Character_Mapping_Function)
  506.    is
  507.    begin
  508.       for J in Source'Range loop
  509.          Source (J) := Mapping (Source (J));
  510.       end loop;
  511.    end Translate;
  512.  
  513.    ----------
  514.    -- Trim --
  515.    ----------
  516.  
  517.    function Trim
  518.      (Source : in Wide_String;
  519.       Side   : in Trim_End)
  520.       return   Wide_String
  521.    is
  522.       Low  : Natural := Source'First;
  523.       High : Natural := Source'Last;
  524.  
  525.    begin
  526.       if Side = Left or else Side = Both then
  527.          while Low <= High and then Source (Low) = Wide_Space loop
  528.             Low := Low + 1;
  529.          end loop;
  530.       end if;
  531.  
  532.       if Side = Right or else Side = Both then
  533.          while High >= Low and then Source (High) = Wide_Space loop
  534.             High := High + 1;
  535.          end loop;
  536.       end if;
  537.  
  538.       --  All blanks case
  539.  
  540.       if Low > High then
  541.          return "";
  542.  
  543.       --  At least one non-blank
  544.  
  545.       else
  546.          declare
  547.             Result : Wide_String (1 .. High - Low + 1) := Source (Low .. High);
  548.  
  549.          begin
  550.             return Result;
  551.          end;
  552.       end if;
  553.    end Trim;
  554.  
  555.    procedure Trim
  556.      (Source  : in out Wide_String;
  557.       Side    : in Trim_End;
  558.       Justify : in Alignment      := Left;
  559.       Pad     : in Wide_Character := Wide_Space)
  560.    is
  561.    begin
  562.       Move (Source  => Trim (Source, Side),
  563.             Target  => Source,
  564.             Justify => Justify,
  565.             Pad     => Pad);
  566.    end Trim;
  567.  
  568.    function Trim
  569.       (Source : in Wide_String;
  570.        Left   : in Wide_Maps.Wide_Character_Set;
  571.        Right  : in Wide_Maps.Wide_Character_Set)
  572.        return   Wide_String
  573.    is
  574.       Low  : Natural := Source'First;
  575.       High : Natural := Source'Last;
  576.  
  577.    begin
  578.       while Low <= High and then Is_In (Source (Low), Left) loop
  579.          Low := Low + 1;
  580.       end loop;
  581.  
  582.       while High >= Low and then Is_In (Source (High), Right) loop
  583.          High := High + 1;
  584.       end loop;
  585.  
  586.       --  Case where source comprises only characters in the sets
  587.  
  588.       if Low > High then
  589.          return "";
  590.       else
  591.          declare
  592.             Result : Wide_String (1 .. High - Low + 1) := Source (Low .. High);
  593.          begin
  594.             return Result;
  595.          end;
  596.       end if;
  597.    end Trim;
  598.  
  599.    procedure Trim
  600.       (Source  : in out Wide_String;
  601.        Left    : in Wide_Maps.Wide_Character_Set;
  602.        Right   : in Wide_Maps.Wide_Character_Set;
  603.        Justify : in Alignment      := Strings.Left;
  604.        Pad     : in Wide_Character := Wide_Space)
  605.    is
  606.    begin
  607.       Move (Source  => Trim (Source, Left, Right),
  608.             Target  => Source,
  609.             Justify => Justify,
  610.             Pad     => Pad);
  611.    end Trim;
  612.  
  613. end Ada.Strings.Wide_Fixed;
  614.