home *** CD-ROM | disk | FTP | other *** search
- with TEXT_IO;
- use TEXT_IO;
- package DYN is
-
-
- ------------------------------------------------------------------------------
- -- This is a package of several string manipulation functions based on --
- -- a built-in dynamic STRING type DYN_STRING. It is an adaptation and --
- -- extension of the package proposed by Sylvan Rubin of Ford Aerospace and --
- -- Communications Corporation in the Nov/Dec 1984 issue of the Journal of --
- -- Pascal, Ada and Modula-2. Some new functions have been added, and much --
- -- of the body code has been rewritten. --
- ------------------------------------------------------------------------------
- -- R.G. Cleaveland 07 December 1984: --
- -- Implementation initially with the Telesoft Ada version 1.3. --
- -- 06 Feb 85: CHAR changed to add the optional parameter POSIT. --
- -- 06 Feb 85: procedure SUBSTITUTE added. --
- -- 05 Apr 85: procedures UPPERCASE and CHECKBYTE added. --
- -- 04 Feb 86: style and formatting changes made, some comments fixed. --
- -- Ported to VERDIX VADS (VAX Ultrix version 5.1). --
- -- 10 Feb 86: Several bugs fixed - SIZE constrained, exception for '&' --
- -- generating too long a string added, error in integer conversion fixed. --
- -- Functions EQUALS, ">", "<=" and ">=" added. Subtype DS_POS incorporated.--
- ------------------------------------------------------------------------------
-
-
-
-
-
-
- MAX_D_STRING_LENGTH : constant POSITIVE := 100;
- -- This is the maximum LENGTH of a dynamic string implemented with this
- -- package. This value is "arbitrary" in that any reasonable number
- -- equal to or less than the maximum STRING LENGTH permitted by the
- -- compiler is acceptable. The specific value above was chosen as a
- -- compromise between programmer convenience and memory space requirements.
-
-
-
- subtype DS_POS is INTEGER range 0..MAX_D_STRING_LENGTH;
-
- type DYN_STRING is private;
-
- STRING_TOO_SHORT: exception;
-
-
-
- function D_STRING(CHAR: CHARACTER) return DYN_STRING;
- -- Creates a one-byte dynamic string of contents CHAR.
-
- function D_STRING(STR : STRING ) return DYN_STRING;
- -- Creates a dynamic string of contents STR.
-
- function D_STRING(N: INTEGER;
- B: NATURAL := 0;
- F: CHARACTER:= ' ') return DYN_STRING;
-
- -- for the preceding function:
- -- B is the number of bytes desired in the returned string.
- -- The first byte is reserved for the sign; it will be blank
- -- or '-'. If B is 0 or unspecified the LENGTH of the
- -- string returned is just enough for the sign and the
- -- significant digits. If the number would overflow B,
- -- the exception STRING_TOO_SHORT is raised.
-
- -- F is a leading-fill CHARACTER. If B is not zero, bytes
- -- from 2 up to the first significant byte will be F.
-
- function D_STRING(FLT : FLOAT; AFT : INTEGER) return DYN_STRING;
- -- Creates a dynamic string representation of the number FLT
- -- in fixed point notation with AFT decimal places.
-
- -- The following four functions convert from dynamic strings to the
- -- desired representation:
-
- function CHAR(DSTR : DYN_STRING;
- POSIT : POSITIVE := 1) return CHARACTER;
-
- function STR (DSTR: DYN_STRING) return STRING;
-
- function INT (DSTR: DYN_STRING) return INTEGER;
-
- function FLT (DSTR: DYN_STRING) return FLOAT;
-
- -- (No function for long integer; depends on compiler implementation)
-
- function LENGTH(DSTR: DYN_STRING) return NATURAL;
- -- returns the LENGTH of the dynamic string.
-
- function EQUALS (DS1, DS2: DYN_STRING) return BOOLEAN;
- -- true if DS1 is equal to DS2 the way Ada compares strings
-
- function "<" (DS1, DS2: DYN_STRING) return BOOLEAN;
- -- true if DS1 is less than DS2 the way Ada compares strings
-
- function "<=" (DS1, DS2: DYN_STRING) return BOOLEAN;
- -- true if DS1 is less than or equal to DS2 the way Ada compares strings
-
- function ">" (DS1, DS2: DYN_STRING) return BOOLEAN;
- -- true if DS1 is greater than DS2 the way Ada compares strings
-
- function ">=" (DS1, DS2: DYN_STRING) return BOOLEAN;
- -- true if DS1 is greater than or equal to DS2 the way Ada compares strings
-
- function "&" (DS1, DS2: DYN_STRING) return DYN_STRING;
- -- concatenates DS1 and DS2. Raises CONSTRAINT_ERROR if LENGTH of
- -- new string would exceed MAX_D_STRING_LENGTH.
-
- function SUBSTRING (DSTR: DYN_STRING; -- Returns a subpart of this string
- START : NATURAL; -- starting at this position
- LENGTH : NATURAL) -- and of this LENGTH.
- return DYN_STRING;
-
- function RIGHT (DSTR: DYN_STRING; -- Returns the part of this string
- START : NATURAL) -- starting here and to the end.
- return DYN_STRING;
-
- procedure SUBSTITUTE(DSTR : in out DYN_STRING;-- Into this string
- POSIT : in POSITIVE; -- at this position,
- C : in CHARACTER); -- this character
- -- is substituted.
-
- function INDEX (SOURCE_STRING : DYN_STRING; -- If this string contains
- PATTERN_STRING: DYN_STRING; -- this string starting AT or
- START_POSIT : INTEGER) -- AFTER this position, the
- return INTEGER; -- position of such start
- -- is returned.
- -- If the string lengths prohibit the search -1 is returned.
- -- If no match was found, 0 is returned.
- -- (This is like the INSTR function of BASIC).
-
- function RINDEX (SOURCE_STRING : DYN_STRING; -- If this string contains
- PATTERN_STRING: DYN_STRING; -- this string starting AT or
- START_POSIT : INTEGER) -- BEFORE this position, the
- return INTEGER; -- position of such start
- -- is returned.
- -- If the string lengths prohibit the search -1 is returned.
- -- If no match was found, 0 is returned.
- -- eg RINDEX(D_STRING("ABC"),D_STRING("C") ,2) = 0
- -- RINDEX(D_STRING("ABC"),D_STRING("BC"),3) = -1
-
- function UPPERCASE (DSTR: DYN_STRING) return DYN_STRING;
- -- Returns with all lower-case characters changed to
- -- uppercase.
- function CHECKBYTE(DSTR: in DYN_STRING) return CHARACTER;
- -- Returns a printable check CHARACTER representing a
- -- logical process on the elements of the string for
- -- purposes of data validity checks.
- procedure CLEAR(DSTR: in out DYN_STRING);
- -- makes DSTR a null string.
-
- private
- type DYN_STRING is
- record
- SIZE: INTEGER range 0..MAX_D_STRING_LENGTH;
- DATA: STRING(1..MAX_D_STRING_LENGTH);
- end record;
- end DYN;
-
-
- package body DYN is
-
- procedure CLEAR(DSTR: in out DYN_STRING) is
-
- begin
- DSTR.SIZE := 0;
- end CLEAR;
-
- function MINIMUM(VALUE1, VALUE2: NATURAL) return NATURAL is
-
- begin
- if VALUE1 < VALUE2 then
- return VALUE1;
- else
- return VALUE2;
- end if;
- end MINIMUM;
-
- function "&" (DS1, DS2: DYN_STRING) return DYN_STRING is
-
- DS3 : DYN_STRING;
-
- begin
- DS3.SIZE := DS1.SIZE + DS2.SIZE;
- DS3.DATA(1..DS3.SIZE) := DS1.DATA(1..DS1.SIZE) & DS2.DATA(1..DS2.SIZE);
- return DS3;
- end "&";
-
- function D_STRING(CHAR: CHARACTER) return DYN_STRING is
-
- DS : DYN_STRING;
-
- begin
- DS.SIZE := 1;
- DS.DATA(1) := CHAR;
- return DS;
- end D_STRING;
-
- function D_STRING(STR : STRING ) return DYN_STRING is
-
- DS : DYN_STRING;
-
- begin
- DS.SIZE := STR'LENGTH;
- DS.DATA(1..DS.SIZE) := STR;
- return DS;
- end D_STRING;
-
- function D_STRING(N: INTEGER;
- B: NATURAL := 0;
- F: CHARACTER:= ' ') return DYN_STRING is
-
- SIGN, V : DYN_STRING;
-
- begin
- if N < 0 then
- SIGN := D_STRING('-');
- else
- SIGN := D_STRING(' ');
- end if;
- if N = 0 then
- V := D_STRING('0');
- else
- V := RIGHT(D_STRING(INTEGER'image(N)),2);
- end if;
- if B /= 0 then
- if B < V.SIZE + 1 then
- raise STRING_TOO_SHORT;
- else
- for I in 1..B-1-V.SIZE loop
- V := D_STRING(F) & V;
- end loop;
- end if;
- end if;
- return SIGN & V;
- end D_STRING;
-
-
-
- function D_STRING(FLT : FLOAT; AFT : INTEGER) return DYN_STRING is
-
- DS : DYN_STRING;
- F : FLOAT;
- L : INTEGER; --This should be longest integer form
- --available for the implementation.
-
- begin
- F := FLT * (10.0 ** AFT);
- L := INTEGER(F); --See note above - implementation dependent
- DS := D_STRING(L);
- while DS.SIZE < AFT+1 loop
- DS := SUBSTRING(DS,1,1) & D_STRING('0') & RIGHT(DS,2);
- end loop;
- DS := SUBSTRING(DS,1,LENGTH(DS)-AFT) & D_STRING('.')
- & RIGHT(DS,LENGTH(DS)-AFT+1);
- return DS;
- end D_STRING;
-
- function CHAR(DSTR : DYN_STRING;
- POSIT : POSITIVE := 1) return CHARACTER is
-
- begin
- if POSIT > DSTR.SIZE then
- raise STRING_TOO_SHORT;
- else
- return DSTR.DATA(POSIT);
- end if;
- end CHAR;
-
- function STR (DSTR: DYN_STRING) return STRING is
-
- begin
- return DSTR.DATA(1..DSTR.SIZE);
- end STR;
-
- function INT (DSTR: DYN_STRING) return INTEGER is
- V: INTEGER;
- L: POSITIVE;
- package INT_IO is new INTEGER_IO(INTEGER);
-
- begin
- INT_IO.GET(STR(DSTR),V,L); -- Package reference may need to be
- return V; -- changed for validated compiler
- end INT;
-
- function FLT (DSTR: DYN_STRING) return FLOAT is
- V: FLOAT;
- L: POSITIVE;
- package F_IO is new FLOAT_IO(FLOAT);
-
- begin
- F_IO.GET(STR(DSTR),V,L); -- See comment above.
- return V;
- end FLT;
-
- function LENGTH(DSTR: DYN_STRING) return NATURAL is
-
- begin
- return DSTR.SIZE;
- end LENGTH;
-
- function EQUALS (DS1, DS2: DYN_STRING) return BOOLEAN is
- -- true if DS1 is equal to DS2 the way Ada compares strings
- begin
- if STR(DS1)=STR(DS2) then
- return (TRUE);
- else
- return (FALSE);
- end if;
- end EQUALS;
-
- function "<" (DS1, DS2: DYN_STRING) return BOOLEAN is
- -- true if DS1 is less than DS2 the way Ada compares strings
-
- begin
- if STR(DS1) < STR(DS2) then
- return (TRUE);
- else
- return (FALSE);
- end if;
- end "<";
-
- function "<=" (DS1, DS2: DYN_STRING) return BOOLEAN is
- -- true if DS1 is less than or equal to DS2 the way Ada compares strings
-
- begin
- if STR(DS1) <= STR(DS2) then
- return (TRUE);
- else
- return (FALSE);
- end if;
- end "<=";
-
-
- function ">" (DS1, DS2: DYN_STRING) return BOOLEAN is
- -- true if DS1 is greater than DS2 the way Ada compares strings
-
- begin
- if STR(DS1) > STR(DS2) then
- return (TRUE);
- else
- return (FALSE);
- end if;
- end ">";
-
- function ">=" (DS1, DS2: DYN_STRING) return BOOLEAN is
- -- true if DS1 is greater than or equal to DS2 the way Ada compares strings
-
- begin
- if STR(DS1) >= STR(DS2) then
- return (TRUE);
- else
- return (FALSE);
- end if;
- end ">=";
-
- procedure SUBSTITUTE(DSTR : in out DYN_STRING;-- Into this string
- POSIT : in POSITIVE; -- at this position,
- C : in CHARACTER) is -- this character
- -- is substituted.
-
- begin
- DSTR.DATA(POSIT) := C;
- if POSIT > DSTR.SIZE then
- DSTR.SIZE := POSIT;
- end if;
- end SUBSTITUTE;
-
- function SUBSTRING (DSTR: DYN_STRING;
- START : NATURAL;
- LENGTH : NATURAL)
- return DYN_STRING is
- DS: DYN_STRING;
- L : NATURAL := LENGTH;
-
- begin
- if (START < 1) or (START > DSTR.SIZE) then
- raise CONSTRAINT_ERROR;
- else
- if DSTR.SIZE < START + L - 1 then
- raise STRING_TOO_SHORT;
- else
- DS.SIZE := L;
- DS.DATA(1..L) := DSTR.DATA(START..START+L-1);
- return DS;
- end if;
- end if;
- end SUBSTRING;
-
- function RIGHT (DSTR: DYN_STRING;
- START : NATURAL) return DYN_STRING is
-
- begin
- return SUBSTRING(DSTR, START, LENGTH(DSTR) - START + 1);
- end RIGHT;
-
- function INDEX(SOURCE_STRING : DYN_STRING;
- PATTERN_STRING: DYN_STRING;
- START_POSIT : INTEGER) return INTEGER is
-
- NO_MATCH : constant INTEGER := 0;
- NO_FIT : constant INTEGER := -1;
-
- begin
- if SOURCE_STRING.SIZE < PATTERN_STRING.SIZE + START_POSIT - 1
- or START_POSIT < 1 then
- return NO_FIT;
- end if;
- for I in START_POSIT..SOURCE_STRING.SIZE-PATTERN_STRING.SIZE+1 loop
- if SOURCE_STRING.DATA(I..I+PATTERN_STRING.SIZE-1)
- = PATTERN_STRING.DATA(1..PATTERN_STRING.SIZE) then
- return I;
- end if;
- end loop;
- return NO_MATCH;
- end INDEX;
-
- function RINDEX(SOURCE_STRING : DYN_STRING;
- PATTERN_STRING: DYN_STRING;
- START_POSIT : INTEGER) return INTEGER is
-
- NO_MATCH : constant INTEGER := 0;
- NO_FIT : constant INTEGER := -1;
-
- begin
- if SOURCE_STRING.SIZE < PATTERN_STRING.SIZE + START_POSIT - 1
- or START_POSIT < 1 then
- return NO_FIT;
- end if;
- for I in reverse 1..START_POSIT loop
- if SOURCE_STRING.DATA(I..I+PATTERN_STRING.SIZE-1)
- = PATTERN_STRING.DATA(1..PATTERN_STRING.SIZE) then
- return I;
- end if;
- end loop;
- return NO_MATCH;
- end RINDEX;
-
- function UPPERCASE (DSTR: DYN_STRING) return DYN_STRING is
-
- DS: DYN_STRING := DSTR;
-
- begin
- for I in 1..LENGTH(DS) loop
- case DSTR.DATA(I) is
- when 'a'..'z' =>
- DS.DATA(I) := CHARACTER'VAL(CHARACTER'pos(DS.DATA(I))-32);
- when others => null;
- end case;
- end loop;
- return DS;
- end UPPERCASE;
-
- function CHECKBYTE(DSTR: in DYN_STRING) return CHARACTER is
-
- -- Returns a printable check CHARACTER representing a
- -- logical process on the elements of the string for
- -- purposes of data validity checks.
- -- IMPLEMENTATION NOTE: The MAX_CHECKSUM is defined
- -- so as to permit identical behavior on all systems
- -- which will compile the routine. This algorithm will
- -- fail to detect a CHARACTER drop or add if that CHARACTER
- -- is the close bracket ']'.
-
- CHECKSUM : NATURAL := DSTR.SIZE;
- MAX_CHECKSUM: constant NATURAL := 16000;
- CALC_MAX : constant NATURAL := 16000 + CHARACTER'pos(CHARACTER'last);
- MODE : constant NATURAL := CHARACTER'pos('Z') - CHARACTER'pos('A');
-
- begin
- for I in 1..DSTR.SIZE loop
- CHECKSUM := CHECKSUM +
- CHARACTER'pos(DSTR.DATA(I));
- if CHECKSUM > MAX_CHECKSUM then
- CHECKSUM := CHECKSUM - 1000;
- end if;
- end loop;
- CHECKSUM := CHECKSUM mod MODE;
- return CHARACTER'VAL(CHECKSUM + CHARACTER'pos('A'));
- end CHECKBYTE;
-
- begin --(DYN)
- null;
- exception when others => PUT("[DYN EXCEPTION]");
- raise;
- end DYN;
-
-