------------------------------------------------------------------------------
--                                                                          --
--                         GNAT RUN-TIME COMPONENTS                         --
--                                                                          --
--                    A D A . S T R I N G S . F I X E D                     --
--                                                                          --
--                                 S p e c                                  --
--                                                                          --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT.  In accordance with the copyright of that document, you can freely --
-- copy and modify this specification,  provided that if you redistribute a --
-- modified version,  any changes that you have made are clearly indicated. --
--                                                                          --
------------------------------------------------------------------------------

--  The language-defined package Strings.Fixed provides string-handling
--  subprograms for fixed-length strings; that is, for values of type
--  Standard.String. Several of these subprograms are procedures that modify
--  the contents of a String that is passed as an out or an in out parameter;
--  each has additional parameters to control the effect when the logical
--  length of the result differs from the parameter's length.
--
--  For each function that returns a String, the lower bound of the returned
--  value is 1.
--
--  The basic model embodied in the package is that a fixed-length string
--  comprises significant characters and possibly padding (with space
--  characters) on either or both ends. When a shorter string is copied to a
--  longer string, padding is inserted, and when a longer string is copied to a
--  shorter one, padding is stripped. The Move procedure in Strings.Fixed,
--  which takes a String as an out parameter, allows the programmer to control
--  these effects. Similar control is provided by the string transformation
--  procedures.

--  Preconditions in this unit are meant for analysis only, not for run-time
--  checking, so that the expected exceptions are raised. This is enforced by
--  setting the corresponding assertion policy to Ignore. Postconditions and
--  contract cases should not be executed at runtime as well, in order not to
--  slow down the execution of these functions.

pragma Assertion_Policy (Pre            => Ignore,
                         Post           => Ignore,
                         Contract_Cases => Ignore,
                         Ghost          => Ignore);

with Ada.Strings.Maps; use type Ada.Strings.Maps.Character_Mapping_Function;
with Ada.Strings.Search;

