-- RopeEdit.mesa -- written by Bill Paxton, February 1981 -- last edit by Bill Paxton, 17-Jan-82 15:44:31 -- This module provides editing and filing operations for ropes -- The edit functions are -- Replace, Delete, Insert, Copy, Move, Transpose -- ReplaceByChar, InsertChar, AppendChar, -- ReplaceByString, InsertString, AppendString -- The filing functions are -- ToFile[fileName] and ToFileC[fileCapability] -- FromFile[fileName] and FromFileC[fileCapability] -- There are also two routines for use with FileByteStreams -- PutRope[fileByteStream,rope] and GetRope[fileByteStream,length] -- Finally, there are a few miscellaneous Rope operations -- Size, Fetch, Flatten DIRECTORY Rope, IOStream, Mopcodes, RopeFrom; RopeEdit: DEFINITIONS IMPORTS Rope, Mopcodes, RopeFrom SHARES Rope = BEGIN OPEN r:Rope, fromI:RopeFrom; ROPE: TYPE = Rope.ROPE; Offset: TYPE = INT; MaxLen: Offset = LAST[Offset]; MaxNat: NAT = LAST[NAT]; -- **** Editing Operations **** Substr: PROC [base: ROPE, start: Offset ← 0, len: Offset ← MaxLen] RETURNS [ROPE]; -- returns a subrope of the base Concat: PROC [base, rest: ROPE, baseLen, restLen: Offset ← MaxLen] RETURNS [ROPE]; -- returns the concatenation of two ropes Replace: PROC [ base: ROPE, start: Offset ← 0, len: Offset ← MaxLen, replace: ROPE ← NIL, baseSize, repSize: Offset ← MaxLen] RETURNS [ROPE]; -- returns a new rope with the given range replaced Delete: PROC [base: ROPE, start, len, baseSize: Offset] RETURNS [ROPE] = INLINE { RETURN [ Replace[base,start,len,NIL,baseSize,0]] }; Insert: PROC [ dest: ROPE, destLoc: Offset ← 0, source: ROPE, destSize, sourceSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [ Replace[dest,destLoc,0,source,destSize,sourceSize]] }; Copy: PROC [ dest: ROPE, destLoc: Offset ← 0, source: ROPE, start: Offset ← 0, len: Offset ← MaxLen, destSize: Offset ← MaxLen] RETURNS [ROPE]; Move: PROC [base: ROPE, dest, start: Offset ← 0, len, baseSize: Offset ← MaxLen] RETURNS [ROPE]; -- no-op if dest in [start..start+len] Transpose: PROC [ base: ROPE, astart, alen, bstart, blen: Offset, baseSize: Offset ← MaxLen] RETURNS [ROPE]; -- [astart..astart+alen) must not intersect [bstart..bstart+blen) BadTranspose: ERROR; ReplaceByChar: PROC [ base: ROPE, char: CHAR, start: Offset ← 0, len, baseSize: Offset ← MaxLen] RETURNS [ROPE]; InsertChar: PROC [ base: ROPE, char: CHAR, loc: Offset ← 0, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [ReplaceByChar[base,char,loc,0,baseSize]] }; AppendChar: PROC [base: ROPE, char: CHAR, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [ReplaceByChar[base,char,MaxLen,0,baseSize]] }; AppendByte: PROC [base: ROPE, x: UNSPECIFIED, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [AppendChar[base,LOOPHOLE[x,CHAR],baseSize]] }; String: TYPE = REF READONLY TEXT; ReplaceByString: PROC [ base: ROPE, string: String, stringStart: NAT ← 0, stringNum: NAT ← MaxNat, start: Offset ← 0, len, baseSize: Offset ← MaxLen] RETURNS [new: ROPE]; InsertString: PROC [ base: ROPE, string: String, stringStart: NAT ← 0, stringNum: NAT ← MaxNat, loc: Offset ← 0, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [ -- string is inserted at loc -- inserts stringNum chars from string starting with stringStart ReplaceByString[base,string,stringStart,stringNum,loc,0,baseSize]] }; AppendString: PROC [ base: ROPE, string: String, stringStart:NAT ← 0, stringNum: NAT ← MaxNat, baseSize: Offset ← MaxLen] RETURNS [ROPE] = INLINE { RETURN [ ReplaceByString[base,string,stringStart,stringNum,MaxLen,0,baseSize]] }; -- **** Filing Operations **** ToFile: PROC [fileName, rope: ROPE, start: Offset ← 0]; -- write the rope on the specified file -- starts writing at given address in file -- truncates file to end of rope FromFile: PROC [fileName: ROPE, start: Offset ← 0, len: Offset ← MaxLen, okToMapFile: BOOLEAN ← FALSE] RETURNS [ROPE]; -- create rope from the contents of a file -- starts reading at given start address in file -- pretends that start+len is the end of the file -- set okToMapFile to TRUE if you will not want to overwrite the contents later -- **** IOStream Operations **** PutRope: PROC [stream: IOStream.Handle, rope: ROPE]; -- does a series of IOStream.PutBlock's GetRope: PROC [stream: IOStream.Handle, len: Offset ← MaxLen] RETURNS [rope: ROPE]; -- reads up to len chars from stream (via GetBlock's) and makes a rope -- **** Miscellaneous Operations Size: PROC [base: ROPE] RETURNS [Offset] = INLINE { -- copied from RopeInline.Mesa OPEN Rope; ExtendPositive: PROC [x: INTEGER] RETURNS [Offset] = MACHINE CODE {Mopcodes.zLI0}; FirstPtr: TYPE = LONG POINTER TO INTEGER; Tobject: TYPE = object node RopeRep; first: INTEGER; IF base = NIL THEN RETURN [0]; IF (first ← LOOPHOLE[base,FirstPtr]↑) >= 0 THEN RETURN [ExtendPositive[first]]; RETURN [LOOPHOLE[base, REF Tobject].size] }; Fetch: PROC [rope: ROPE, index: Offset] RETURNS [CHAR] = INLINE { RETURN [Rope.Fetch[rope,index]] }; CountPieces: PROC [rope: ROPE] RETURNS [count: Offset] = INLINE { [,count,] ← RopeStats[rope] }; RopeStats: PROC [base: ROPE, start: Offset ← 0, len: Offset ← MaxLen] RETURNS [size, pieces, depth: Offset]; Flatten: PROC [rope: ROPE] RETURNS [ROPE] = INLINE { RETURN [fromI.FlatSubstr[rope,0,MaxLen]] }; -- create a flat version of rope Depth: PROC [rope: ROPE] RETURNS [depth: INTEGER]; -- ***** Character property information CharProperty: TYPE = {white, alphaNumeric, punctuation, illegal}; CharPropertyTable: TYPE = PACKED ARRAY CHAR OF CharProperty; charPropertyTable: REF READONLY CharPropertyTable; WhiteChar, BlankChar: PROC [char: CHAR] RETURNS [BOOLEAN] = INLINE { -- Returns TRUE iff char has property=white. RETURN [charPropertyTable[char] = white] }; AlphaNumericChar: PROC [char: CHAR] RETURNS [BOOLEAN] = INLINE { -- Returns TRUE iff char has property=alphaNumeric. RETURN [charPropertyTable[char] = alphaNumeric] }; PunctuationChar: PROC [char: CHAR] RETURNS [BOOLEAN] = INLINE { -- Returns TRUE iff char has property=punctuation. RETURN [charPropertyTable[char] = punctuation] }; IllegalChar: PROC [char: CHAR] RETURNS [BOOLEAN] = INLINE { -- Returns TRUE iff char has property=illegal. RETURN [charPropertyTable[char] = illegal] }; TestCharProp: PROC [char: CHAR, property: CharProperty] RETURNS [BOOLEAN] = INLINE { -- Returns TRUE iff char has property. RETURN [charPropertyTable[char] = property] }; GetCharProp: PROC [char: CHAR] RETURNS[property: CharProperty] = INLINE { -- Returns property {white, alphaNumeric, punctuation, illegal} for char. RETURN [charPropertyTable[char]] }; CR: CHAR = 'M-100B; TAB: CHAR = 'I-100B; SP: CHAR = ' ; UpperCase: PROC [c: CHAR] RETURNS [CHAR] = INLINE { RETURN [IF c IN ['a..'z] THEN c-40B ELSE c] }; LowerCase: PROC [c: CHAR] RETURNS [CHAR] = INLINE { RETURN [IF c IN ['A..'Z] THEN c+40B ELSE c] }; -- ***** Initialization Start: PROC; -- for initialization only END.