DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400 Tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400 Tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T V

⟦80d32dbdf⟧ TextFile

    Length: 21571 (0x5443)
    Types: TextFile
    Names: »V«

Derivation

└─⟦180fe333a⟧ Bits:30000405 8mm tape, Rational 1000, SW CATALOG, 10_20_0
└─⟦180fe333a⟧ Bits:30000537 8mm tape, Rational 1000, SW Catalog 10_20_0
    └─⟦5cb1d1d7f⟧ »DATA« 
        └─⟦3b1ee7bd8⟧ 
            └─⟦this⟧ 

TextFile

package String_Pkg is

    --| Overview:
    --| Package string_pkg exports an abstract data type, string_type.  A
    --| string_type value is a sequence of characters.  The values have arbitrary
    --| length.  For a value, s, with length, l, the individual characters are
    --| numbered from 1 to l.  These values are immutable; characters cannot be
    --| replaced or appended in a destructive fashion.
    --|
    --| In the documentation for this package, we are careful to distinguish
    --| between string_type objects, which are Ada objects in the usual sense,
    --| and string_type values, the members of this data abstraction as described
    --| above.  A string_type value is said to be associated with, or bound to,
    --| a string_type object after an assignment (:=) operation.
    --|
    --| The operations provided in this package fall into three categories:
    --|
    --| 1. Constructors:  These functions typically take one or more string_type
    --|      objects as arguments.  They work with the values associated with
    --|      these objects, and return new string_type values according to
    --|      specification.  By a slight abuse of language, we will sometimes
    --|      coerce from string_type objects to values for ease in description.
    --|
    --| 2. Heap Management:
    --|      These operations (make_persistent, flush, mark, release) control the
    --|      management of heap space.  Because string_type values are
    --|      allocated on the heap, and the type is not limited, it is necessary
    --|      for a user to assume some responsibility for garbage collection.
    --|      String_type is not limited because of the convenience of
    --|      the assignment operation, and the usefulness of being able to
    --|      instantiate generic units that contain private type formals.
    --|      ** Important: To use this package properly, it is necessary to read
    --|      the descriptions of the operations in this section.
    --|
    --| 3. Queries:  These functions return information about the values
    --|      that are associated with the argument objects.  The same conventions
    --|      for description of operations used in (1) is adopted.
    --|
    --| A note about design decisions...  The decision to not make the type
    --| limited causes two operations to be carried over from the representation.
    --| These are the assignment operation, :=, and the "equality" operator, "=".
    --| See the discussion at the beginning of the Heap Management section for a
    --| discussion of :=.
    --| See the spec for the first of the equal functions for a discussion of "=".
    --|
    --| The following is a complete list of operations, written in the order
    --| in which they appear in the spec.  Overloaded subprograms are followed
    --| by (n), where n is the number of subprograms of that name.
    --|
    --| 1. Constructors:
    --|        create
    --|        "&" (3)
    --|        substr
    --|        splice
    --|        insert (3)
    --| t (2)
    --|        flush
    --|        mark, release
    --| 3. Queries:
    --|        is_empty
    --|        length
    --|        value
    --|        fetch
    --|        equal (3)
    --|        "<" (3),
    --|ot_c
    --|        match_s (2)
    --|        match_any (2)
    --|        match_none (2)

    --| Notes:
    --| Programmer: Ron Kownacki

    type String_Type is private;

    Bounds : exception;  --| Raised on index out of bounds.
    Any_Empty : exception;  --| Raised on incorrect use of match_any.
    Illegal_Alloc : exception;  --| Raised by value creating operations.
    Illegal_Dealloc : exception;  --| Raised by release.


    -- Constructors:

    function Create (S : in String) return String_Type;

    --| Raises: illegal_alloc
    --| Effects:
    --| Return a value consisting of the sequence of characters in s.
    --| Sometimes useful for array or record aggregates.
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function "&" (S1, S2 : in String_Type) return String_Type;

    --| Raises: illegal_alloc
    --| Effects:
    --| Return the concatenation of s1 and s2.
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function "&" (S1 : in String_Type; S2 : in String) return String_Type;

    --| Raises: illegal_alloc
    --| Effects:
    --| Return the concatenation of s1 and create(s2).
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function "&" (S1 : in String; S2 : in String_Type) return String_Type;

    --| Raises: illegal_alloc
    --| Effects:
    --| Return the concatenation of create(s1) and s2.
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function Substr (S : in String_Type; I : in Positive; Len : in Natural)
                    return String_Type;

    --| Raises: bounds, illegal_alloc
    --| Effects:
    --| Return the substring, of specified length, that occurs in s at
    --| position i.  If len = 0, then returns the empty value.
    --| Otherwise, raises bounds if either i or (i + len - 1)
    --| is not in 1..length(s).
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function Splice (S : in String_Type; I : in Positive; Len : in Natural)
                    return String_Type;

    --| Raises: bounds, illegal_alloc
    --| Effects:
    --| Let s be the string, abc, where a, b and c are substrings.  If
    --| substr(s, i, length(b)) = b, for some i in 1..length(s), then
    --| splice(s, i, length(b)) = ac.
    --| Returns a value equal to s if len = 0.  Otherwise, raises bounds if
    --| either i or (i + len - 1) is not in 1..length(s).
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function Insert (S1, S2 : in String_Type; I : in Positive)
                    return String_Type;

    --| Raises: bounds, illegal_alloc
    --| Effects:
    --| Return substr(s1, 1, i - 1) & s2 &
    --|        substr(s1, i, length(s1) - i + 1).
    --| equal(splice(insert(s1, s2, i), i, length(s2)), s1) holds if no
    --| exception is raised by insert.
    --| Raises bounds if is_empty(s1) or else i is not in 1..length(s1).
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function Insert (S1 : in String_Type; S2 : in String; I : in Positive)
                    return String_Type;

    --| Raises: bounds, illegal_alloc
    --| Effects:
    --| Return substr(s1, 1, i - 1) & s2 &
    --|        substr(s1, i, length(s1) - i + 1).
    --| equal(splice(insert(s1, s2, i), i, length(s2)), s1) holds if no
    --| exception is raised by insert.
    --| Raises bounds if is_empty(s1) or else i is not in 1..length(s1).
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function Insert (S1 : in String; S2 : in String_Type; I : in Positive)
                    return String_Type;

    --| Raises: bounds, illegal_alloc
    --| Effects:
    --| Return s1(s1'first..i - 1) & s2 &
    --|        s1(i..length(s1) - i + 1).
    --| equal(splice(insert(s1, s2, i), i, length(s2)), s1) holds if no
    --| exception is raised by insert.
    --| Raises bounds if i is not in s'range.
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function Lower (S : in String) return String_Type;

    --| Raises: illegal_alloc
    --| Effects:
    --| Return a value that contains exactly those characters in s with
    --| the exception that all upper case characters are replaced by their
    --| lower case counterparts.
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function Lower (S : in String_Type) return String_Type;

    --| Raises: illegal_alloc
    --| Effects:
    --| Return a value that is a copy of s with the exception that all
    --| upper case characters are replaced by their lower case counterparts.
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function Upper (S : in String) return String_Type;

    --| Raises: illegal_alloc
    --| Effects:
    --| Return a value that contains exactly those characters in s with
    --| the exception that all lower case characters are replaced by their
    --| upper case counterparts.
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)

    function Upper (S : in String_Type) return String_Type;

    --| Raises: illegal_alloc
    --| Effects:
    --| Return a value that is a copy of s with the exception that all
    --| lower case characters are replaced by their upper case counterparts.
    --| Raises illegal_alloc if string space has been improperly
    --| released.  (See procedures mark/release.)


    -- Heap Management (including object/value binding):
    --
    -- Two forms of heap management are provided.  The general scheme is to "mark"
    -- the current state of heap usage, and to "release" in order to reclaim all
    -- space that has been used since the last mark.  However, this alone is
    -- insufficient because it is frequently desirable for objects to remain
    -- associated with values for longer periods of time, and this may come into
    -- conflict with the need to clean up after a period of "string hacking."
    -- To deal with this problem, we introduce the notions of "persistent" and
    -- "nonpersistent" values.
    --
    -- The nonpersistent values are those that are generated by the constructors
    -- in the previous section.  These are claimed by the release procedure.
    -- Persistent values are generated by the two make_persistent functions
    -- described below.  These values must be disposed of individually by means of
    -- the flush procedure.
    --
    -- This allows a description of the meaning of the ":=" operation.  For a
    -- statement of the form, s := expr, where expr is a string_type expression,
    -- the result is that the value denoted/created by expr becomes bound to the
    -- the object, s.  Assignment in no way affects the persistence of the value.
    -- If expr happens to be an object, then the value associated  with it will be
    -- shared.  Ideally, this sharing would not be visible, since values are
    -- immutable.  However, the sharing may be visible because of the memory
    -- management, as described below.  Programs which depend on such sharing are
    -- erroneous.

    function Make_Persistent (S : in String_Type) return String_Type;

    --| Effects:
    --| Returns a persistent value, v, containing exactly those characters in
    --| value(s).  The value v will not be claimed by any subsequent release.
    --| Only an invocation of flush will claim v.  After such a claiming
    --| invocation of flush, the use (other than :=) of any other object to
    --| which v was bound is erroneous, and program_error may be raised for
    --| such a use.

    function Make_Persistent (S : in String) return String_Type;

    --| Effects:
    --| Returns a persistent value, v, containing exactly those chars in s.
    --| The value v will not be claimed by any subsequent release.
    --| Only an invocation of flush will reclaim v.  After such a claiming
    --| invocation of flush, the use (other than :=) of any other object to
    --| which v was bound is erroneous, and program_error may be raised for
    --| such a use.

    procedure Flush (S : in out String_Type);

    --| Effects:
    --| Return heap space used by the value associated with s, if any, to
    --| the heap.  s becomes associated with the empty value.  After an
    --| invocation of flush claims the value, v, then any use (other than :=)
    --| of an object to which v was bound is erroneous, and program_error
    --| may be raised for such a use.
    --|
    --| This operation should be used only for persistent values.  The mark
    --| and release operations are used to deallocate space consumed by other
    --| values.  For example, flushing a nonpersistent value implies that a
    --| release that tries to claim this value will be erroneous, and
    --| program_error may be raised for such a use.

    procedure Mark;

    --| Effects:
    --| Marks the current state of heap usage for use by release.
    --| An implicit mark is performed at the beginning of program execution.

    procedure Release;

    --| Raises: illegal_dealloc
    --| Effects:
    --| Releases all heap space used by nonpersistent values that have been
    --| allocated since the last mark.  The values that are claimed include
    --| those bound to objects as well as those produced and discarded during
    --| the course of general "string hacking."  If an invocation of release
    --| claims a value, v, then any subsequent use (other than :=) of any
    --| other object to which v is bound is erroneous, and program_error may
    --| be raised for such a use.
    --|
    --| Raises illegal_dealloc if the invocation of release does not balance
    --| an invocation of mark.  It is permissible to match the implicit
    --| initial invocation of mark.  However, subsequent invocations of
    --| constructors will raise the illegal_alloc exception until an
    --| additional mark is performed.  (Anyway, there is no good reason to
    --| do this.)  In any case, a number of releases matching the number of
    --| currently active marks is implicitly performed at the end of program
    --| execution.
    --|
    --| Good citizens generally perform their own marks and releases
    --| explicitly.  Extensive string hacking without cleaning up will
    --| cause your program to run very slowly, since the heap manager will
    --| be forced to look hard for chunks of space to allocate.

    -- Queries:

    function Is_Empty (S : in String_Type) return Boolean;

    --| Effects:
    --| Return true iff s is the empty sequence of characters.

    function Length (S : in String_Type) return Natural;

    --| Effects:
    --| Return number of characters in s.

    function Value (S : in String_Type) return String;

    --| Effects:
    --| Return a string, s2, that contains the same characters that s
    --| contains.  The properties, s2'first = 1 and s2'last = length(s),
    --| are satisfied.  This implies that, for a given string, s3,
    --| value(create(s3))'first may not equal s3'first, even though
    --| value(create(s3)) = s3 holds.  Thus, "content equality" applies
    --| although the string objects may be distinguished by the use of
    --| the array attributes.

    function Fetch (S : in String_Type; I : in Positive) return Character;

    --| Raises: bounds
    --| Effects:
    --| Return the ith character in s.  Characters are numbered from
    --| 1 to length(s).  Raises bounds if i not in 1..length(s).

    function Equal (S1, S2 : in String_Type) return Boolean;

    --| Effects:
    --| Value equality relation; return true iff length(s1) = length(s2)
    --| and, for all i in 1..length(s1), fetch(s1, i) = fetch(s2, i).
    --| The "=" operation is carried over from the representation.
    --| It allows one to distinguish among the heap addresses of
    --| string_type values.  Even "equal" values may not be "=", although
    --| s1 = s2 implies equal(s1, s2).
    --| There is no reason to use "=".

    function Equal (S1 : in String_Type; S2 : in String) return Boolean;

    --| Effects:
    --| Return equal(s1, create(s2)).

    function Equal (S1 : in String; S2 : in String_Type) return Boolean;

    --| Effects:
    --| Return equal(create(s1), s2).

    function "<" (S1 : in String_Type; S2 : in String_Type) return Boolean;

    --| Effects:
    --| Lexicographic comparison; return value(s1) < value(s2).

    function "<" (S1 : in String_Type; S2 : in String) return Boolean;

    --| Effects:
    --| Lexicographic comparison; return value(s1) < s2.

    function "<" (S1 : in String; S2 : in String_Type) return Boolean;

    --| Effects:
    --| Lexicographic comparison; return s1 < value(s2).

    function "<=" (S1 : in String_Type; S2 : in String_Type) return Boolean;

    --| Effects:
    --| Lexicographic comparison; return value(s1) <= value(s2).

    function "<=" (S1 : in String_Type; S2 : in String) return Boolean;

    --| Effects:
    --| Lexicographic comparison; return value(s1) <= s2.

    function "<=" (S1 : in String; S2 : in String_Type) return Boolean;

    --| Effects:
    --| Lexicographic comparison; return s1 <= value(s2).

    function Match_C
                (S : in String_Type; C : in Character; Start : in Positive := 1)
                return Natural;

    --| Raises: no_match
    --| Effects:
    --| Return the minimum index, i in start..length(s), such that
    --| fetch(s, i) = c.  Returns 0 if no such i exists,
    --| including the case where is_empty(s).

    function Match_Not_C
                (S : in String_Type; C : in Character; Start : in Positive := 1)
                return Natural;

    --| Raises: no_match
    --| Effects:
    --| Return the minimum index, i in start..length(s), such that
    --| fetch(s, i) /= c.  Returns 0 if no such i exists,
    --| including the case where is_empty(s).

    function Match_S (S1, S2 : in String_Type; Start : in Positive := 1)
                     return Natural;

    --| Raises: no_match.
    --| Effects:
    --| Return the minimum index, i, in start..length(s1), such that,
    --| for all j in 1..length(s2), fetch(s2, j) = fetch(s1, i + j - 1).
    --| This is the position of the substring, s2, in s1.
    --| Returns 0 if no such i exists, including the cases
    --| where is_empty(s1) or is_empty(s2).
    --| Note that equal(substr(s1, match_s(s1, s2, i), length(s2)), s2)
    --| holds, providing that match_s does not raise an exception.

    function Match_S
                (S1 : in String_Type; S2 : in String; Start : in Positive := 1)
                return Natural;

    --| Raises: no_match.
    --| Effects:
    --| Return the minimum index, i, in start..length(s1), such that,
    --| for all j in s2'range, s2(j) = fetch(s1, i + j - 1).
    --| This is the position of the substring, s2, in s1.
    --| Returns 0 if no such i exists, including the cases
    --| where is_empty(s1) or s2 = "".
    --| Note that equal(substr(s1, match_s(s1, s2, i), s2'length), s2)
    --| holds, providing that match_s does not raise an exception.

    function Match_Any (S, Any : in String_Type; Start : in Positive := 1)
                       return Natural;

    --| Raises: no_match, any_empty
    --| Effects:
    --| Return the minimum index, i in start..length(s), such that
    --| fetch(s, i) = fetch(any, j), for some j in 1..length(any).
    --| Raises any_empty if is_empty(any).
    --| Otherwise, returns 0 if no such i exists, including the case
    --| where is_empty(s).


    function Match_Any
                (S : in String_Type; Any : in String; Start : in Positive := 1)
                return Natural;

    --| Raises: no_match, any_empty
    --| Effects:
    --| Return the minimum index, i, in start..length(s), such that
    --| fetch(s, i) = any(j), for some j in any'range.
    --| Raises any_empty if any = "".
    --| Otherwise, returns 0 if no such i exists, including the case
    --| where is_empty(s).

    function Match_None (S, None : in String_Type; Start : in Positive := 1)
                        return Natural;

    --| Raises: no_match
    --| Effects:
    --| Return the minimum index, i in start..length(s), such that
    --| fetch(s, i) /= fetch(none, j) for each j in 1..length(none).
    --| If (not is_empty(s)) and is_empty(none), then i is 1.
    --| Returns 0 if no such i exists, including the case
    --| where is_empty(s).

    function Match_None
                (S : in String_Type; None : in String; Start : in Positive := 1)
                return Natural;

    --| Raises: no_match.
    --| Effects:
    --| Return the minimum index, i in start..length(s), such that
    --| fetch(s, i) /= none(j) for each j in none'range.
    --| If not is_empty(s) and none = "", then i is 1.
    --| Returns 0 if no such i exists, including the case
    --| where is_empty(s).


private

    type String_Type is access String;

    --| Abstract data type, string_type, is a constant sequence of chars
    --| of arbitrary length.  Representation type is access string.
    --| It is important to distinguish between an object of the rep type
    --| and its value; for an object, r, val(r) denotes the value.
    --|
    --| Representation Invariant:  I: rep --> boolean
    --| I(r: rep) = (val(r) = null) or else
    --|             (val(r).all'first = 1 &
    --|              val(r).all'last >= 0 &
    --|              (for all r2, val(r) = val(r2) /= null => r is r2))
    --|
    --| Abstraction Function:  A: rep --> string_type
    --| A(r: rep) = if r = null then
    --|                 the empty sequence
    --|             elsif r'last = 0 then
    --|                 the empty sequence
    --|             else
    --|                 the sequence consisting of r(1),...,r(r'last).

end String_Pkg;