package Ada.Strings.Fixed with SPARK_Mode is
   pragma Preelaborate;

   --------------------------------------------------------------
   -- Copy Procedure for Strings of Possibly Different Lengths --
   --------------------------------------------------------------

   procedure Move
     (Source  : String;
      Target  : out String;
      Drop    : Truncation := Error;
      Justify : Alignment  := Left;
      Pad     : Character  := Space)
   with

     --  Incomplete contract

     Global => null;
   --  The Move procedure copies characters from Source to Target. If Source
   --  has the same length as Target, then the effect is to assign Source to
   --  Target. If Source is shorter than Target then:
   --
   --  * If Justify=Left, then Source is copied into the first Source'Length
   --    characters of Target.
   --
   --  * If Justify=Right, then Source is copied into the last Source'Length
   --    characters of Target.
   --
   --  * If Justify=Center, then Source is copied into the middle Source'Length
   --    characters of Target. In this case, if the difference in length
   --    between Target and Source is odd, then the extra Pad character is on
   --    the right.
   --
   --  * Pad is copied to each Target character not otherwise assigned.
   --
   --  If Source is longer than Target, then the effect is based on Drop.
   --
   --  * If Drop=Left, then the rightmost Target'Length characters of Source
   --    are copied into Target.
   --
   --  * If Drop=Right, then the leftmost Target'Length characters of Source
   --    are copied into Target.
   --
   --  * If Drop=Error, then the effect depends on the value of the Justify
   --    parameter and also on whether any characters in Source other than Pad
   --    would fail to be copied:
   --
   --    * If Justify=Left, and if each of the rightmost
   --      Source'Length-Target'Length characters in Source is Pad, then the
   --      leftmost Target'Length characters of Source are copied to Target.
   --
   --    * If Justify=Right, and if each of the leftmost
   --      Source'Length-Target'Length characters in Source is Pad, then the
   --      rightmost Target'Length characters of Source are copied to Target.
   --
   --    * Otherwise, Length_Error is propagated.

   ------------------------
   -- Search Subprograms --
   ------------------------

   function Index
     (Source  : String;
      Pattern : String;
      From    : Positive;
      Going   : Direction := Forward;
      Mapping : Maps.Character_Mapping_Function) return Natural
   with
     Pre            => Pattern'Length > 0
       and then Mapping /= null
       and then (if Source'Length > 0 then From in Source'Range),

     Post           => Index'Result in 0 | Source'Range,
     Contract_Cases =>

       --  If Source is the empty string, then 0 is returned

       (Source'Length = 0
        =>
          Index'Result = 0,

        --  If some slice of Source matches Pattern, then a valid index is
        --  returned.

        Source'Length > 0
          and then
            (for some J in
              (if Going = Forward then From else Source'First)
               .. (if Going = Forward then Source'Last else From)
                - (Pattern'Length - 1) =>
              Ada.Strings.Search.Match (Source, Pattern, Mapping, J))
        =>
          --  The result is in the considered range of Source

          Index'Result in
            (if Going = Forward then From else Source'First)
            .. (if Going = Forward then Source'Last else From)
             - (Pattern'Length - 1)

            --  The slice beginning at the returned index matches Pattern

            and then
              Ada.Strings.Search.Match (Source, Pattern, Mapping, Index'Result)

            --  The result is the smallest or largest index which satisfies
            --  the matching, respectively when Going = Forward and Going =
            --  Backward.

            and then
              (for all J in Source'Range =>
                 (if (if Going = Forward
                      then J in From .. Index'Result - 1
                      else J - 1 in Index'Result
                                    .. From - Pattern'Length)
                  then not (Ada.Strings.Search.Match
                              (Source, Pattern, Mapping, J)))),

        --  Otherwise, 0 is returned

        others
        =>
          Index'Result = 0),
     Global         => null;
   pragma Ada_05 (Index);

   function Index
     (Source  : String;
      Pattern : String;
      From    : Positive;
      Going   : Direction := Forward;
      Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
   with
     Pre            => Pattern'Length > 0
       and then (if Source'Length > 0 then From in Source'Range),

     Post           => Index'Result in 0 | Source'Range,
     Contract_Cases =>

       --  If Source is the empty string, then 0 is returned

       (Source'Length = 0
        =>
          Index'Result = 0,

        --  If some slice of Source matches Pattern, then a valid index is
        --  returned.

        Source'Length > 0
          and then
            (for some J in
              (if Going = Forward then From else Source'First)
              .. (if Going = Forward then Source'Last else From)
               - (Pattern'Length - 1) =>
              Ada.Strings.Search.Match (Source, Pattern, Mapping, J))
        =>
          --  The result is in the considered range of Source

          Index'Result in
            (if Going = Forward then From else Source'First)
            .. (if Going = Forward then Source'Last else From)
             - (Pattern'Length - 1)

          --  The slice beginning at the returned index matches Pattern

          and then
            Ada.Strings.Search.Match (Source, Pattern, Mapping, Index'Result)

            --  The result is the smallest or largest index which satisfies the
            --  matching, respectively when Going = Forward and
            --  Going = Backward.

            and then
              (for all J in Source'Range =>
                 (if (if Going = Forward
                      then J in From .. Index'Result - 1
                      else J - 1 in Index'Result
                                    .. From - Pattern'Length)
                  then not (Ada.Strings.Search.Match
                              (Source, Pattern, Mapping, J)))),

        --  Otherwise, 0 is returned

        others
        =>
          Index'Result = 0),
     Global         => null;
   pragma Ada_05 (Index);

   --  Each Index function searches, starting from From, for a slice of
   --  Source, with length Pattern'Length, that matches Pattern with respect to
   --  Mapping; the parameter Going indicates the direction of the lookup. If
   --  Source is the null string, Index returns 0; otherwise, if From is not in
   --  Source'Range, then Index_Error is propagated. If Going = Forward, then
   --  Index returns the smallest index I which is greater than or equal to
   --  From such that the slice of Source starting at I matches Pattern. If
   --  Going = Backward, then Index returns the largest index I such that the
   --  slice of Source starting at I matches Pattern and has an upper bound
   --  less than or equal to From. If there is no such slice, then 0 is
   --  returned. If Pattern is the null string, then Pattern_Error is
   --  propagated.

   function Index
     (Source  : String;
      Pattern : String;
      Going   : Direction := Forward;
      Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
   with
     Pre            => Pattern'Length > 0,

     Post           => Index'Result in 0 | Source'Range,
     Contract_Cases =>

       --  If Source is the empty string, then 0 is returned

       (Source'Length = 0
        =>
          Index'Result = 0,

        --  If some slice of Source matches Pattern, then a valid index is
        --  returned.

        Source'Length > 0
          and then
            (for some J in
              Source'First .. Source'Last - (Pattern'Length - 1) =>
                Ada.Strings.Search.Match (Source, Pattern, Mapping, J))
        =>
          --  The result is in the considered range of Source

          Index'Result in Source'First .. Source'Last - (Pattern'Length - 1)

            --  The slice beginning at the returned index matches Pattern

            and then
              Ada.Strings.Search.Match (Source, Pattern, Mapping, Index'Result)

            --  The result is the smallest or largest index which satisfies
            --  the matching, respectively when Going = Forward and Going =
            --  Backward.

            and then
              (for all J in Source'Range =>
                 (if (if Going = Forward
                      then J <= Index'Result - 1
                      else J - 1 in Index'Result
                                    .. Source'Last - Pattern'Length)
                  then not (Ada.Strings.Search.Match
                              (Source, Pattern, Mapping, J)))),

        --  Otherwise, 0 is returned

        others
        =>
          Index'Result = 0),
     Global         => null;

   function Index
     (Source  : String;
      Pattern : String;
      Going   : Direction := Forward;
      Mapping : Maps.Character_Mapping_Function) return Natural
   with
     Pre            => Pattern'Length > 0 and then Mapping /= null,

     Post           => Index'Result in 0 | Source'Range,
     Contract_Cases =>

       --  If Source is the empty string, then 0 is returned

       (Source'Length = 0
        =>
          Index'Result = 0,

        --  If some slice of Source matches Pattern, then a valid index is
        --  returned.

        Source'Length > 0
          and then
            (for some J in
              Source'First .. Source'Last - (Pattern'Length - 1) =>
                Ada.Strings.Search.Match (Source, Pattern, Mapping, J))
        =>
          --  The result is in the considered range of Source

          Index'Result in Source'First .. Source'Last - (Pattern'Length - 1)

          --  The slice beginning at the returned index matches Pattern

          and then
            Ada.Strings.Search.Match (Source, Pattern, Mapping, Index'Result)

            --  The result is the smallest or largest index which satisfies
            --  the matching, respectively when Going = Forward and Going =
            --  Backward.

            and then
              (for all J in Source'Range =>
                 (if (if Going = Forward
                      then J <= Index'Result - 1
                      else J - 1 in Index'Result
                                    .. Source'Last - Pattern'Length)
                  then not (Ada.Strings.Search.Match
                              (Source, Pattern, Mapping, J)))),

        --  Otherwise, 0 is returned

        others
        =>
          Index'Result = 0),
     Global         => null;

   --  If Going = Forward, returns:
   --
   --     Index (Source, Pattern, Source'First, Forward, Mapping)
   --
   --  otherwise, returns:
   --
   --     Index (Source, Pattern, Source'Last, Backward, Mapping).

   function Index
     (Source : String;
      Set    : Maps.Character_Set;
      Test   : Membership := Inside;
      Going  : Direction  := Forward) return Natural
   with
     Post           => Index'Result in 0 | Source'Range,
     Contract_Cases =>

        --  If no character of Source satisfies the property Test on Set, then
        --  0 is returned.

       ((for all C of Source =>
           (Test = Inside) /= Ada.Strings.Maps.Is_In (C, Set))
        =>
          Index'Result = 0,

        --  Otherwise, an index in the range of Source is returned

        others
        =>

          --  The result is in the range of Source

          Index'Result in Source'Range

            --  The character at the returned index satisfies the property
            --  Test on Set.

            and then
              (Test = Inside)
              = Ada.Strings.Maps.Is_In (Source (Index'Result), Set)

            --  The result is the smallest or largest index which satisfies
            --  the property, respectively when Going = Forward and Going =
            --  Backward.

            and then
              (for all J in Source'Range =>
                 (if J /= Index'Result
                       and then (J < Index'Result) = (Going = Forward)
                  then (Test = Inside)
                       /= Ada.Strings.Maps.Is_In (Source (J), Set)))),
     Global         => null;

   function Index
     (Source  : String;
      Set     : Maps.Character_Set;
      From    : Positive;
      Test    : Membership := Inside;
      Going   : Direction := Forward) return Natural
   with
     Pre            => (if Source'Length > 0 then From in Source'Range),
     Post           => Index'Result in 0 | Source'Range,
     Contract_Cases =>

        --  If Source is the empty string, or no character of the considered
        --  slice of Source satisfies the property Test on Set, then 0 is
        --  returned.

        (Source'Length = 0
          or else
            (for all J in Source'Range =>
               (if J = From or else (J > From) = (Going = Forward) then
                  (Test = Inside) /= Ada.Strings.Maps.Is_In (Source (J), Set)))
        =>
          Index'Result = 0,

        --  Otherwise, an index in the considered range of Source is returned

        others
        =>

          --  The result is in the considered range of Source

          Index'Result in Source'Range
            and then (Index'Result = From
                       or else
                         (Index'Result > From) = (Going = Forward))

            --  The character at the returned index satisfies the property
            --  Test on Set.

            and then
              (Test = Inside)
              = Ada.Strings.Maps.Is_In (Source (Index'Result), Set)

            --  The result is the smallest or largest index which satisfies
            --  the property, respectively when Going = Forward and Going =
            --  Backward.

            and then
              (for all J in Source'Range =>
                 (if J /= Index'Result
                    and then (J < Index'Result) = (Going = Forward)
                    and then (J = From
                                or else (J > From) = (Going = Forward))
                  then (Test = Inside)
                       /= Ada.Strings.Maps.Is_In (Source (J), Set)))),
     Global         => null;
   pragma Ada_05 (Index);
   --  Index searches for the first or last occurrence of any of a set of
   --  characters (when Test=Inside), or any of the complement of a set of
   --  characters (when Test=Outside). If Source is the null string, Index
   --  returns 0; otherwise, if From is not in Source'Range, then Index_Error
   --  is propagated. Otherwise, it returns the smallest index I >= From (if
   --  Going=Forward) or the largest index I <= From (if Going=Backward) such
   --  that Source(I) satisfies the Test condition with respect to Set; it
   --  returns 0 if there is no such Character in Source.

   function Index_Non_Blank
     (Source : String;
      From   : Positive;
      Going  : Direction := Forward) return Natural
   with
     Pre            => (if Source'Length /= 0 then From in Source'Range),

     Post           => Index_Non_Blank'Result in 0 | Source'Range,
     Contract_Cases =>

        --  If Source is the empty string, or all characters in the considered
        --  slice of Source are Space characters, then 0 is returned.

        (Source'Length = 0
          or else
            (for all J in Source'Range =>
               (if J = From or else (J > From) = (Going = Forward) then
                  Source (J) = ' '))
        =>
          Index_Non_Blank'Result = 0,

        --  Otherwise, a valid index is returned

        others
        =>

          --  The result is in the considered range of Source

          Index_Non_Blank'Result in Source'Range
            and then (Index_Non_Blank'Result = From
                        or else (Index_Non_Blank'Result > From)
                                = (Going = Forward))

            --  The character at the returned index is not a Space character

            and then Source (Index_Non_Blank'Result) /= ' '

            --  The result is the smallest or largest index which is not a
            --  Space character, respectively when Going = Forward and
            --  Going = Backward.

            and then
              (for all J in Source'Range =>
                 (if J /= Index_Non_Blank'Result
                       and then (J < Index_Non_Blank'Result)
                                = (Going = Forward)
                       and then (J = From or else (J > From)
                                = (Going = Forward))
                  then Source (J) = ' '))),
     Global         => null;
   pragma Ada_05 (Index_Non_Blank);
   --  Returns Index (Source, Maps.To_Set(Space), From, Outside, Going)

   function Index_Non_Blank
     (Source : String;
      Going  : Direction := Forward) return Natural
   with
     Post           => Index_Non_Blank'Result in 0 | Source'Range,
     Contract_Cases =>

        --  If all characters of Source are Space characters, then 0 is
        --  returned.

       ((for all C of Source => C = ' ') => Index_Non_Blank'Result = 0,

        --  Otherwise, a valid index is returned

        others                           =>

          --  The result is in the range of Source

          Index_Non_Blank'Result in Source'Range

            --  The character at the returned index is not a Space character

            and then Source (Index_Non_Blank'Result) /= ' '

            --  The result is the smallest or largest index which is not a
            --  Space character, respectively when Going = Forward and Going
            --  = Backward.

            and then
              (for all J in Source'Range =>
                 (if J /= Index_Non_Blank'Result
                       and then (J < Index_Non_Blank'Result)
                              = (Going = Forward)
                  then Source (J) = ' '))),
     Global         => null;
   --  Returns Index (Source, Maps.To_Set(Space), Outside, Going)

   function Count
     (Source  : String;
      Pattern : String;
      Mapping : Maps.Character_Mapping := Maps.Identity) return Natural
   with
     Pre    => Pattern'Length /= 0,
     Global => null;

   function Count
     (Source  : String;
      Pattern : String;
      Mapping : Maps.Character_Mapping_Function) return Natural
   with
     Pre    => Pattern'Length /= 0 and then Mapping /= null,
     Global => null;

   --  Returns the maximum number of nonoverlapping slices of Source that match
   --  Pattern with respect to Mapping. If Pattern is the null string then
   --  Pattern_Error is propagated.

   function Count
     (Source : String;
      Set    : Maps.Character_Set) return Natural
   with
     Global => null;
   --  Returns the number of occurrences in Source of characters that are in
   --  Set.

   procedure Find_Token
     (Source : String;
      Set    : Maps.Character_Set;
      From   : Positive;
      Test   : Membership;
      First  : out Positive;
      Last   : out Natural)
   with
     Pre            => (if Source'Length /= 0 then From in Source'Range),
     Contract_Cases =>

        --  If Source is the empty string, or if no character of the considered
        --  slice of Source satisfies the property Test on Set, then First is
        --  set to From and Last is set to 0.

       (Source'Length = 0
          or else
            (for all C of Source (From .. Source'Last) =>
               (Test = Inside) /= Ada.Strings.Maps.Is_In (C, Set))
        =>
          First = From and then Last = 0,

        --  Otherwise, First and Last are set to valid indexes

        others
        =>

          --  First and Last are in the considered range of Source

          First in From .. Source'Last
            and then Last in First .. Source'Last

            --  No character between From and First satisfies the property Test
            --  on Set.

            and then
              (for all C of Source (From .. First - 1) =>
                 (Test = Inside) /= Ada.Strings.Maps.Is_In (C, Set))

            --  All characters between First and Last satisfy the property Test
            --  on Set.

            and then
              (for all C of Source (First .. Last) =>
                 (Test = Inside) = Ada.Strings.Maps.Is_In (C, Set))

            --  If Last is not Source'Last, then the character at position
            --  Last + 1 does not satify the property Test on Set.

            and then
              (if Last < Source'Last
               then
                 (Test = Inside)
                 /= Ada.Strings.Maps.Is_In (Source (Last + 1), Set))),
     Global         => null;
   pragma Ada_2012 (Find_Token);
   --  If Source is not the null string and From is not in Source'Range, then
   --  Index_Error is raised. Otherwise, First is set to the index of the first
   --  character in Source(From .. Source'Last) that satisfies the Test
   --  condition. Last is set to the largest index such that all characters in
   --  Source(First .. Last) satisfy the Test condition. If no characters in
   --  Source(From .. Source'Last) satisfy the Test condition, First is set to
   --  From, and Last is set to 0.

   procedure Find_Token
     (Source : String;
      Set    : Maps.Character_Set;
      Test   : Membership;
      First  : out Positive;
      Last   : out Natural)
   with
     Pre            => Source'First > 0,
     Contract_Cases =>

        --  If Source is the empty string, or if no character of Source
        --  satisfies the property Test on Set, then First is set to From and
        --  Last is set to 0.

       (Source'Length = 0
          or else
            (for all C of Source =>
               (Test = Inside) /= Ada.Strings.Maps.Is_In (C, Set))
        =>
          First = Source'First and then Last = 0,

        --  Otherwise, First and Last are set to valid indexes

        others
        =>

          --  First and Last are in the considered range of Source

          First in Source'Range
            and then Last in First .. Source'Last

            --  No character before First satisfies the property Test on Set

            and then
              (for all C of Source (Source'First .. First - 1) =>
                 (Test = Inside) /= Ada.Strings.Maps.Is_In (C, Set))

            --  All characters between First and Last satisfy the property Test
            --  on Set.

            and then
              (for all C of Source (First .. Last) =>
                 (Test = Inside) = Ada.Strings.Maps.Is_In (C, Set))

            --  If Last is not Source'Last, then the character at position
            --  Last + 1 does not satify the property Test on Set.

            and then
              (if Last < Source'Last
               then
                 (Test = Inside)
                 /= Ada.Strings.Maps.Is_In (Source (Last + 1), Set))),
     Global => null;
   --  Equivalent to Find_Token (Source, Set, Source'First, Test, First, Last)

   ------------------------------------
   -- String Translation Subprograms --
   ------------------------------------

   function Translate
     (Source  : String;
      Mapping : Maps.Character_Mapping_Function) return String
   with
     Pre    => Mapping /= null,
     Post   =>

       --  Lower bound of the returned string is 1

       Translate'Result'First = 1

         --  The returned string has the same length as Source

         and then Translate'Result'Last = Source'Length

         --  Each character in the returned string is the translation of the
         --  character at the same position in Source through Mapping.

         and then
           (for all J in Source'Range =>
              Translate'Result (J - Source'First + 1)
              = Mapping (Source (J))),
     Global => null;

   function Translate
     (Source  : String;
      Mapping : Maps.Character_Mapping) return String
   with
     Post   =>

       --  Lower bound of the returned string is 1

       Translate'Result'First = 1

         --  The returned string has the same length as Source

         and then Translate'Result'Last = Source'Length

         --  Each character in the returned string is the translation of the
         --  character at the same position in Source through Mapping.

         and then
           (for all J in Source'Range =>
              Translate'Result (J - Source'First + 1)
              = Ada.Strings.Maps.Value (Mapping, Source (J))),
     Global => null;

   --  Returns the string S whose length is Source'Length and such that S (I)
   --  is the character to which Mapping maps the corresponding element of
   --  Source, for I in 1 .. Source'Length.

   procedure Translate
     (Source  : in out String;
      Mapping : Maps.Character_Mapping_Function)
   with
     Pre    => Mapping /= null,
     Post   =>

       --  Each character in Source after the call is the translation of the
       --  character at the same position before the call, through Mapping.

       (for all J in Source'Range => Source (J) = Mapping (Source'Old (J))),
     Global => null;

   procedure Translate
     (Source  : in out String;
      Mapping : Maps.Character_Mapping)
   with
     Post   =>

       --  Each character in Source after the call is the translation of the
       --  character at the same position before the call, through Mapping.

       (for all J in Source'Range =>
          Source (J) = Ada.Strings.Maps.Value (Mapping, Source'Old (J))),
     Global => null;

   --  Equivalent to Source := Translate(Source, Mapping)

   ---------------------------------------
   -- String Transformation Subprograms --
   ---------------------------------------

   function Replace_Slice
     (Source : String;
      Low    : Positive;
      High   : Natural;
      By     : String) return String
   with
     Pre            =>
       Low - 1 <= Source'Last
         and then High >= Source'First - 1
         and then (if High >= Low
                   then Natural'Max (0, Low - Source'First)
                        <= Natural'Last
                           - By'Length
                           - Natural'Max (Source'Last - High, 0)
                   else Source'Length <= Natural'Last - By'Length),

     --  Lower bound of the returned string is 1

     Post           => Replace_Slice'Result'First = 1,
     Contract_Cases =>

        --  If High >= Low, then the returned string comprises
        --  Source (Source'First .. Low - 1) & By
        --  & Source(High + 1 .. Source'Last).

       (High >= Low =>

          --  Length of the returned string

          Replace_Slice'Result'Length
          = Integer'Max (0, Low - Source'First)
            + By'Length
            + Integer'Max (Source'Last - High, 0)

            --  Elements starting at Low are replaced by elements of By

            and then
              Replace_Slice'Result (1 .. Integer'Max (0, Low - Source'First))
              = Source (Source'First .. Low - 1)
            and then
              Replace_Slice'Result
                (Integer'Max (0, Low - Source'First) + 1
                 .. Integer'Max (0, Low - Source'First) + By'Length)
              = By

            --  When there are remaining characters after the replaced slice,
            --  they are appended to the result.

            and then
              (if High < Source'Last
               then
                 Replace_Slice'Result
                   (Integer'Max (0, Low - Source'First) + By'Length + 1
                    .. Replace_Slice'Result'Last)
                 = Source (High + 1 .. Source'Last)),

        --  If High < Low, then the returned string is
        --  Insert (Source, Before => Low, New_Item => By).

        others      =>

          --  Length of the returned string

          Replace_Slice'Result'Length = Source'Length + By'Length

            --  Elements of By are inserted after the element at Low

            and then
              Replace_Slice'Result (1 .. Low - Source'First)
              = Source (Source'First .. Low - 1)
            and then
              Replace_Slice'Result
                (Low - Source'First + 1 .. Low - Source'First + By'Length)
              = By

            --  When there are remaining characters after Low in Source, they
            --  are appended to the result.

            and then
              (if Low < Source'Last
               then
                Replace_Slice'Result
                  (Low - Source'First + By'Length + 1
                   .. Replace_Slice'Result'Last)
                = Source (Low .. Source'Last))),
     Global         => null;
   --  If Low > Source'Last + 1, or High < Source'First - 1, then Index_Error
   --  is propagated. Otherwise:
   --
   --  * If High >= Low, then the returned string comprises
   --    Source (Source'First .. Low - 1)
   --    & By & Source(High + 1 .. Source'Last), but with lower bound 1.
   --
   --  * If High < Low, then the returned string is
   --    Insert (Source, Before => Low, New_Item => By).

   procedure Replace_Slice
     (Source  : in out String;
      Low     : Positive;
      High    : Natural;
      By      : String;
      Drop    : Truncation := Error;
      Justify : Alignment  := Left;
      Pad     : Character  := Space)
   with
     Pre    =>
       Low - 1 <= Source'Last
         and then High >= Source'First - 1
         and then (if High >= Low
                   then Natural'Max (0, Low - Source'First)
                        <= Natural'Last
                           - By'Length
                           - Natural'Max (Source'Last - High, 0)
                   else Source'Length <= Natural'Last - By'Length),

   --  Incomplete contract

     Global => null;
   --  Equivalent to:
   --
   --    Move (Replace_Slice (Source, Low, High, By),
   --          Source, Drop, Justify, Pad).

   function Insert
     (Source   : String;
      Before   : Positive;
      New_Item : String) return String
   with
     Pre    =>
       Before - 1 in Source'First - 1 .. Source'Last
         and then Source'Length <= Natural'Last - New_Item'Length,

     Post   =>

       --  Lower bound of the returned string is 1

       Insert'Result'First = 1

         --  Length of the returned string

         and then Insert'Result'Length = Source'Length + New_Item'Length

         --  Elements of New_Item are inserted after element at Before

         and then
           Insert'Result (1 .. Before - Source'First)
           = Source (Source'First .. Before - 1)
         and then
           Insert'Result
             (Before - Source'First + 1
              .. Before - Source'First + New_Item'Length)
           = New_Item

         --  When there are remaining characters after Before in Source, they
         --  are appended to the returned string.

         and then
           (if Before <= Source'Last
            then
              Insert'Result
                (Before - Source'First + New_Item'Length + 1
                 .. Insert'Result'Last)
              = Source (Before .. Source'Last)),
     Global => null;
   --  Propagates Index_Error if Before is not in
   --  Source'First .. Source'Last + 1; otherwise, returns
   --  Source (Source'First .. Before - 1)
   --  & New_Item & Source(Before..Source'Last), but with lower bound 1.

   procedure Insert
     (Source   : in out String;
      Before   : Positive;
      New_Item : String;
      Drop     : Truncation := Error)
   with
     Pre    =>
       Before - 1 in Source'First - 1 .. Source'Last
         and then Source'Length <= Natural'Last - New_Item'Length,

     --  Incomplete contract

     Global => null;
   --  Equivalent to Move (Insert (Source, Before, New_Item), Source, Drop)

   function Overwrite
     (Source   : String;
      Position : Positive;
      New_Item : String) return String
   with
     Pre    =>
       Position - 1 in Source'First - 1 .. Source'Last
         and then
           (if Position - Source'First >= Source'Length - New_Item'Length
            then Position - Source'First <= Natural'Last - New_Item'Length),

     Post   =>

       --  Lower bound of the returned string is 1

       Overwrite'Result'First = 1

         --  Length of the returned string

         and then
           Overwrite'Result'Length
           = Integer'Max (Source'Length,
                          Position - Source'First + New_Item'Length)

         --  Elements after Position are replaced by elements of New_Item

         and then
           Overwrite'Result (1 .. Position - Source'First)
           = Source (Source'First .. Position - 1)
         and then
           Overwrite'Result
             (Position - Source'First + 1
              .. Position - Source'First + New_Item'Length)
           = New_Item

         --  If the end of Source is reached before the characters in New_Item
         --  are exhausted, the remaining characters from New_Item are appended
         --  to the string.

         and then
           (if Position <= Source'Last - New_Item'Length
            then
              Overwrite'Result
                (Position - Source'First + New_Item'Length + 1
                 .. Overwrite'Result'Last)
              = Source (Position + New_Item'Length .. Source'Last)),
     Global => null;
   --  Propagates Index_Error if Position is not in
   --  Source'First .. Source'Last + 1; otherwise, returns the string obtained
   --  from Source by consecutively replacing characters starting at Position
   --  with corresponding characters from New_Item. If the end of Source is
   --  reached before the characters in New_Item are exhausted, the remaining
   --  characters from New_Item are appended to the string.

   procedure Overwrite
     (Source   : in out String;
      Position : Positive;
      New_Item : String;
      Drop     : Truncation := Right)
   with
     Pre    =>
       Position - 1 in Source'First - 1 .. Source'Last
         and then
           (if Position - Source'First >= Source'Length - New_Item'Length
            then Position - Source'First <= Natural'Last - New_Item'Length),

     --  Incomplete contract

     Global => null;
   --  Equivalent to Move(Overwrite(Source, Position, New_Item), Source, Drop)

   function Delete
     (Source  : String;
      From    : Positive;
      Through : Natural) return String
   with
     Pre            => (if From <= Through
                        then (From in Source'Range
                                and then Through <= Source'Last)),

     --  Lower bound of the returned string is 1

     Post           =>
       Delete'Result'First = 1,

     Contract_Cases =>

        --  If From <= Through, the characters between From and Through are
        --  removed.

       (From <= Through =>

          --  Length of the returned string

          Delete'Result'Length = Source'Length - (Through - From + 1)

            --  Elements before From are preserved

            and then
              Delete'Result (1 .. From - Source'First)
              = Source (Source'First .. From - 1)

            --  If there are remaining characters after Through, they are
            --  appended to the returned string.

            and then
              (if Through < Source'Last
               then Delete'Result
                      (From - Source'First + 1 .. Delete'Result'Last)
                    = Source (Through + 1 .. Source'Last)),

        --  Otherwise, the returned string is Source with lower bound 1

        others          =>
          Delete'Result'Length = Source'Length
            and then Delete'Result = Source),
     Global         => null;
   --  If From <= Through, the returned string is
   --  Replace_Slice(Source, From, Through, ""); otherwise, it is Source with
   --  lower bound 1.

   procedure Delete
     (Source  : in out String;
      From    : Positive;
      Through : Natural;
      Justify : Alignment := Left;
      Pad     : Character := Space)
   with
     Pre    => (if From <= Through
                then (From in Source'Range
                        and then Through <= Source'Last)),

     --  Incomplete contract

     Global => null;
   --  Equivalent to:
   --
   --     Move (Delete (Source, From, Through),
   --           Source, Justify => Justify, Pad => Pad).

   ---------------------------------
   -- String Selector Subprograms --
   ---------------------------------

   function Trim
     (Source : String;
      Side   : Trim_End) return String
   with
     Post   =>

       --  Lower bound of the returned string is 1

       Trim'Result'First = 1

       --  If all characters in Source are Space, the returned string is
       --  empty.

         and then
           (if (for all J in Source'Range => Source (J) = ' ')
            then Trim'Result = ""

            --  Otherwise, the returned string is a slice of Source

            else
              (declare
                 Low  : constant Positive :=
                   (if Side = Right then Source'First
                    else Index_Non_Blank (Source, Forward));
                 High : constant Positive :=
                   (if Side = Left then Source'Last
                    else Index_Non_Blank (Source, Backward));
               begin
                 Trim'Result = Source (Low .. High))),
     Global => null;
   --  Returns the string obtained by removing from Source all leading Space
   --  characters (if Side = Left), all trailing Space characters (if
   --  Side = Right), or all leading and trailing Space characters (if
   --  Side = Both).

   procedure Trim
     (Source  : in out String;
      Side    : Trim_End;
      Justify : Alignment := Left;
      Pad     : Character := Space)
   with

     --  Incomplete contract

     Global => null;
   --  Equivalent to:
   --
   --     Move (Trim (Source, Side), Source, Justify=>Justify, Pad=>Pad).

   function Trim
     (Source : String;
      Left   : Maps.Character_Set;
      Right  : Maps.Character_Set) return String
   with
     Post   =>

       --  Lower bound of the returned string is 1

       Trim'Result'First = 1

         --  If all characters are contained in one of the sets Left and Right,
         --  then the returned string is empty.

         and then
           (if (for all K in Source'Range =>
                  Ada.Strings.Maps.Is_In (Source (K), Left))
                 or
                   (for all K in Source'Range =>
                      Ada.Strings.Maps.Is_In (Source (K), Right))
            then Trim'Result = ""

        --  Otherwise, the returned string is a slice of Source

        else
           (declare
              Low  : constant Positive :=
                Index (Source, Left, Outside, Forward);
              High : constant Positive :=
                Index (Source, Right, Outside, Backward);
            begin
              Trim'Result = Source (Low .. High))),
     Global => null;
   --  Returns the string obtained by removing from Source all leading
   --  characters in Left and all trailing characters in Right.

   procedure Trim
     (Source  : in out String;
      Left    : Maps.Character_Set;
      Right   : Maps.Character_Set;
      Justify : Alignment := Strings.Left;
      Pad     : Character := Space)
   with

     --  Incomplete contract

     Global => null;
   --  Equivalent to:
   --
   --     Move (Trim (Source, Left, Right),
   --           Source, Justify => Justify, Pad=>Pad).

   function Head
     (Source : String;
      Count  : Natural;
      Pad    : Character := Space) return String
   with
     Post           =>

       --  Lower bound of the returned string is 1

       Head'Result'First = 1

         --  Length of the returned string is Count.

         and then Head'Result'Length = Count,

     Contract_Cases =>

        --  If Count <= Source'Length, then the first Count characters of
        --  Source are returned.

       (Count <= Source'Length =>
          Head'Result = Source (Source'First .. Source'First - 1 + Count),

        --  Otherwise, the returned string is Source concatenated with
        --  Count - Source'Length Pad characters.

        others                 =>
          Head'Result (1 .. Source'Length) = Source
            and then
              Head'Result (Source'Length + 1 .. Count)
              = (1 .. Count - Source'Length => Pad)),
     Global         => null;
   --  Returns a string of length Count. If Count <= Source'Length, the string
   --  comprises the first Count characters of Source. Otherwise, its contents
   --  are Source concatenated with Count - Source'Length Pad characters.

   procedure Head
     (Source  : in out String;
      Count   : Natural;
      Justify : Alignment := Left;
      Pad     : Character := Space)
   with

     --  Incomplete contract

     Global => null;
   --  Equivalent to:
   --
   --     Move (Head (Source, Count, Pad),
   --           Source, Drop => Error, Justify => Justify, Pad => Pad).

   function Tail
     (Source : String;
      Count  : Natural;
      Pad    : Character := Space) return String
   with
     Post   =>

       --  Lower bound of the returned string is 1

       Tail'Result'First = 1

         --  Length of the returned string is Count

         and then Tail'Result'Length = Count,
     Contract_Cases =>

       --  If Count is zero, then the returned string is empty

       (Count = 0                     =>
          Tail'Result = "",

        --  Otherwise, if Count <= Source'Length, then the last Count
        --  characters of Source are returned.

        (Count in 1 .. Source'Length) =>
          Tail'Result = Source (Source'Last - Count + 1 .. Source'Last),

        --  Otherwise, the returned string is Count - Source'Length Pad
        --  characters concatenated with Source.

        others                        =>

           --  If Source is empty, then the returned string is Count Pad
           --  characters.

          (if Source'Length = 0
           then Tail'Result = (1 .. Count => Pad)
           else
             Tail'Result (1 .. Count - Source'Length)
             = (1 .. Count - Source'Length => Pad)
               and then
                 Tail'Result (Count - Source'Length + 1 .. Tail'Result'Last)
                 = Source)),
     Global => null;
   --  Returns a string of length Count. If Count <= Source'Length, the string
   --  comprises the last Count characters of Source. Otherwise, its contents
   --  are Count-Source'Length Pad characters concatenated with Source.

   procedure Tail
     (Source  : in out String;
      Count   : Natural;
      Justify : Alignment := Left;
      Pad     : Character := Space)
   with

     --  Incomplete contract

     Global => null;
   --  Equivalent to:
   --
   --     Move (Tail (Source, Count, Pad),
   --           Source, Drop => Error, Justify => Justify, Pad => Pad).

   ----------------------------------
   -- String Constructor Functions --
   ----------------------------------

   function "*"
     (Left  : Natural;
      Right : Character) return String
   with
     Post   =>

       --  Lower bound of the returned string is 1

       "*"'Result'First = 1

         --  Length of the returned string

         and then "*"'Result'Length = Left

         --  All characters of the returned string are Right

         and then (for all C of "*"'Result => C = Right),
     Global => null;

   function "*"
     (Left  : Natural;
      Right : String) return String
   with
     Pre    => (if Right'Length /= 0 then Left <= Natural'Last / Right'Length),

     Post   =>

       --  Lower bound of the returned string is 1

       "*"'Result'First = 1

         --  Length of the returned string

         and then "*"'Result'Length = Left * Right'Length

         --  Content of the string is Right concatenated with itself Left times

         and then
           (for all K in "*"'Result'Range =>
              "*"'Result (K) = Right (Right'First + (K - 1) mod Right'Length)),
     Global => null;

   --  These functions replicate a character or string a specified number of
   --  times. The first function returns a string whose length is Left and each
   --  of whose elements is Right. The second function returns a string whose
   --  length is Left * Right'Length and whose value is the null string if
   --  Left = 0 and otherwise is (Left - 1)*Right & Right with lower bound 1.

end Ada.Strings.Fixed;
