<> <> <> <> DIRECTORY Basics USING [Comparison], EditSpan USING [InsertTextNode, Place], IndexProps USING [Compare, IndexEntry, Phrases], IndexTree, IO USING [PutFR, rope], RedBlackTree USING [Create, Compare, Delete, DuplicateKey, GetKey, Insert, Lookup3, LookupNextLarger, Table], Rope USING [Cat, Compare, Concat, Length, Equal, ROPE], TextNode USING [Body, Parent, Ref, Span], TiogaButtons USING [CreateButtonFromNode, TiogaButton, TiogaButtonProc], TiogaFileOps USING [InsertNode, SetContents], TiogaOps USING [CompareNodeOrder, GetRope, Parent, Ref], TiogaOpsDefs USING []; -- convince the compiler I know what a Ref really is! IndexTreeImpl: CEDAR PROGRAM IMPORTS EditSpan, IO, IndexProps, RedBlackTree, Rope, TextNode, TiogaButtons, TiogaFileOps, TiogaOps EXPORTS TiogaOpsDefs, TiogaFileOps, IndexTree = BEGIN ROPE: TYPE = Rope.ROPE; Comparison: TYPE = Basics.Comparison; NodeBody: PUBLIC TYPE = TextNode.Body; Index: TYPE ~ IndexTree.Index; IxItem: TYPE ~ IndexTree.IxItem; IxItemRec: TYPE ~ IndexTree.IxItemRec; Table: TYPE ~ RedBlackTree.Table; DuplicateKey: PUBLIC SIGNAL = CODE; -- if ix entry already present in the indexTable <<>> <<>> <<>> <> <<>> <<>> <<>> CreateIndex: PUBLIC PROC [root: TiogaOps.Ref] RETURNS [index: Index] ~ { index.table _ RedBlackTree.Create[getKey: IxItemGetKey, compare: IxItemCompare]; index.root _ root; }; <<>> IxItemGetKey: RedBlackTree.GetKey ~ { RETURN [data]; }; <<>> IxItemCompare: RedBlackTree.Compare ~ { <> ixItem1: IxItem ~ NARROW[k]; ixItem2: IxItem ~ NARROW[data]; result: Basics.Comparison _ IndexProps.Compare[ixItem1.ix, ixItem2.ix].result; IF result # equal THEN RETURN [result]; <> { see1: IndexProps.Phrases _ ixItem1.ix.seePhrases; see2: IndexProps.Phrases _ ixItem1.ix.seePhrases; a: ROPE; b: ROPE; UNTIL see1 = NIL DO a _ see1.first; b _ IF see2 # NIL THEN see2.first ELSE NIL; result _ Rope.Compare[a, b, FALSE]; IF result # equal THEN RETURN [result]; see1 _ see1.rest; IF see2 # NIL THEN see2 _ see2.rest; ENDLOOP; IF see2 # NIL THEN RETURN [less]; }; <> RETURN [CompareSpanOrder[ixItem1.range, ixItem2.range]]; }; <<>> CompareSpanOrder: PROC [span1, span2: TextNode.Span] RETURNS [result: Basics.Comparison] ~ { <