-- File: HeapStringsA.mesa - last edit:
  -- Mark on: Feb 9, 1981 2:57 PM
  -- Evans on: April 11, 1980  9:57 AM
  
DIRECTORY
  Ascii USING [SP, TAB],
  HeapString,
  Storage USING [CopyString, EmptyString, FreeString, FreeStringNil, String, StringLength];
  
HeapStringsA: PROGRAM
  IMPORTS Storage
  EXPORTS HeapString =
  BEGIN
  
  AppendChar: PUBLIC PROCEDURE [p: POINTER TO STRING, c: CHARACTER] =
    BEGIN
    s: STRING ← [2];
    s[0] ← c; s.length ← 1;
    AppendString[p, s];
    END;
    
  AppendExtensionIfNeeded: PUBLIC PROCEDURE
    [to: POINTER TO STRING, extension: STRING] RETURNS [done: BOOLEAN] =
    BEGIN
    i: CARDINAL;
    done ← FALSE;
    IF ~Storage.EmptyString[to↑] THEN 
      BEGIN
      FOR i DECREASING IN [1..to.length) DO
	SELECT to↑[i] FROM
	  '., Ascii.SP, Ascii.TAB => to.length ← to.length-1;
	  ENDCASE => EXIT;
	ENDLOOP;
      FOR i IN [0..to.length) DO
	IF to↑[i] = '. THEN EXIT;
	REPEAT
	  FINISHED =>
	    BEGIN
	    AppendString[to, extension];
	    done ← TRUE;
	    END;
	ENDLOOP
      END;
    END;
    
  AppendString: PUBLIC PROCEDURE [
    to: POINTER TO STRING, from: STRING, extra: CARDINAL ← 0] =
    BEGIN
    length: CARDINAL;
    i: CARDINAL;
    IF Storage.EmptyString[from] OR to = NIL THEN RETURN;
    length ← from.length + Storage.StringLength[to↑];
    IF to↑ = NIL THEN to↑ ← Storage.String[length]
    ELSE IF to.maxlength < length THEN
      BEGIN
      temp: STRING ← to↑;
      to↑ ← Storage.CopyString[to↑, length-to.length+extra];
      Storage.FreeString[temp];
      END;
    FOR i IN [0..from.length) DO to[i + to.length] ← from[i] ENDLOOP;
    to.length ← length;
    RETURN
    END;
    
  Merge: PUBLIC PROCEDURE [s1, s2: STRING, f1, f2: BOOLEAN]
    RETURNS[s: STRING] =
    BEGIN
    s ← Storage.String[Storage.StringLength[s1]+Storage.StringLength[s2]];
    AppendString[@s, s1];
    AppendString[@s, s2];
    IF f1 THEN Storage.FreeString[s1];
    IF f2 THEN Storage.FreeString[s2];
    END;
    
  Replace: PUBLIC PROCEDURE [to: POINTER TO STRING, from: STRING] =
    BEGIN
    IF to = NIL THEN RETURN[];
    to↑ ← Storage.FreeStringNil[to↑];
    IF from # NIL THEN to↑ ← Storage.CopyString[from];
    RETURN
    END;
    
    
END... of HeapStringsA.mesa