<> <> <> <> <> <> DIRECTORY Basics USING [Comparison], PrincOps USING [zLI1, zLI0, zBNDCK], Rope USING [ActionType, Compare, Equal, Find, Map, Match, SkipOver, SkipTo, ROPE, Text]; RefText: CEDAR DEFINITIONS IMPORTS Rope = BEGIN ROPE: TYPE = Rope.ROPE; <> <> <> <> < s.length THEN BoundsFault ELSE len _ MIN[len, s.length-start].>> <> <> <> <> MaxLen: NAT = NAT.LAST; <<>> <> New: PROC [nChars: NAT] RETURNS [REF TEXT]; <> <<>> <> ObtainScratch: PROC [nChars: NAT] RETURNS [REF TEXT]; <> <= nChars. This TEXT is generally obtained from a pool of TEXTs.>> <> <> line: NAT = 100; page: NAT = 512; Error: ERROR [ec: ErrorCode]; ErrorCode: TYPE = { clientModifiedReleasedText }; ReleaseScratch: PROC [t: REF TEXT]; <> <> <<>> <> Append: PROC [ to: REF TEXT, from: REF READONLY TEXT, start: NAT _ 0, len: NAT _ MaxLen] RETURNS [REF TEXT]; <> < to.maxLength or length of result text would exceed MaxLen)>> AppendTextRope: PROC [ to: REF TEXT, from: Rope.Text, start: NAT _ 0, len: NAT _ MaxLen] RETURNS [REF TEXT] = INLINE { <> < to.maxLength or length of result text would exceed MaxLen)>> RETURN[Append[to, TrustTextRopeAsText[from], start, len]]; }; AppendRope: PROC [ to: REF TEXT, from: ROPE, start: NAT _ 0, len: NAT _ MaxLen] RETURNS [REF TEXT]; <> < to.maxLength or length of result text would exceed MaxLen)>> AppendChar: PROC [to: REF TEXT, from: CHAR] RETURNS [REF TEXT]; <> < to.maxLength or length of result text would exceed MaxLen)>> InlineAppendChar: PROC [to: REF TEXT, from: CHAR] RETURNS [REF TEXT] = INLINE { <> < to.maxLength or length of result text would exceed MaxLen)>> IF to.length >= to.maxLength THEN RETURN [AppendChar[to, from]]; to[to.length] _ from; to.length _ to.length + 1; RETURN [to]; }; ReserveChars: PROC [to: REF TEXT, nChars: NAT] RETURNS [REF TEXT]; <> <> <= to.length + nChars.>> InlineReserveChars: PROC [to: REF TEXT, nChars: NAT] RETURNS [REF TEXT] = INLINE { <> <> IF LOOPHOLE[to.maxLength, INTEGER]-LOOPHOLE[nChars, INTEGER] < LOOPHOLE[to.length, INTEGER] THEN RETURN [ReserveChars[to, nChars]]; RETURN [to]; }; <<>> <> Compare: PROC [s1, s2: REF READONLY TEXT, case: BOOL _ TRUE] RETURNS [Basics.Comparison] = INLINE { <> < case of characters is significant>> RETURN [Rope.Compare[TrustTextAsRope[s1], TrustTextAsRope[s2], case]]}; Equal: PROC [s1, s2: REF READONLY TEXT, case: BOOL _ TRUE] RETURNS [BOOL] = INLINE { <> <> RETURN [Rope.Equal[TrustTextAsRope[s1], TrustTextAsRope[s2], case]]}; Fetch: PROC [base: REF READONLY TEXT, index: NAT] RETURNS [CHAR] = INLINE { < base.length)>> <> IF base = NIL OR index > base.length THEN BoundsFault[]; RETURN [base[index]]}; Find: PROC [s1, s2: REF READONLY TEXT, pos1: NAT _ 0, case: BOOL _ TRUE] RETURNS [INTEGER] = INLINE { <> <> <= Length[s1])>> RETURN [Rope.Find[TrustTextAsRope[s1], TrustTextAsRope[s2], pos1, case]]}; Length: PROC [base: REF READONLY TEXT] RETURNS [NAT] = INLINE { <> RETURN [IF base = NIL THEN 0 ELSE base.length]}; Map: PROC [s: REF READONLY TEXT, start: NAT _ 0, len: NAT _ MaxLen, action: ActionType] RETURNS [quit: BOOL] = INLINE { < s.length)>> <> <> RETURN [Rope.Map[TrustTextAsRope[s], start, len, action]]}; ActionType: TYPE = PROC [CHAR] RETURNS [BOOL]; Match: PROC [pattern, object: REF READONLY TEXT, case: BOOL _ TRUE] RETURNS [BOOL] = INLINE { <> <> RETURN [Rope.Match[TrustTextAsRope[pattern], TrustTextAsRope[object], case]]}; SkipTo: PROC [s: REF READONLY TEXT, pos: NAT _ 0, skip: REF READONLY TEXT] RETURNS [NAT] = INLINE { <> RETURN [Rope.SkipTo[TrustTextAsRope[s], pos, TrustTextAsRope[skip]]]}; SkipOver: PROC [s: REF READONLY TEXT, pos: NAT _ 0, skip: REF READONLY TEXT] RETURNS [NAT] = INLINE { <> RETURN [Rope.SkipOver[TrustTextAsRope[s], pos, TrustTextAsRope[skip]]]}; <<>> <> TrustTextAsRope: PROC [text: REF READONLY TEXT] RETURNS [Rope.Text] = INLINE { TRUSTED {RETURN [LOOPHOLE[text]]}}; <> <> TrustTextRopeAsText: PROC [rope: Rope.Text] RETURNS [REF READONLY TEXT] = INLINE { TRUSTED {RETURN [LOOPHOLE[rope]]}}; <> <> BoundsFault: PROC = TRUSTED MACHINE CODE { PrincOps.zLI1; PrincOps.zLI0; PrincOps.zBNDCK}; END.