<<-- TreeFindImpl.Mesa>> <<-- written by Bill Paxton, June 1981>> <<-- last written by Paxton, December 30, 1982 10:33 am>> <> 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.