-- TexString.mesa -- last written by Doug Wyatt, September 21, 1979 11:52 AM DIRECTORY TexMemDefs: FROM "TexMemDefs", TexStringDefs: FROM "TexStringDefs", InlineDefs: FROM "InlineDefs" USING [DIVMOD], StreamDefs: FROM "StreamDefs" USING [StreamHandle,StreamObject,StreamError], SystemDefs: FROM "SystemDefs" USING [AllocateHeapNode,FreeHeapNode]; TexString: PROGRAM IMPORTS TexMemDefs,InlineDefs,StreamDefs,SystemDefs EXPORTS TexStringDefs = BEGIN OPEN StreamDefs,TexStringDefs; StringFull: PUBLIC SIGNAL[oldstring: STRING] RETURNS[newstring: STRING] = CODE; CreateStringStream: PUBLIC PROCEDURE[string: STRING] RETURNS[StringHandle] = BEGIN stream: StringHandle←SystemDefs.AllocateHeapNode[SIZE[Other StreamObject]]; stream↑←[reset: SSReset, get: SSGet, putback: SSPutBack, put: SSPut, endof: SSEndof, destroy: SSDestroy, link: NIL, body: Other[type: 0, data: string]]; RETURN[stream]; END; SSReset: PROCEDURE[stream: StreamHandle] = BEGIN WITH s:stream SELECT FROM Other => LOOPHOLE[s.data,STRING].length←0; ENDCASE => SIGNAL StreamError[@s, StreamType]; END; SSGet: PROCEDURE[stream: StreamHandle] RETURNS[UNSPECIFIED] = BEGIN WITH s:stream SELECT FROM Other => SIGNAL StreamError[@s, StreamOperation]; -- get not implemented ENDCASE => SIGNAL StreamError[@s, StreamType]; RETURN[0C]; END; SSPutBack: PROCEDURE[stream: StreamHandle, item: UNSPECIFIED] = BEGIN WITH s:stream SELECT FROM Other => SIGNAL StreamError[@s, StreamOperation]; ENDCASE => SIGNAL StreamError[@s, StreamType]; END; SSPut: PROCEDURE[stream: StreamHandle, item: UNSPECIFIED] = BEGIN WITH s:stream SELECT FROM Other => AppendChar[LOOPHOLE[s.data,STRING],item]; ENDCASE => SIGNAL StreamError[@s, StreamType]; END; SSEndof: PROCEDURE[stream: StreamHandle] RETURNS[BOOLEAN] = BEGIN WITH s:stream SELECT FROM Other => BEGIN string: STRING=s.data; RETURN[string.length~<string.maxlength]; END; ENDCASE => BEGIN SIGNAL StreamError[@s, StreamType]; RETURN[FALSE] END; END; SSDestroy: PROCEDURE[stream: StreamHandle] = BEGIN WITH s:stream SELECT FROM Other => SystemDefs.FreeHeapNode[@s]; ENDCASE => SIGNAL StreamError[@s, StreamType]; END; AppendChar: PUBLIC PROCEDURE[s: STRING, c: CHARACTER] = BEGIN i: CARDINAL; UNTIL (i←s.length)<s.maxlength DO s←SIGNAL StringFull[s] ENDLOOP; s[i]←c; s.length←i+1; END; AppendString: PUBLIC PROCEDURE[s1: STRING, s2: STRING] = BEGIN i: CARDINAL; FOR i IN[0..s2.length) DO AppendChar[s1,s2[i]] ENDLOOP; END; AppendNumber: PUBLIC PROCEDURE[s: STRING, val: CARDINAL, radix: CARDINAL] = BEGIN xn: PROCEDURE [n: CARDINAL] = BEGIN r: CARDINAL; [n,r] ← InlineDefs.DIVMOD[n,radix]; IF n # 0 THEN xn[n]; IF r>9 THEN r ← r + 'A-'0-10; AppendChar[s, r+'0]; END; xn[val]; END; CopyString: PUBLIC PROCEDURE[old: STRING] RETURNS[new: STRING] = BEGIN new←TexMemDefs.AllocString[old.length]; AppendString[new,old]; END; EqualString: PUBLIC PROCEDURE[s,t: STRING] RETURNS[BOOLEAN] = BEGIN i: CARDINAL; IF s.length=t.length THEN FOR i IN[0..s.length) DO IF s[i]#t[i] THEN EXIT REPEAT FINISHED => RETURN[TRUE] ENDLOOP; RETURN[FALSE]; END; END.