DIRECTORY Inline, TextLooks, TextLooksSupport, TextNode; TextLooksSupportImpl: CEDAR PROGRAM IMPORTS Inline, TextLooks, TextLooksSupport EXPORTS TextLooksSupport, TextLooks SHARES TextLooks = BEGIN OPEN TextLooksSupport, TextLooks; CountRunsAfterChanges: PUBLIC PROC [ref: Runs, start, len: Offset, limit: Offset _ MaxOffset, remove, add: Looks, merge: BOOLEAN _ FALSE, firstLooks: Looks _ noLooks] RETURNS [count: NAT, nonempty: BOOLEAN, lastLooks: Looks] = TRUSTED { ChangedBaseRuns: PROC [x: BaseRuns, start, len, size: Offset, remove, add: Looks, limit: Offset _ MaxOffset] RETURNS [count: NAT, firstLooks, lastLooks: Looks] = TRUSTED INLINE { first, last: NAT; IF remove=allLooks THEN RETURN [1, add, add]; [first, last] _ FindBaseRuns[x, start, len]; count _ 1; firstLooks _ lastLooks _ ModifyLooks[x[first].looks, remove, add]; FOR i: NAT IN (first..last] DO newLooks: Looks _ ModifyLooks[x[i].looks, remove, add]; IF newLooks # lastLooks THEN { IF (count _ count+1) > limit THEN RETURN; lastLooks _ newLooks }; ENDLOOP }; c: NAT; IF len=0 THEN RETURN [0, merge, firstLooks]; IF remove=allLooks THEN RETURN [ IF merge AND firstLooks=add THEN 0 ELSE 1, TRUE, add]; count _ 0; DO nonempty _ merge; IF len=0 THEN { lastLooks _ firstLooks; RETURN }; IF ref=NIL THEN { c _ IF merge AND firstLooks=add THEN 0 ELSE 1; RETURN [count+c, TRUE, add] }; WITH x:ref SELECT FROM base => { size: Offset; firstLks, lastLks: Looks; len _ MIN[len, CheckLongSub[size_TbaseSize[@x], start]]; [c,firstLks,lastLks] _ ChangedBaseRuns[ @x,start,len,size,remove,add,limit]; IF c > limit THEN { count _ count+c; RETURN }; IF merge AND firstLooks=firstLks THEN c _ c-1; RETURN [count+c, TRUE, lastLks] }; node => WITH x:x SELECT FROM substr => { len _ MIN[len, CheckLongSub[x.size, start]]; start _ start + x.start; ref _ x.base; LOOP}; concat => { xpos: Offset _ x.pos; len _ MIN[len, CheckLongSub[x.size, start]]; IF start < xpos THEN { subLen: Offset _ xpos - start; IF len <= subLen THEN { ref _ x.base; LOOP }; [c, merge, firstLooks] _ CountRunsAfterChanges[ x.base,start,subLen, limit,remove,add,merge,firstLooks]; count _ count+c; IF c > limit THEN RETURN; limit _ limit-c; start _ xpos; len _ len-subLen }; start _ start-xpos; ref _ x.rest; LOOP }; replace => { xstart: Offset _ x.start; xnew: Offset _ x.newPos; len _ MIN[len, CheckLongSub[x.size, start]]; IF start < xstart THEN { subLen: Offset _ xstart - start; IF len <= subLen THEN {ref _ x.base; LOOP}; [c, merge, firstLooks] _ CountRunsAfterChanges[ x.base,start,subLen, limit,remove,add,merge,firstLooks]; count _ count+c; IF c > limit THEN RETURN; limit _ limit-c; start _ xstart; len _ len-subLen}; IF start < xnew THEN { st: Offset _ start - xstart; subLen: Offset _ xnew - start; IF len <= subLen THEN { start _ st; ref _ x.replace; LOOP}; [c, merge, firstLooks] _ CountRunsAfterChanges[ x.replace,st,subLen,limit,remove,add,merge,firstLooks]; count _ count+c; IF c > limit THEN RETURN; limit _ limit-c; start _ xnew; len _ len-subLen}; start _ start - xnew + x.oldPos; ref _ x.base; LOOP}; change => { xstart: Offset _ x.start; xend, subLen: Offset; len _ MIN[len, CheckLongSub[x.size, start]]; IF start < xstart THEN { IF len <= (subLen _ xstart-start) THEN {ref _ x.base; LOOP}; [c, merge, firstLooks] _ CountRunsAfterChanges[ x.base,start,subLen,limit,remove,add,merge,firstLooks]; count _ count+c; IF c > limit THEN RETURN; limit _ limit-c; start _ xstart; len _ len-subLen}; IF start < (xend _ xstart+x.len) THEN { newRemove, newAdd: Looks; [newRemove, newAdd] _ MergeChanges[x.remove, x.add, remove, add]; subLen _ MIN[xend-start,len]; [c, merge, firstLooks] _ CountRunsAfterChanges[ x.base,start,subLen, limit,newRemove,newAdd,merge,firstLooks]; count _ count+c; IF c > limit THEN RETURN; limit _ limit-c; start _ xend; len _ len-subLen}; ref _ x.base; LOOP}; ENDCASE => ERROR; ENDCASE => ERROR; ENDLOOP}; ExtractRunsAfterChanges: PUBLIC PROC [base: BaseRuns, ref: Runs, remove, add: Looks, start: Offset, len: Offset, index: NAT _ 0] RETURNS [NAT] = TRUSTED { -- value is next index IF len>0 AND remove=allLooks THEN RETURN [InsertRun[base, len, add, index]]; DO IF len=0 THEN RETURN [index]; IF ref=NIL THEN -- treat as noLooks RETURN [InsertRun[base, len, add, index]]; WITH x:ref SELECT FROM base => { first, last: NAT; firstLen, lastLen, xloc, next, loc, size: Offset; newLooks, oldLooks: Looks; len _ IF (size_TbaseSize[@x]) < start THEN 0 ELSE MIN[len,size-start]; [first, last] _ FindBaseRuns[@x, start, len]; [firstLen, lastLen] _ BaseRunLengths[@x,start,len,first,last]; oldLooks _ ModifyLooks[x[first].looks, remove, add]; IF index=0 THEN { -- this is the first run to be extracted loc _ firstLen; base[0] _ [loc, oldLooks]; index _ 1 } ELSE { loc _ base[index-1].after + firstLen; IF base[index-1].looks=oldLooks -- merge runs THEN base[index-1].after _ loc ELSE { base[index] _ [loc, oldLooks]; index _ index+1 }}; xloc _ x[first].after; FOR i: NAT IN (first..last] DO newLooks _ ModifyLooks[x[i].looks, remove, add]; next _ IF i=last THEN xloc+lastLen ELSE x[i].after; loc _ loc+next-xloc; xloc _ next; IF newLooks # oldLooks THEN { base[index] _ [loc, newLooks]; oldLooks _ newLooks; index _ index+1 } ELSE base[index-1].after _ loc; ENDLOOP; RETURN [index] }; node => WITH x:x SELECT FROM substr => { len _ MIN[len, CheckLongSub[x.size, start]]; start _ start + x.start; ref _ x.base; LOOP}; concat => { xpos: Offset _ x.pos; len _ MIN[len, CheckLongSub[x.size, start]]; IF start < xpos THEN { subLen: Offset _ xpos - start; IF len <= subLen THEN { ref _ x.base; LOOP }; index _ ExtractRunsAfterChanges[ base,x.base,remove,add,start,subLen,index]; start _ xpos; len _ len-subLen }; start _ start-xpos; ref _ x.rest; LOOP }; replace => { xstart: Offset _ x.start; xnew: Offset _ x.newPos; len _ MIN[len, CheckLongSub[x.size, start]]; IF start < xstart THEN { subLen: Offset _ xstart - start; IF len <= subLen THEN {ref _ x.base; LOOP}; index _ ExtractRunsAfterChanges[ base,x.base,remove,add,start,subLen,index]; start _ xstart; len _ len-subLen}; IF start < xnew THEN { st: Offset _ start - xstart; subLen: Offset _ xnew - start; IF len <= subLen THEN { start _ st; ref _ x.replace; LOOP}; index _ ExtractRunsAfterChanges[ base,x.replace,remove,add,st,subLen,index]; start _ xnew; len _ len-subLen}; start _ start - xnew + x.oldPos; ref _ x.base; LOOP}; change => { xstart: Offset _ x.start; xend, subLen: Offset; len _ MIN[len, CheckLongSub[x.size, start]]; IF start < xstart THEN { IF len <= (subLen _ xstart-start) THEN {ref _ x.base; LOOP}; index _ ExtractRunsAfterChanges[ base,x.base,remove,add,start,subLen,index]; start _ xstart; len _ len-subLen}; IF start < (xend _ xstart+x.len) THEN { newRemove, newAdd: Looks; [newRemove,newAdd] _ MergeChanges[x.remove,x.add,remove,add]; subLen _ MIN[xend-start,len]; index _ ExtractRunsAfterChanges[ base,x.base,newRemove,newAdd,start,subLen,index]; start _ xend; len _ len-subLen}; ref _ x.base; LOOP}; ENDCASE => ERROR; ENDCASE => ERROR; ENDLOOP}; LooksStats: PUBLIC PROC [base: Runs, start: Offset _ 0, len: Offset _ MaxOffset] RETURNS [size, pieces, depth: Offset] = TRUSTED { rem, altDepth, subSize, subDepth, subPieces: Offset; size _ 0; rem _ Size[base] - start; altDepth _ 0; IF len > rem THEN len _ rem; pieces _ depth _ 0; WHILE len > 0 DO x: Runs _ base; WITH x: x SELECT FROM base => { first, last: NAT; [first,last] _ FindBaseRuns[@x,start,len]; RETURN [size+last-first+1,pieces+1,MAX[depth,altDepth]] }; node => { depth _ depth+1; WITH x: x SELECT FROM substr => {base _ x.base; start _ start + x.start; LOOP}; concat => {subLen: Offset _ x.pos - start; IF subLen > 0 THEN {IF len <= subLen THEN {base _ x.base; LOOP}; [subSize,subPieces,subDepth] _ LooksStats[x.base, start, subLen]; pieces _ pieces+subPieces; size _ size+subSize; altDepth _ MAX[altDepth,depth+subDepth]; len _ len - subLen; start _ 0} ELSE start _ -subLen; base _ x.rest; LOOP}; replace => {xstart: Offset _ x.start; len1: Offset _ xstart - start; base _ x.base; IF len1 > 0 THEN {-- a piece in first section IF len1 >= len THEN LOOP; -- only in first section [subSize,subPieces,subDepth] _ LooksStats[base, start, len1]; pieces _ pieces+subPieces; size _ size+subSize; altDepth _ MAX[altDepth,depth+subDepth]; start _ xstart; len _ len - len1; len1 _ 0}; {xpos: Offset _ x.newPos; len2: Offset _ xpos - start; IF len2 <= 0 THEN {-- no piece in middle section start _ x.oldPos - len2; LOOP}; base _ x.replace; start _ -len1; IF len2 >= len THEN LOOP; -- only in middle section [subSize,subPieces,subDepth] _ LooksStats[base, start, len2]; pieces _ pieces+subPieces; size _ size+subSize; altDepth _ MAX[altDepth,depth+subDepth]; base _ x.base; start _ x.oldPos; len _ len - len2; }}; change => {base _ x.base; LOOP}; ENDCASE => ERROR }; ENDCASE => ERROR; ENDLOOP; RETURN [0,0,0]; }; Lks: TYPE = ARRAY [0..1] OF UNSPECIFIED; LooksAND: PUBLIC PROC [looks1, looks2: Looks] RETURNS [Looks] = TRUSTED { OPEN Inline; lks1: Lks _ LOOPHOLE[looks1]; lks2: Lks _ LOOPHOLE[looks2]; lks: Lks; lks[0] _ BITAND[lks1[0],lks2[0]]; lks[1] _ BITAND[lks1[1],lks2[1]]; RETURN [LOOPHOLE[lks]] }; LooksOR: PUBLIC PROC [looks1, looks2: Looks] RETURNS [Looks] = TRUSTED { OPEN Inline; lks1: Lks _ LOOPHOLE[looks1]; lks2: Lks _ LOOPHOLE[looks2]; lks: Lks; lks[0] _ BITOR[lks1[0],lks2[0]]; lks[1] _ BITOR[lks1[1],lks2[1]]; RETURN [LOOPHOLE[lks]] }; LooksNOT: PUBLIC PROC [looks: Looks] RETURNS [Looks] = TRUSTED { OPEN Inline; lks: Lks _ LOOPHOLE[looks]; lks[0] _ BITNOT[lks[0]]; lks[1] _ BITNOT[lks[1]]; RETURN [LOOPHOLE[lks]] }; StartTextLooksSupport: PUBLIC PROC = { }; END. ò-- TextLooksSupportImpl.mesa -- written by Bill Paxton, February 1981 -- last edit by Bill Paxton, 10-Feb-82 12:58:05 Last Edited by: Maxwell, January 5, 1983 3:57 pm -- support procedures -- equivalent procedures including changed looks -- stops counting when exceeds limit -- if firstSize is > 0, then tries to merge with first run -- find the runs in x in [start..start+len) -- modify looks according to remove&add -- return count of distinct runs after modify -- and looks of first & last runs after modify -- now compute count, lastLooks, and lastSize -- three pieces to consider (first, middle, last) -- a piece in middle section of replace node -- compute looks1 & looks2 -- compute looks1 v looks2 -- compute ~looks -- ***** Initialization Ê Ð˜JšÏc™Jš(™(Jš/™/J™0JšÏk ˜ J˜J˜ J˜J˜ J˜šœž ˜#Jšžœ$˜+Jšžœ˜#Jšžœ ˜—Jšžœžœ˜'J˜Jš™J˜Jš0™0J˜šÏnœžœž˜"˜:Jšœžœžœ˜H—Jšžœ žœ žœžœ˜EJš$™$Jš:™:šŸœž˜˜'J˜.—Jšžœ žœ"žœžœ˜EJš+™+Jš'™'Jš-™-Jš.™.Jšœ žœ˜Jšžœžœžœ˜-J˜,J˜ J˜Bšžœžœžœž˜J˜7šžœžœ˜Jšžœžœžœ˜)J˜—Jšžœ˜ ——Jšœžœ˜Jšžœžœžœ˜,šžœžœžœ˜ Jš žœžœžœžœžœ˜6—J˜ šžœ˜J˜Jšžœžœžœ˜1šžœžœžœ˜Jš œžœžœžœžœ˜.Jšžœ žœ ˜—Jšžœžœž˜˜ J˜ J˜Jšœžœ/˜8˜'J˜$—Jš-™-Jšžœ žœžœ˜.Jšžœžœžœ ˜.Jšžœ žœ ˜"—šœžœžœž˜˜ Jšœžœ#˜,Jšœ'žœ˜-—˜ J˜Jšœžœ#˜,šžœžœ˜J˜Jšžœžœžœ˜-˜/J˜J˜$—Jšœžœ žœžœ˜*J˜J˜"—Jšœ"žœ˜)—˜ J˜J˜Jšœžœ#˜,šžœžœ˜J˜ Jšžœžœžœ˜+˜/J˜J˜$—Jšœžœ žœžœ˜*J˜3—šžœžœ˜J˜J˜šžœžœ˜Jšœžœ˜#—˜/J˜8—Jšœžœ žœžœ˜*J˜1—Jšœ/žœ˜5—˜ J˜J˜Jšœžœ#˜,šžœžœ˜Jšžœ žœžœ˜<˜/J˜8—Jšœžœ žœžœ˜*J˜3—šžœžœ˜'J˜˜J˜+—Jšœ žœ˜˜/J˜J˜*—Jšœžœ žœžœ˜*J˜1—Jšœžœ˜—Jšžœžœ˜—Jšžœžœ˜Jšžœ˜ J˜——šŸœžœž˜$˜/Jšœ#žœ˜+—Jšžœžœžœ˜0šžœžœž˜!Jšžœ$˜*—šžœ˜Jšžœžœžœ ˜šžœžœžœ˜#Jšžœ$˜*—Jšžœžœž˜˜ Jšœ žœ˜J˜1J˜Jš œžœžœžœžœ˜FJ˜-J˜>J˜4šžœ žœ(˜:J˜6—šžœ˜J˜%šžœ ˜-Jšžœ˜—Jšžœ5˜9—J˜šžœžœžœž˜J˜0Jšœžœžœžœ ˜3J˜!šžœžœ˜J˜J˜&—Jšžœ˜Jšžœ˜—Jšžœ ˜—šœžœžœž˜˜ Jšœžœ#˜,Jšœ'žœ˜-—˜ J˜Jšœžœ#˜,šžœžœ˜J˜Jšžœžœžœ˜-˜ J˜+—J˜"—Jšœ"žœ˜)—˜ J˜J˜Jšœžœ#˜,šžœžœ˜J˜ Jšžœžœžœ˜+˜ J˜,—J˜"—šžœžœ˜J˜J˜šžœžœ˜Jšœžœ˜#—˜ J˜,—J˜ —Jšœ/žœ˜5—˜ J˜J˜Jšœžœ#˜,šžœžœ˜Jšžœ žœžœ˜<˜ J˜,—J˜"—šžœžœ˜'J˜˜J˜(—Jšœ žœ˜˜ J˜2—J˜ —Jšœžœ˜—Jšžœžœ˜—Jšžœžœ˜Jšžœ˜ J˜——šŸ œžœžœ9˜PJšžœ"žœ˜2J˜4J˜ J˜J˜ Jšžœ žœ ˜J˜šžœ ž˜J˜šžœžœž˜˜ Jšœ žœ˜J˜*Jšžœžœ˜:—˜ J˜šžœžœž˜˜ Jšœ)žœ˜/—˜ ˜ šžœ žœ˜šœžœžœžœ˜-J˜AJ˜J˜Jšœ žœ˜(J˜—Jšžœ˜—Jšœžœ˜——˜ Jš1™1˜J˜J˜šžœ ž˜šœ˜Jšžœ žœžœ˜2J˜=J˜J˜Jšœ žœ˜(J˜,——˜J˜šžœ ž˜šœ˜Jšœžœ˜——Jš,™,J˜ Jšžœ žœžœ˜3J˜=J˜J˜Jšœ žœ˜(J˜2J˜———Jšœžœ˜ Jšžœžœ˜——Jšžœžœ˜—Jšžœ˜—Jšžœ ˜J˜J˜—Jš œžœžœžœž œ˜(J˜š Ÿœžœžœžœ žœ˜IJš™Jšžœ˜ Jšœ žœ ˜Jšœ žœ ˜J˜ Jšœ žœ˜!Jšœ žœ˜!Jšžœžœ ˜J˜—š Ÿœžœžœžœ žœ˜HJš™Jšžœ˜ Jšœ žœ ˜Jšœ žœ ˜J˜ Jšœ žœ˜ Jšœ žœ˜ Jšžœžœ ˜J˜—š Ÿœžœžœžœ žœ˜@Jš™Jšžœ˜ Jšœ žœ˜Jšœ žœžœ ˜1Jšžœžœ ˜J˜—Jš™J˜šŸœžœžœ˜&J˜J˜—Jšžœ˜J˜J˜—…—%x3: