-- TreeFindImpl.Mesa
-- written by Bill Paxton, June 1981
-- last written by Paxton, December 30, 1982 10:33 am
Last Edited by: Maxwell, January 5, 1983 3:51 pm
DIRECTORY
TreeFind,
TextFind,
TextNode,
TextLooks,
TextEdit,
NameSymbolTable,
Rope;
TreeFindImpl:
CEDAR PROGRAM
IMPORTS TextFind, TextNode, TextEdit
EXPORTS TreeFind =
BEGIN OPEN TreeFind, TextNode;
Try:
PUBLIC
PROC [finder: Finder, first: Ref, start: Offset ← 0,
last: Ref ← NIL, lastLen: Offset ← MaxLen, looksExact: BOOLEAN ← FALSE,
commentControl: CommentControl ← includeComments,
checkType: BOOLEAN ← FALSE, type: TextNode.TypeName ← TextNode.nullTypeName,
checkStyle: BOOLEAN ← FALSE, style: NameSymbolTable.Name ← NameSymbolTable.nullName,
styleProc: PROC [Ref] RETURNS [NameSymbolTable.Name] ← NIL,
interrupt: REF BOOL ← NIL]
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.typename # type THEN NULL
ELSE IF checkStyle AND styleProc[node] # style THEN NULL
ELSE WITH n:node SELECT FROM
text =>
IF (
SELECT commentControl
FROM
excludeComments => ~n.comment,
commentsOnly => n.comment,
ENDCASE => TRUE) THEN {
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] };
IF found THEN { where ← @n; RETURN }};
other => NULL;
ENDCASE => ERROR;
-- go to next one
start ← 0;
IF node=last THEN RETURN;
IF (node ← StepForward[node])=NIL THEN RETURN;
ENDLOOP };
TryBackwards:
PUBLIC
PROC [finder: TextFind.Finder, first: Ref,
len: Offset ← MaxLen, last: Ref ← NIL, lastStart: Offset ← 0,
looksExact: BOOLEAN ← FALSE, commentControl: CommentControl ← includeComments,
checkType: BOOLEAN ← FALSE, type: TextNode.TypeName ← TextNode.nullTypeName,
checkStyle: BOOLEAN ← FALSE, style: NameSymbolTable.Name ← NameSymbolTable.nullName,
styleProc: PROC [Ref] RETURNS [NameSymbolTable.Name] ← NIL,
interrupt: REF BOOL ← NIL]
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.typename # type THEN NULL
ELSE IF checkStyle AND styleProc[node] # style THEN NULL
ELSE WITH n:node SELECT FROM
text =>
IF (
SELECT commentControl
FROM
excludeComments => ~n.comment,
commentsOnly => n.comment,
ENDCASE => TRUE) THEN {
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] };
IF found THEN { where ← @n; RETURN }};
other => NULL;
ENDCASE => ERROR;
-- go to next one
len ← MaxLen;
IF node=last THEN RETURN;
[node,parent] ← Backward[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: BOOLEAN ← FALSE,
commentControl: CommentControl ← includeComments,
checkType: BOOLEAN ← FALSE, type: TextNode.TypeName ← TextNode.nullTypeName,
checkStyle: BOOLEAN ← FALSE, 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 ← StepForward[node]; start ← 0 };
ENDLOOP };
END.