home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume2 / pstrings / part01 / concatS.p < prev    next >
Encoding:
Text File  |  1991-08-07  |  2.2 KB  |  86 lines

  1.  
  2.  
  3.  
  4.  
  5. # include "strings.h"
  6.  
  7. function concatS{(s1, s2: String):String};
  8. {
  9. * Returns s1 + s2
  10. * Concatenates s1 and s2.
  11. }
  12.    var t: String;  { -- Result is built in t }
  13.        l, r, End1: stringtail;
  14.        StillInHeadOfT, InTailOfT, InTailOfS2: Boolean;
  15.        i, j: Nat1;
  16.        tindx, rindx: 1..slength;
  17.        null: Char;
  18. begin
  19.  t := nil;
  20.  null := chr(0);
  21.  { -- Deal with trivial cases first }
  22.  if s1 = nil then concatS := s2 else
  23.  if s2 = nil then concatS := s1 else
  24.  { -- Both s1 and s2 are non-empty }
  25.   begin
  26.     new(t);
  27.     with t^ do begin
  28.       LEN := s1^.LEN + s2^.LEN;
  29.       { -- Copy head of s1 }
  30.       HEAD := s1^.HEAD;
  31.       TAIL := nil;
  32.           { -- Allocate and link in any extra string chunks needed }
  33.         for i := 1 to (LEN-1) div slength do begin
  34.             new(l);
  35.         { -- pad with nulls if chunk is last one }
  36.         if i=1 then
  37.          for j:=1 to slength do l^.MORE[j] := null;
  38.             l^.REST := TAIL;
  39.             TAIL := l
  40.       end;
  41.           { -- Loop through copying string tail of s1, if required }
  42.       l := TAIL;  End1 := TAIL; r := s1^.TAIL;
  43.       for i := 1 to (s1^.LEN-1) div slength  do begin
  44.            l^.MORE := r^.MORE;
  45.         End1 := l; 
  46.            l := l^.REST;
  47.            r := r^.REST
  48.          end;
  49.       { -- End1 points to the last tail entry (partially) filled}
  50.       if s1^.LEN mod slength <> 0 then l := End1;
  51.       r := s2^.TAIL;
  52.       { -- Loop thru copying s2 to end of t char by char! }
  53.       tindx := s1^.LEN mod slength + 1;
  54.       rindx := 1; 
  55.       StillInHeadOfT := s1^.LEN < slength;
  56.       InTailOfT := false;  InTailOfS2 := false;
  57.       for i := 1 to s2^.LEN do begin
  58.         if  StillInHeadOfT then begin
  59.              HEAD[tindx] := s2^.HEAD[rindx];
  60.              StillInHeadOfT := tindx < slength
  61.         end
  62.         else
  63.         if i <= slength then begin
  64.             InTailOfT := true;
  65.             l^.MORE[tindx] := s2^.HEAD[rindx]
  66.         end
  67.         else begin
  68.             InTailOfS2 := true;
  69.             l^.MORE[tindx] := r^.MORE[rindx]
  70.         end;
  71.         { -- Always inc indices and step down lists if req. }
  72.         tindx := tindx mod slength + 1;
  73.         if (tindx = 1) and InTailOfT  then l := l^.REST;
  74.         rindx := rindx mod slength + 1;
  75.         if (rindx = 1) and InTailOfS2 then r := r^.REST
  76.       end
  77.       end{ -- with};
  78.     { -- Make 0 ref count }
  79.     t^.REFS := 0;
  80.     { -- Tidy up any intermediate storage }
  81.     if s1 <> nil then if s1^.REFS = 0 then disposeS(s1);
  82.     if s2 <> nil then if s2^.REFS = 0 then disposeS(s2);
  83.     concatS := t
  84.  end
  85. end{ -- concatS};
  86.