<<-- TreeFind.mesa>> <<-- written by Bill Paxton, June 1981>> <<-- last edit by Bill Paxton, December 30, 1982 10:30 am>> <<-- This module provides a "Find" operation for text in trees>> <<-- The pattern matching is done by TextFind.Mesa>> <<-- This module simply walks the tree (forward or backwards) applying the text>> DIRECTORY TextFind, TextNode, NameSymbolTable, Rope; TreeFind: CEDAR DEFINITIONS IMPORTS TextFind = BEGIN Ref: TYPE = TextNode.Ref; RefTextNode: TYPE = TextNode.RefTextNode; Offset: TYPE = TextNode.Offset; ROPE: TYPE = Rope.ROPE; MaxLen: Offset = LAST[Offset]; Finder: TYPE = TextFind.Finder; Create: PROC [ pattern: RefTextNode, literal, word, ignoreLooks, ignoreCase, addBounds: BOOLEAN _ FALSE, patternStart: Offset _ 0, patternLen: Offset _ MaxLen] RETURNS [Finder] = INLINE { RETURN [TextFind.Create[ pattern,literal,word,ignoreLooks,ignoreCase,addBounds,patternStart,patternLen]] }; <<-- creates a record containing a "compiled" version of the pattern>> <<-- see TextFind.Mesa for more info about patterns>> <<-- if literal is true, each character in pattern is taken literally>> <<-- if word flag is true, pattern only matches if no adjacent letters or digits>> <<-- if ignoreLooks if true, then ignore the looks of the pattern characters>> <<-- if ignoreCase is false, then alpha chars in pattern must match case>> <<-- otherwise, they can match either upper or lower>> <<-- if addBounds is true, add |'s to both ends of pattern>> CreateFromRope: PROC [pattern: ROPE, literal, word, ignoreCase, addBounds: BOOLEAN _ FALSE, patternStart: Offset _ 0, patternLen: Offset _ MaxLen] RETURNS [Finder] = INLINE { RETURN [TextFind.CreateFromRope[ pattern,literal,word,ignoreCase,addBounds,patternStart,patternLen]] }; CommentControl: TYPE = { includeComments, excludeComments, commentsOnly }; Try: 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]; <<-- searches first node beginning at start>> <<-- continues until finds a match or reaches last node>> <<-- seaches lastLen chars in last node; seaches to end of other nodes>> <<-- if finds a match, returns with found = true,>> <<-- at = beginning of match or location corresponding to { in pattern>> <<-- atEnd = end of match or location corresponding to } in pattern>> <<-- after = end of entire match, which may be > atEnd if used } in pattern>> <<-- before = start of entire match, which may be < at if used { in pattern>> <<-- if looksExact is true, then match by equality, else by subset>> <<-- commentControl allows restriction of search to comments/noncomments>> <<-- if checkType is true, then only match in nodes with given type>> <<-- if checkStyle is true, then only match in nodes with given style>> <<-- styleProc is supplied so called can determine style for nodes>> <<-- if just interested in type/style, can pass finder=NIL>> <<-- if interrupt^ becomes true, will stop searching>> TryBackwards: PROC [finder: 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]; <<-- searches first node from start=0 to end=len>> <<-- continues back through tree until finds a match or reaches last node>> <<-- searches from lastStart in last node; searches from 0 in other nodes>> Apply: 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]; <<-- finds a span of text and calls proc>> ApplyProc: TYPE = PROC [where: RefTextNode, at, atEnd, before, after: Offset] RETURNS [continue, bumpCount: BOOLEAN, from, delta: Offset]; <<-- arg's are results from Try>> <<-- if continue is true, Apply will Try again starting at "from" in "where">> <<-- delta tells change in length caused by the action>> <<-- Apply does the following with delta>> <<-- IF where=last AND lastLen < MaxLen THEN lastLen _ lastLen+delta>> <<-- if bumpCount is true, Apply will increment its result counter>> END.