-- File: StringsA.Mesa Edited by: -- Sandman on July 1, 1980 8:39 AM -- Sapsford on May 8, 1980 4:04 PM -- Forrest on October 16, 1980 3:45 PM -- Copyright Xerox Corporation 1979, 1980 DIRECTORY Inline USING [BITOR], String USING [CharsPerWord, StringHeaderSize, SubString]; StringsImplA: PROGRAM IMPORTS Inline EXPORTS String = PUBLIC BEGIN OPEN String; WordsForString: PROCEDURE [nchars: CARDINAL] RETURNS [CARDINAL] = BEGIN RETURN[StringHeaderSize + (nchars + (CharsPerWord - 1))/CharsPerWord] END; StringBoundsFault: SIGNAL [s: STRING] RETURNS [ns: STRING] = CODE; AppendChar: PROCEDURE [s: STRING, c: CHARACTER] = BEGIN IF s = NIL THEN RETURN; UNTIL s.length < s.maxlength DO s ← SIGNAL StringBoundsFault[s]; ENDLOOP; s[s.length] ← c; s.length ← s.length + 1; RETURN END; AppendString: PROCEDURE [to: STRING, from: STRING] = BEGIN i, j, n: CARDINAL; IF to = NIL OR from = NIL THEN RETURN; WHILE from.length + to.length > to.maxlength DO to ← SIGNAL StringBoundsFault[to]; ENDLOOP; n ← MIN[from.length, LOOPHOLE[to.maxlength - to.length, CARDINAL]]; i ← to.length; j ← 0; WHILE j < n DO to[i] ← from[j]; i ← i + 1; j ← j + 1; ENDLOOP; to.length ← i; RETURN END; EqualString, EqualStrings: PROCEDURE [s1, s2: STRING] RETURNS [BOOLEAN] = BEGIN i: CARDINAL; IF s1 = NIL AND s2 = NIL THEN RETURN[TRUE]; IF s1 = NIL OR s2 = NIL OR s1.length # s2.length THEN RETURN[FALSE]; FOR i IN [0..s1.length) DO IF s1[i] # s2[i] THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE] END; EquivalentString, EquivalentStrings: PROCEDURE [s1, s2: STRING] RETURNS [BOOLEAN] = BEGIN OPEN Inline; i: CARDINAL; casebit: WORD = 40B; IF s1 = NIL AND s2 = NIL THEN RETURN[TRUE]; IF s1 = NIL OR s2 = NIL OR s1.length # s2.length THEN RETURN[FALSE]; FOR i IN [0..s1.length) DO IF BITOR[s1[i], casebit] # BITOR[s2[i], casebit] THEN RETURN[FALSE]; ENDLOOP; RETURN[TRUE] END; AppendSubString: PROCEDURE [to: STRING, from: SubString] = BEGIN i, j, n: CARDINAL; s: STRING; IF to = NIL OR (s ← from.base) = NIL THEN RETURN; WHILE from.length + to.length > to.maxlength DO to ← SIGNAL StringBoundsFault[to]; ENDLOOP; i ← to.length; j ← from.offset; n ← MIN[from.length, LOOPHOLE[to.maxlength - to.length, CARDINAL]]; WHILE n > 0 DO to[i] ← s[j]; i ← i + 1; j ← j + 1; n ← n - 1; ENDLOOP; to.length ← i; RETURN END; EqualSubString, EqualSubStrings: PROCEDURE [s1, s2: SubString] RETURNS [BOOLEAN] = BEGIN i1, i2, n: CARDINAL; b1, b2: STRING; IF s1.length # s2.length THEN RETURN[FALSE]; b1 ← s1.base; i1 ← s1.offset; b2 ← s2.base; i2 ← s2.offset; FOR n ← s1.length, n - 1 WHILE n > 0 DO IF b1[i1] # b2[i2] THEN RETURN[FALSE]; i1 ← i1 + 1; i2 ← i2 + 1; ENDLOOP; RETURN[TRUE] END; EquivalentSubString, EquivalentSubStrings: PROCEDURE [s1, s2: SubString] RETURNS [BOOLEAN] = BEGIN OPEN Inline; casebit: WORD = 40B; i1, i2, n: CARDINAL; b1, b2: STRING; IF s1.length # s2.length THEN RETURN[FALSE]; b1 ← s1.base; i1 ← s1.offset; b2 ← s2.base; i2 ← s2.offset; FOR n ← s1.length, n - 1 WHILE n > 0 DO IF BITOR[b1[i1], casebit] # BITOR[b2[i2], casebit] THEN RETURN[FALSE]; i1 ← i1 + 1; i2 ← i2 + 1; ENDLOOP; RETURN[TRUE] END; DeleteSubString: PROCEDURE [s: SubString] = BEGIN b: STRING = s.base; i: CARDINAL ← s.offset; j: CARDINAL ← i + s.length; WHILE j < b.length DO b[i] ← b[j]; i ← i + 1; j ← j + 1; ENDLOOP; b.length ← i; RETURN END; END....