TreeFindImpl.Mesa; written by Bill Paxton, June 1981
edited by McGregor, February 8, 1983 9:59 am
edited by Paxton, June 9, 1983 10:44 am
edited by Maxwell, January 5, 1983 3:51 pm
DIRECTORY
TreeFind,
TextFind,
TiogaNode,
TiogaNodeOps,
TextEdit,
NameSymbolTable,
Rope;
TreeFindImpl: CEDAR PROGRAM
IMPORTS TextFind, TiogaNodeOps, TextEdit
EXPORTS TreeFind =
BEGIN OPEN TreeFind, TiogaNode;
Try: PUBLIC PROC [finder: Finder, first: Ref, start: Offset ← 0,
last: Ref ← NIL, lastLen: Offset ← MaxLen, looksExact: BOOLEANFALSE,
commentControl: CommentControl ← includeComments,
checkType: BOOLEANFALSE, type: TiogaNode.Name ← TiogaNode.nullName,
checkStyle: BOOLEANFALSE, style: NameSymbolTable.Name ← NameSymbolTable.nullName,
styleProc: PROC [Ref] RETURNS [NameSymbolTable.Name] ← NIL,
interrupt: REF BOOLNIL]
RETURNS [found: BOOLEAN, where: RefTextNode, at, atEnd, before, after: Offset] = TRUSTED {
node: Ref;
found ← FALSE;
IF (node ← first)=NIL THEN RETURN;
DO-- test new node each time through the loop
IF checkType AND node.format # type THEN NULL
ELSE IF checkStyle AND styleProc[node] # style THEN NULL
ELSE IF TiogaNodeOps.IsText[node] THEN BEGIN
n: TiogaNode.RefTextNode = TiogaNodeOps.NarrowToTextNode[node];
IF (SELECT commentControl FROM
excludeComments => ~n.comment,
commentsOnly => n.comment,
ENDCASE => TRUE) THEN BEGIN
IF finder # NIL THEN
[found,at,atEnd,before,after] ←
TextFind.Try[finder,n,start,
IF n=last THEN lastLen-start ELSE MaxLen,looksExact,interrupt]
ELSE { found ← TRUE;
at ← before ← 0;
atEnd ← after ← TextEdit.Size[n] };
END;
IF found THEN { where ← n; RETURN };
END;
go to next one
start ← 0;
IF node=last THEN RETURN;
IF (node ← TiogaNodeOps.StepForwardNode[node])=NIL THEN RETURN;
ENDLOOP };
TryBackwards: PUBLIC PROC [finder: TextFind.Finder, first: Ref,
len: Offset ← MaxLen, last: Ref ← NIL, lastStart: Offset ← 0,
looksExact: BOOLEANFALSE, commentControl: CommentControl ← includeComments,
checkType: BOOLEANFALSE, type: TiogaNode.Name ← TiogaNode.nullName,
checkStyle: BOOLEANFALSE, style: NameSymbolTable.Name ← NameSymbolTable.nullName,
styleProc: PROC [Ref] RETURNS [NameSymbolTable.Name] ← NIL,
interrupt: REF BOOLNIL]
RETURNS [found: BOOLEAN, where: RefTextNode, at, atEnd, before, after: Offset] = TRUSTED {
node, parent: Ref;
found ← FALSE;
IF (node ← first)=NIL THEN RETURN;
DO-- test new node each time through the loop
IF checkType AND node.format # type THEN NULL
ELSE IF checkStyle AND styleProc[node] # style THEN NULL
ELSE IF TiogaNodeOps.IsText[node] THEN BEGIN
n: TiogaNode.RefTextNode = TiogaNodeOps.NarrowToTextNode[node];
IF (SELECT commentControl FROM
excludeComments => ~n.comment,
commentsOnly => n.comment,
ENDCASE => TRUE) THEN BEGIN
IF finder # NIL THEN
[found,at,atEnd,before,after] ← TextFind.TryBackwards[finder,n,
IF n=last THEN lastStart ELSE 0,len,looksExact,interrupt]
ELSE { found ← TRUE;
at ← before ← 0;
atEnd ← after ← TextEdit.Size[n] };
END;
IF found THEN { where ← n; RETURN };
END;
go to next one
len ← MaxLen;
IF node=last THEN RETURN;
[node,parent] ← TiogaNodeOps.StepBackwardNode[node,parent];
IF node=NIL THEN RETURN;
ENDLOOP };
Apply: PUBLIC PROC [finder: Finder, first: Ref, proc: ApplyProc, start: Offset ← 0,
last: Ref ← NIL, lastLen: Offset ← MaxLen, looksExact: BOOLEANFALSE,
commentControl: CommentControl ← includeComments,
checkType: BOOLEANFALSE, type: TiogaNode.Name ← TiogaNode.nullName,
checkStyle: BOOLEANFALSE, style: NameSymbolTable.Name ← NameSymbolTable.nullName,
styleProc: PROC [Ref] RETURNS [NameSymbolTable.Name] ← NIL]
RETURNS [count: LONG INTEGER] = {
where: RefTextNode;
node: Ref;
at, atEnd, before, after, from, delta: Offset;
found, continue, bumpCount: BOOLEAN;
count ← 0; node ← first;
UNTIL node=NIL DO
IF node=last AND start >= lastLen THEN RETURN;
[found,where,at,atEnd,before,after] ←
Try[finder,node,start,last,lastLen,looksExact,commentControl,
checkType,type,checkStyle,style,styleProc];
IF ~found THEN RETURN;
[continue,bumpCount,from,delta] ← proc[where,at,atEnd,before,after];
IF bumpCount THEN count ← count+1;
IF ~continue THEN RETURN;
IF where=last AND lastLen < MaxLen THEN lastLen ← lastLen+delta;
IF finder # NIL THEN { node ← where; start ← from }
ELSE { node ← TiogaNodeOps.StepForwardNode[node]; start ← 0 };
ENDLOOP };
END.