DIRECTORY Rope USING [ROPE], TextEdit USING [Size], TextFind USING [Create, CreateFromRope, Finder, Try, TryBackwards], TextLooks USING [], TextNode USING [Backward, Node, StepForward], TreeFind USING [ApplyProc, CommentControl]; TreeFindImpl: CEDAR PROGRAM IMPORTS TextFind, TextNode, TextEdit EXPORTS TreeFind = BEGIN OPEN TreeFind; Finder: TYPE ~ TextFind.Finder; ROPE: TYPE = Rope.ROPE; Node: TYPE = TextNode.Node; Create: PUBLIC PROC [ pattern: Node, literal, word, ignoreLooks, ignoreCase, addBounds: BOOL _ FALSE, patternStart: INT _ 0, patternLen: INT _ LAST[INT]] RETURNS [Finder] = { RETURN [TextFind.Create[ pattern, literal, word, ignoreLooks, ignoreCase, addBounds, patternStart, patternLen]] }; CreateFromRope: PUBLIC PROC [pattern: ROPE, literal, word, ignoreCase, addBounds: BOOL _ FALSE, patternStart: INT _ 0, patternLen: INT _ LAST[INT]] RETURNS [Finder] = { RETURN [ TextFind.CreateFromRope[pattern, literal, word, ignoreCase, addBounds, patternStart, patternLen] ] }; Try: PUBLIC PROC [ finder: Finder, first: Node, start: INT _ 0, last: Node _ NIL, lastLen: INT _ LAST[INT], looksExact: BOOLEAN _ FALSE, commentControl: CommentControl _ includeComments, checkFormat: BOOLEAN _ FALSE, format: ATOM _ NIL, checkStyle: BOOLEAN _ FALSE, style: ATOM _ NIL, styleProc: PROC [Node] RETURNS [ATOM] _ NIL, interrupt: REF BOOL _ NIL] RETURNS [found: BOOLEAN, where: Node, at, atEnd, before, after: INT] = { node: Node; found _ FALSE; IF (node _ first)=NIL THEN RETURN; DO -- test new node each time through the loop IF checkFormat AND node.formatName # format THEN NULL ELSE IF checkStyle AND styleProc[node] # style THEN NULL ELSE { IF (SELECT commentControl FROM excludeComments => ~node.comment, commentsOnly => node.comment, ENDCASE => TRUE) THEN { IF finder # NIL THEN [found, at, atEnd, before, after] _ TextFind.Try[finder, node, start, IF node=last THEN lastLen-start ELSE LAST[INT], looksExact, interrupt] ELSE { found _ TRUE; at _ before _ 0; atEnd _ after _ TextEdit.Size[node]; }; IF found THEN { where _ node; RETURN }; }; }; IF interrupt#NIL AND interrupt^ THEN EXIT; start _ 0; IF node=last THEN RETURN; IF (node _ TextNode.StepForward[node])=NIL THEN RETURN; ENDLOOP }; TryBackwards: PUBLIC PROC [ finder: TextFind.Finder, first: Node, len: INT _ LAST[INT], last: Node _ NIL, lastStart: INT _ 0, looksExact: BOOLEAN _ FALSE, commentControl: CommentControl _ includeComments, checkFormat: BOOLEAN _ FALSE, format: ATOM _ NIL, checkStyle: BOOLEAN _ FALSE, style: ATOM _ NIL, styleProc: PROC [Node] RETURNS [ATOM] _ NIL, interrupt: REF BOOL _ NIL] RETURNS [found: BOOLEAN, where: Node, at, atEnd, before, after: INT] = { node, parent: Node; found _ FALSE; IF (node _ first)=NIL THEN RETURN; DO -- test new node each time through the loop IF checkFormat AND node.formatName # format THEN NULL ELSE IF checkStyle AND styleProc[node] # style THEN NULL ELSE { IF (SELECT commentControl FROM excludeComments => ~node.comment, commentsOnly => node.comment, ENDCASE => TRUE) THEN { IF finder # NIL THEN [found, at, atEnd, before, after] _ TextFind.TryBackwards[finder, node, IF node=last THEN lastStart ELSE 0, len, looksExact, interrupt] ELSE { found _ TRUE; at _ before _ 0; atEnd _ after _ TextEdit.Size[node]; }; IF found THEN { where _ node; RETURN } }; }; IF interrupt#NIL AND interrupt^ THEN EXIT; len _ LAST[INT]; IF node=last THEN RETURN; [node, parent] _ TextNode.Backward[node, parent]; IF node=NIL THEN RETURN; ENDLOOP }; Apply: PUBLIC PROC [ finder: Finder, first: Node, proc: ApplyProc, start: INT _ 0, last: Node _ NIL, lastLen: INT _ LAST[INT], looksExact: BOOLEAN _ FALSE, commentControl: CommentControl _ includeComments, checkFormat: BOOLEAN _ FALSE, format: ATOM _ NIL, checkStyle: BOOLEAN _ FALSE, style: ATOM _ NIL, styleProc: PROC [Node] RETURNS [ATOM] _ NIL] RETURNS [count: LONG INTEGER] = { where: Node; node: Node; at, atEnd, before, after, from, delta: INT; 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, 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 where=last AND lastLen < LAST[INT] THEN lastLen _ lastLen+delta; IF finder # NIL THEN { node _ where; start _ from } ELSE { node _ TextNode.StepForward[node]; start _ 0 }; ENDLOOP }; END. ŠTreeFindImpl.mesa Copyright Σ 1985, 1986, 1988 by Xerox Corporation. All rights reserved. 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 Michael Plass, March 29, 1985 5:34:07 pm PST Rick Beach, March 27, 1985 1:02:13 pm PST Doug Wyatt, February 17, 1988 2:30:15 pm PST go to next one go to next one Κb˜codešœ™KšœH™HKšœ!™!Kšœ2™2Kšœ0™0Kšœ,™,K™)™,K™——šΟk ˜ Jšœœœ˜Jšœ œ˜Jšœ œ5˜CJšœ œ˜Jšœ œ˜-Jšœ œ˜+—K˜KšΟn œœ˜Kšœ˜$Kšœ ˜šœœœ ˜K˜Kšœœ˜Kšœœœ˜Kšœœ˜˜K˜—šžœœœ˜Kš œBœœœœœœ˜ƒšœœ˜-K˜W—K˜—K˜šžœœœ œ(œœœœœœœ ˜¨šœ˜Kšœ`˜`Kšœ˜—K˜—K˜šDžœœœ'œœ œ œœœœœœ2œ œœ œœœ œœ œœœ œœœœœ œœœœ œ)œ˜³K˜ Kšœœ˜Kšœœœœ˜"šœΟc+˜.Kšœ œœ˜5Kš œœ œœ˜8šœ˜š œœœAœœœ˜wKšœ œœGœ œœœœ˜‘šœ˜Kšœœ˜ K˜K˜$K˜—Kšœœœ˜'K˜—K˜—Kšœ™Kš œ œœ œœ˜*K˜ Kšœ œœ˜Kšœ%œœœ˜7Kšœ˜—K˜—K˜š8ž œœœ.œœœœ œœœBœœ œœœœ œœœœœœœœœœ œ)œ˜ΔK˜Kšœœ˜Kšœœœœ˜"šœŸ+˜.Kšœ œœ˜5Kš œœ œœ˜8šœ˜š œœœAœœœ˜vKš œ œœIœ œ œ˜œšœ˜Kšœœ˜ K˜K˜$K˜—Kšœœœ˜&K˜—K˜—Kšœ™Kš œ œœ œœ˜*Kšœœœ˜Kšœ œœ˜K˜1Kšœœœœ˜Kšœ˜—K˜—K˜š:žœœœ8œœ œ œœœœœ4œ œœ œœœ œœ œœœ œœœœœ œœ˜‚K˜ K˜ Kšœ'œ˜+Kšœœ˜$K˜šœœ˜Kšœ œœœ˜.˜*˜DK˜3——Kšœœœ˜K˜KKšœ œ˜"Kšœ œœ˜Kš œ œ œœœ˜CKšœ œœ˜3Kšœ2˜6Kšœ˜—K˜——K˜Kšœ˜K˜—…—δΠ