<> <> <> <> DIRECTORY TreeFind, TextFind, TiogaNode, TiogaNodeOps, TiogaPathOps, TextEdit, NameSymbolTable, Rope; TreeFindImpl: CEDAR PROGRAM IMPORTS TextFind, TiogaNodeOps, TiogaPathOps EXPORTS TreeFind = BEGIN OPEN TreeFind, TiogaNode; Try: PUBLIC PROC [finder: Finder, first: Path, start: Offset _ 0, last: Path _ [NIL, NIL], lastLen: Offset _ MaxLen, looksExact: BOOLEAN _ FALSE, commentControl: CommentControl _ includeComments, checkFormat: BOOLEAN _ FALSE, format: TiogaNode.Name _ TiogaNode.nullName, checkStyle: BOOLEAN _ FALSE, style: NameSymbolTable.Name _ NameSymbolTable.nullName, styleProc: PROC [Ref] RETURNS [NameSymbolTable.Name] _ NIL, interrupt: REF BOOL _ NIL] RETURNS [found: BOOLEAN, where: Path, at, atEnd, before, after: Offset] = TRUSTED { p: Path _ first; found _ FALSE; DO -- test new node each time through the loop n: TiogaNode.RefTextNode; node: TiogaNode.Ref; lastOne: BOOL = TiogaPathOps.Equal[p, last]; IF (node _ p.node)=NIL THEN RETURN; IF checkFormat AND node.format # format THEN NULL ELSE IF checkStyle AND styleProc[node] # style THEN NULL ELSE IF (n _ TiogaNodeOps.NarrowToTextNode[node])#NIL THEN BEGIN 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 lastOne THEN lastLen-start ELSE MaxLen,looksExact,interrupt] ELSE { found _ TRUE; at _ before _ 0; atEnd _ after _ TiogaNodeOps.Size[n] }; END; IF found THEN { where _ p; RETURN }; END; <> start _ 0; IF lastOne THEN RETURN; p _ TiogaPathOps.StepForwardNode[p]; ENDLOOP }; TryBackwards: PUBLIC PROC [finder: TextFind.Finder, first: Path, len: Offset _ MaxLen, last: Path _ [NIL, NIL], lastStart: Offset _ 0, looksExact: BOOLEAN _ FALSE, commentControl: CommentControl _ includeComments, checkFormat: BOOLEAN _ FALSE, format: TiogaNode.Name _ TiogaNode.nullName, checkStyle: BOOLEAN _ FALSE, style: NameSymbolTable.Name _ NameSymbolTable.nullName, styleProc: PROC [Ref] RETURNS [NameSymbolTable.Name] _ NIL, interrupt: REF BOOL _ NIL] RETURNS [found: BOOLEAN, where: Path, at, atEnd, before, after: Offset] = TRUSTED { p, parent: Path; found _ FALSE; p _ first; DO -- test new node each time through the loop n: TiogaNode.RefTextNode; node: TiogaNode.Ref; lastOne: BOOL = TiogaPathOps.Equal[p, last]; IF (node _ p.node)=NIL THEN RETURN; IF checkFormat AND node.format # format THEN NULL ELSE IF checkStyle AND styleProc[node] # style THEN NULL ELSE IF (n _ TiogaNodeOps.NarrowToTextNode[node])#NIL THEN BEGIN 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 lastOne THEN lastStart ELSE 0,len,looksExact,interrupt] ELSE { found _ TRUE; at _ before _ 0; atEnd _ after _ TiogaNodeOps.Size[n] }; END; IF found THEN { where _ p; RETURN }; END; <> IF lastOne THEN RETURN; [p,parent] _ TiogaPathOps.StepBackwardNode[p,parent]; len _ MaxLen; ENDLOOP }; Apply: PUBLIC PROC [finder: Finder, first: Path, proc: ApplyProc, start: Offset _ 0, last: Path _ [NIL, NIL], lastLen: Offset _ MaxLen, looksExact: BOOLEAN _ FALSE, commentControl: CommentControl _ includeComments, checkFormat: BOOLEAN _ FALSE, format: TiogaNode.Name _ TiogaNode.nullName, checkStyle: BOOLEAN _ FALSE, style: NameSymbolTable.Name _ NameSymbolTable.nullName, styleProc: PROC [Ref] RETURNS [NameSymbolTable.Name] _ NIL] RETURNS [count: LONG INTEGER] = { where, p: Path; at, atEnd, before, after, from, delta: Offset; found, continue, bumpCount: BOOLEAN; count _ 0; p _ first; UNTIL p.node=NIL DO IF TiogaPathOps.Equal[p, last] AND start >= lastLen THEN RETURN; [found,where,at,atEnd,before,after] _ Try[finder,p,start,last,lastLen,looksExact,commentControl, checkFormat,format,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 TiogaPathOps.Equal[where, last] AND lastLen < MaxLen THEN lastLen _ lastLen+delta; IF finder # NIL THEN { p _ where; start _ from } ELSE { p _ TiogaPathOps.StepForwardNode[p]; start _ 0 }; ENDLOOP }; END.