home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / misc / dstr1.ada < prev    next >
Encoding:
Text File  |  1988-05-03  |  8.4 KB  |  230 lines

  1. with text_io; use text_io;
  2. package DYN is
  3.  
  4. ------------------------------------------------------------------------------
  5. --  This is a package of several string manipulation functions based on     --
  6. -- a built-in dynamic string type DYN_STRING.  It is an adaptation and      --
  7. -- extension of the package proposed by Sylvan Rubin of Ford Aerospace and  --
  8. -- Communications Corporation in the Nov/Dec 1984 issue of the Journal of   --
  9. -- Pascal, Ada and Modula-2.  Some new functions have been added, the       --
  10. -- SUBSTRING function has been modified to permit it to return the right    --
  11. -- part of a string if the third parameter is permitted to default, and     --
  12. -- much of the body code has been rewritten.                                --
  13. ------------------------------------------------------------------------------
  14. -- R.G. Cleaveland 07 December 1984:                                        --
  15. --  Implementation initially with the Telesoft Ada version                  --
  16. -- This required definition of the DYN_STRING type without use of a         --
  17. -- discriminant; an arbitrary maximum string length was chosen.  This       --
  18. -- should be changed when an improved compiler is available.                --
  19. ------------------------------------------------------------------------------
  20. -- Richard Powers 03 January 1985:                                          --
  21. -- changed to be used with a real compiler.                                 --
  22. -- Some of the routines removed by my whim.                                 --
  23. ------------------------------------------------------------------------------
  24. -- Richard Powers 26 January 1985:
  25. -- Added UPPER_CASE function
  26. ------------------------------------------------------------------------------
  27.  
  28. type DYN_STRING is private;
  29.  
  30. STRING_TOO_SHORT: exception;
  31.  
  32. function D_STRING(CHAR: character)  return DYN_STRING;
  33.         -- Creates a one-byte dynamic string of contents CHAR.
  34.  
  35. function D_STRING(STR : string   )  return DYN_STRING;
  36.         -- Creates a dynamic string of contents STR.
  37.  
  38. -- The following four functions convert from dynamic strings to the
  39. -- desired representation:
  40. function CHAR(DSTR: DYN_STRING) return character;
  41. function STR (DSTR: DYN_STRING) return string;
  42. function INT (DSTR: DYN_STRING) return integer;
  43. function FLT (DSTR: DYN_STRING) return float;
  44.  
  45. function LENGTH(DSTR: DYN_STRING) return natural;
  46. function "<" (DS1, DS2: DYN_STRING) return boolean;
  47. function "&" (DS1, DS2: DYN_STRING) return DYN_STRING;
  48.  
  49. function SUBSTRING (DSTR: DYN_STRING;      -- Returns a subpart of this string
  50.                     START  : natural;      -- starting at this position
  51.                     LENGTH : natural := 0) -- and of this length.
  52.                 return DYN_STRING;
  53.                 -- if LENGTH is zero or not specified, the remainder of the
  54.                 -- string is returned (eg the "RIGHT" function).
  55.  
  56. function INDEX (SOURCE_STRING,              --If this string contains
  57.                 PATTERN_STRING: DYN_STRING; --this string starting at or AFTER
  58.                 START_POS: integer)         --this position, the position of
  59.                 return integer;             --such start is returned.
  60.                 -- If the string lengths prohibit the search -1 is returned.
  61.                 -- If no match was found, 0 is returned.
  62.                 -- (This is like the INSTR function of BASIC).
  63.  
  64. function RINDEX (SOURCE_STRING,             --If this string contains
  65.                 PATTERN_STRING: DYN_STRING; --this string starting at or BEFORE
  66.                 START_POS: integer)         --this position, the position of
  67.                 return integer;             --such start is returned.
  68.                 -- If the string lengths prohibit the search -1 is returned.
  69.                 -- If no match was found, 0 is returned.
  70.  
  71. function UPPER_CASE(STRG : in DYN.DYN_STRING) return STRING;
  72.                 -- Return the input string in upper case
  73.  
  74. private
  75.  
  76.         type STRING_CONTENTS(SIZE : natural := 0) is
  77.            record
  78.                DATA: string(1..SIZE);
  79.            end record;
  80.  
  81.         type DYN_STRING is access STRING_CONTENTS;
  82.  
  83. end DYN;
  84.  
  85. ----------------------------------------------------------------------------
  86.  
  87. package body DYN is
  88.  
  89. package MY_INTEGER_IO is new INTEGER_IO(INTEGER);
  90.  
  91. package MY_FLOAT_IO is new FLOAT_IO(FLOAT);
  92.  
  93. function "&" (DS1, DS2: DYN_STRING) return DYN_STRING is
  94.         DS3 : DYN_STRING;
  95.     begin
  96.         DS3 := new STRING_CONTENTS(DS1.SIZE+DS2.SIZE);
  97.         DS3.DATA(1..DS3.SIZE):=   DS1.DATA(1..DS1.SIZE)
  98.                                 & DS2.DATA(1..DS2.SIZE);
  99.         return DS3;
  100.     end "&";
  101.  
  102. function D_STRING(CHAR: character)  return DYN_STRING is
  103.         DS : DYN_STRING;
  104.     begin
  105.         DS := new STRING_CONTENTS(SIZE=>1);
  106.         DS.DATA(1) := CHAR;
  107.         return DS;
  108.     end D_STRING;
  109.  
  110. function D_STRING(STR : string   )  return DYN_STRING is
  111.         DS : DYN_STRING;
  112.     begin
  113.         DS := new STRING_CONTENTS(SIZE => STR'length);
  114.         DS.DATA(1..DS.SIZE)  := STR;
  115.         return DS;
  116.     end D_STRING;
  117.  
  118. function CHAR(DSTR: DYN_STRING) return character is
  119.     begin
  120.         return DSTR.DATA(1);
  121.     end CHAR;
  122.  
  123. function STR (DSTR: DYN_STRING) return string is
  124.     begin
  125.         return DSTR.DATA(1..DSTR.SIZE);
  126.     end STR;
  127.  
  128. function INT (DSTR: DYN_STRING) return integer is
  129.         V: integer;
  130.         L: positive;
  131.     begin
  132.         MY_INTEGER_IO.get(STR(DSTR),V,L);
  133.         return V;
  134.     end INT;
  135.  
  136. function FLT (DSTR: DYN_STRING) return float is
  137.         V: float;
  138.         L: positive;
  139.     begin
  140.         MY_FLOAT_IO.get(STR(DSTR),V,L);
  141.         return V;
  142.     end FLT;
  143.  
  144. function LENGTH(DSTR: DYN_STRING) return natural is
  145.     begin
  146.         return DSTR.SIZE;
  147.     end LENGTH;
  148.  
  149. function "<" (DS1, DS2: DYN_STRING) return boolean is
  150.     begin
  151.         if STR(DS1) < STR(DS2)
  152.         then return (TRUE);
  153.         else return (FALSE);
  154.         end if;
  155.     end "<";
  156.  
  157. function SUBSTRING (DSTR: DYN_STRING;
  158.                     START  : natural;
  159.                     LENGTH : natural := 0)
  160.                                            return DYN_STRING is
  161.         DS: DYN_STRING;
  162.         L : natural := LENGTH;
  163.     begin
  164.         if (START < 1) or (START > DSTR.SIZE)
  165.         then raise CONSTRAINT_ERROR;
  166.         else if L = 0
  167.              then L := DSTR.SIZE-START+1;
  168.              end if;
  169.              if DSTR.SIZE < START + L - 1
  170.              then  raise STRING_TOO_SHORT;
  171.              else
  172.                    DS := new STRING_CONTENTS(L);
  173.                    DS.DATA(1..L) := DSTR.DATA(START..START+L-1);
  174.                    return DS;
  175.              end if;
  176.          end if;
  177.     end SUBSTRING;
  178.  
  179. function INDEX(SOURCE_STRING, PATTERN_STRING: DYN_STRING;
  180.                         START_POS: integer) return integer is
  181.         NO_MATCH        : integer := 0;
  182.         NO_FIT          : integer := -1;
  183.     begin
  184.         if SOURCE_STRING.SIZE < PATTERN_STRING.SIZE + START_POS - 1
  185.         or START_POS < 1
  186.         then return NO_FIT;
  187.         end if;
  188.         for I in START_POS..SOURCE_STRING.SIZE-PATTERN_STRING.SIZE+1 loop
  189.             if SOURCE_STRING.DATA(I..I+PATTERN_STRING.SIZE-1)
  190.                = PATTERN_STRING.DATA(1..PATTERN_STRING.SIZE)
  191.             then return I;
  192.             end if;
  193.         end loop;
  194.         return NO_MATCH;
  195.     end INDEX;
  196.  
  197. function RINDEX(SOURCE_STRING, PATTERN_STRING: DYN_STRING;
  198.                         START_POS: integer) return integer is
  199.         NO_MATCH        : integer := 0;
  200.         NO_FIT          : integer := -1;
  201.     begin
  202.         if SOURCE_STRING.SIZE < PATTERN_STRING.SIZE + START_POS - 1
  203.         or START_POS < 1
  204.         then return NO_FIT;
  205.         end if;
  206.         for I in reverse 1..START_POS loop
  207.             if SOURCE_STRING.DATA(I..I+PATTERN_STRING.SIZE-1)
  208.                = PATTERN_STRING.DATA(1..PATTERN_STRING.SIZE)
  209.             then return I;
  210.             end if;
  211.         end loop;
  212.         return NO_MATCH;
  213.     end RINDEX;
  214.  
  215.     function UPPER_CASE(STRG : in DYN.DYN_STRING) return STRING is
  216.         ANSWER : STRING(1..LENGTH(STRG));
  217.     begin
  218.         ANSWER := STR(STRG);
  219.         for I in 1..LENGTH(STRG) loop
  220.             if (ANSWER(I) >= 'a') and (ANSWER(I) <= 'z') then
  221.                 ANSWER(I) := CHARACTER'VAL(CHARACTER'POS(ANSWER(I)) -
  222.                     CHARACTER'POS('a') + CHARACTER'POS('A'));
  223.             end if;
  224.         end loop;
  225.         return ANSWER;
  226. end UPPER_CASE;
  227.  
  228. end DYN;
  229.  
  230.