TreeFind.mesa; written by Bill Paxton, June 1981
edited by McGregor, February 8, 1983 9:43 am
edited 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,
TiogaNode,
Rope;
TreeFind: CEDAR DEFINITIONS IMPORTS TextFind =
BEGIN
Path: TYPE = TiogaNode.Path;
Ref: TYPE = TiogaNode.Ref;
RefTextNode: TYPE = TiogaNode.RefTextNode;
Offset: TYPE = TiogaNode.Offset;
ROPE: TYPE = Rope.ROPE;
MaxLen: Offset = LAST[Offset];
Finder: TYPE = TextFind.Finder;
Create: PROC [
pattern: RefTextNode, literal, word, ignoreLooks, ignoreCase, addBounds: BOOLFALSE,
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: BOOLFALSE,
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: Path, start: Offset ← 0,
last: Path ← [NIL, NIL], lastLen: Offset ← MaxLen, looksExact: BOOLEANFALSE,
commentControl: CommentControl ← includeComments,
checkFormat: BOOLEANFALSE, format: TiogaNode.Name ← TiogaNode.nullName,
checkStyle: BOOLEANFALSE, style: TiogaNode.Name ← TiogaNode.nullName,
styleProc: PROC [Ref] RETURNS [TiogaNode.Name] ← NIL,
interrupt: REF BOOLNIL]
RETURNS [found: BOOLEAN, where: Path, 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: Path,
len: Offset ← MaxLen, last: Path ← [NIL, NIL], lastStart: Offset ← 0,
looksExact: BOOLEANFALSE, commentControl: CommentControl ← includeComments,
checkFormat: BOOLEANFALSE, format: TiogaNode.Name ← TiogaNode.nullName,
checkStyle: BOOLEANFALSE, style: TiogaNode.Name ← TiogaNode.nullName,
styleProc: PROC [Ref] RETURNS [TiogaNode.Name] ← NIL,
interrupt: REF BOOLNIL]
RETURNS [found: BOOLEAN, where: Path, 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: Path, proc: ApplyProc, start: Offset ← 0,
last: Path ← [NIL, NIL], lastLen: Offset ← MaxLen, looksExact: BOOLFALSE,
commentControl: CommentControl ← includeComments,
checkFormat: BOOLEANFALSE, format: TiogaNode.Name ← TiogaNode.nullName,
checkStyle: BOOLEANFALSE, style: TiogaNode.Name ← TiogaNode.nullName,
styleProc: PROC [Ref] RETURNS [TiogaNode.Name] ← NIL]
RETURNS [count: LONG INTEGER];
finds a span of text and calls proc
ApplyProc: TYPE = PROC [where: Path, at, atEnd, before, after: Offset]
RETURNS [continue, bumpCount: BOOL, 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.