⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tktextbtree.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    while (nodePtr->level > 0) {	nodePtr = nodePtr->children.nodePtr;    }    return nodePtr->children.linePtr;}/* *---------------------------------------------------------------------- * * TkBTreePreviousLine -- * *	Given an existing line in a B-tree, this procedure locates the *	previous line in the B-tree.  This procedure is used for scanning *	through the B-tree in the reverse direction. * * Results: *	The return value is a pointer to the line that immediately *	preceeds linePtr, or NULL if there is no such line. * * Side effects: *	None. * *---------------------------------------------------------------------- */TkTextLine *TkBTreePreviousLine(linePtr)    register TkTextLine *linePtr;	/* Pointer to existing line in					 * B-tree. */{    register Node *nodePtr;    register Node *node2Ptr;    register TkTextLine *prevPtr;    /*     * Find the line under this node just before the starting line.     */    prevPtr = linePtr->parentPtr->children.linePtr;	/* First line at leaf */    while (prevPtr != linePtr) {	if (prevPtr->nextPtr == linePtr) {	    return prevPtr;	}	prevPtr = prevPtr->nextPtr;	if (prevPtr == (TkTextLine *) NULL) {	    panic("TkBTreePreviousLine ran out of lines");	}    }    /*     * This was the first line associated with the particular parent node.     * Search up the tree for the previous node, then search down from that     * node to find its last line.     */    for (nodePtr = linePtr->parentPtr; ; nodePtr = nodePtr->parentPtr) {	if (nodePtr == (Node *) NULL || nodePtr->parentPtr == (Node *) NULL) {	    return (TkTextLine *) NULL;	}	if (nodePtr != nodePtr->parentPtr->children.nodePtr) {	    break;	}    }    for (node2Ptr = nodePtr->parentPtr->children.nodePtr; ; 	    node2Ptr = node2Ptr->children.nodePtr) {	while (node2Ptr->nextPtr != nodePtr) {	    node2Ptr = node2Ptr->nextPtr;	}	if (node2Ptr->level == 0) {	    break;	}	nodePtr = (Node *)NULL;    }    for (prevPtr = node2Ptr->children.linePtr ; ; prevPtr = prevPtr->nextPtr) {	if (prevPtr->nextPtr == (TkTextLine *) NULL) {	    return prevPtr;	}    }}/* *---------------------------------------------------------------------- * * TkBTreeLineIndex -- * *	Given a pointer to a line in a B-tree, return the numerical *	index of that line. * * Results: *	The result is the index of linePtr within the tree, where 0 *	corresponds to the first line in the tree. * * Side effects: *	None. * *---------------------------------------------------------------------- */intTkBTreeLineIndex(linePtr)    TkTextLine *linePtr;		/* Pointer to existing line in					 * B-tree. */{    register TkTextLine *linePtr2;    register Node *nodePtr, *parentPtr, *nodePtr2;    int index;    /*     * First count how many lines precede this one in its level-0     * node.     */    nodePtr = linePtr->parentPtr;    index = 0;    for (linePtr2 = nodePtr->children.linePtr; linePtr2 != linePtr;	    linePtr2 = linePtr2->nextPtr) {	if (linePtr2 == NULL) {	    panic("TkBTreeLineIndex couldn't find line");	}	index += 1;    }    /*     * Now work up through the levels of the tree one at a time,     * counting how many lines are in nodes preceding the current     * node.     */    for (parentPtr = nodePtr->parentPtr ; parentPtr != NULL;	    nodePtr = parentPtr, parentPtr = parentPtr->parentPtr) {	for (nodePtr2 = parentPtr->children.nodePtr; nodePtr2 != nodePtr;		nodePtr2 = nodePtr2->nextPtr) {	    if (nodePtr2 == NULL) {		panic("TkBTreeLineIndex couldn't find node");	    }	    index += nodePtr2->numLines;	}    }    return index;}/* *---------------------------------------------------------------------- * * TkBTreeLinkSegment -- * *	This procedure adds a new segment to a B-tree at a given *	location. * * Results: *	None. * * Side effects: *	SegPtr will be linked into its tree. * *---------------------------------------------------------------------- */	/* ARGSUSED */voidTkBTreeLinkSegment(segPtr, indexPtr)    TkTextSegment *segPtr;	/* Pointer to new segment to be added to				 * B-tree.  Should be completely initialized				 * by caller except for nextPtr field. */    TkTextIndex *indexPtr;	/* Where to add segment:  it gets linked				 * in just before the segment indicated				 * here. */{    register TkTextSegment *prevPtr;    prevPtr = SplitSeg(indexPtr);    if (prevPtr == NULL) {	segPtr->nextPtr = indexPtr->linePtr->segPtr;	indexPtr->linePtr->segPtr = segPtr;    } else {	segPtr->nextPtr = prevPtr->nextPtr;	prevPtr->nextPtr = segPtr;    }    CleanupLine(indexPtr->linePtr);    if (tkBTreeDebug) {	TkBTreeCheck(indexPtr->tree);    }}/* *---------------------------------------------------------------------- * * TkBTreeUnlinkSegment -- * *	This procedure unlinks a segment from its line in a B-tree. * * Results: *	None. * * Side effects: *	SegPtr will be unlinked from linePtr.  The segment itself *	isn't modified by this procedure. * *---------------------------------------------------------------------- */	/* ARGSUSED */voidTkBTreeUnlinkSegment(tree, segPtr, linePtr)    TkTextBTree tree;			/* Tree containing segment. */    TkTextSegment *segPtr;		/* Segment to be unlinked. */    TkTextLine *linePtr;		/* Line that currently contains					 * segment. */{    register TkTextSegment *prevPtr;    if (linePtr->segPtr == segPtr) {	linePtr->segPtr = segPtr->nextPtr;    } else {	for (prevPtr = linePtr->segPtr; prevPtr->nextPtr != segPtr;		prevPtr = prevPtr->nextPtr) {	    /* Empty loop body. */	}	prevPtr->nextPtr = segPtr->nextPtr;    }    CleanupLine(linePtr);}/* *---------------------------------------------------------------------- * * TkBTreeTag -- * *	Turn a given tag on or off for a given range of characters in *	a B-tree of text. * * Results: *	None. * * Side effects: *	The given tag is added to the given range of characters *	in the tree or removed from all those characters, depending *	on the "add" argument.  The structure of the btree is modified *	enough that index1Ptr and index2Ptr are no longer valid after *	this procedure returns, and the indexes may be modified by *	this procedure. * *---------------------------------------------------------------------- */voidTkBTreeTag(index1Ptr, index2Ptr, tagPtr, add)    register TkTextIndex *index1Ptr;	/* Indicates first character in					 * range. */    register TkTextIndex *index2Ptr;	/* Indicates character just after the					 * last one in range. */    TkTextTag *tagPtr;			/* Tag to add or remove. */    int add;				/* One means add tag to the given					 * range of characters;  zero means					 * remove the tag from the range. */{    TkTextSegment *segPtr, *prevPtr;    TkTextSearch search;    TkTextLine *cleanupLinePtr;    int oldState;    int changed;    /*     * See whether the tag is present at the start of the range.  If     * the state doesn't already match what we want then add a toggle     * there.     */    oldState = TkBTreeCharTagged(index1Ptr, tagPtr);    if ((add != 0) ^ oldState) {	segPtr = (TkTextSegment *) ckalloc(TSEG_SIZE);	segPtr->typePtr = (add) ? &tkTextToggleOnType : &tkTextToggleOffType;	prevPtr = SplitSeg(index1Ptr);	if (prevPtr == NULL) {	    segPtr->nextPtr = index1Ptr->linePtr->segPtr;	    index1Ptr->linePtr->segPtr = segPtr;	} else {	    segPtr->nextPtr = prevPtr->nextPtr;	    prevPtr->nextPtr = segPtr;	}	segPtr->size = 0;	segPtr->body.toggle.tagPtr = tagPtr;	segPtr->body.toggle.inNodeCounts = 0;    }    /*     * Scan the range of characters and delete any internal tag     * transitions.  Keep track of what the old state was at the end     * of the range, and add a toggle there if it's needed.     */    TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, &search);    cleanupLinePtr = index1Ptr->linePtr;    while (TkBTreeNextTag(&search)) {	oldState ^= 1;	segPtr = search.segPtr;	prevPtr = search.curIndex.linePtr->segPtr;	if (prevPtr == segPtr) {	    search.curIndex.linePtr->segPtr = segPtr->nextPtr;	} else {	    while (prevPtr->nextPtr != segPtr) {		prevPtr = prevPtr->nextPtr;	    }	    prevPtr->nextPtr = segPtr->nextPtr;	}	if (segPtr->body.toggle.inNodeCounts) {	    ChangeNodeToggleCount(search.curIndex.linePtr->parentPtr,		    segPtr->body.toggle.tagPtr, -1);	    segPtr->body.toggle.inNodeCounts = 0;	    changed = 1;	} else {	    changed = 0;	}	ckfree((char *) segPtr);	/*	 * The code below is a bit tricky.  After deleting a toggle	 * we eventually have to call CleanupLine, in order to allow	 * character segments to be merged together.  To do this, we	 * remember in cleanupLinePtr a line that needs to be	 * cleaned up, but we don't clean it up until we've moved	 * on to a different line.  That way the cleanup process	 * won't goof up segPtr.	 */	if (cleanupLinePtr != search.curIndex.linePtr) {	    CleanupLine(cleanupLinePtr);	    cleanupLinePtr = search.curIndex.linePtr;	}	/*	 * Quick hack.  ChangeNodeToggleCount may move the tag's root	 * location around and leave the search in the void.  This resets	 * the search.	 */	if (changed) {	    TkBTreeStartSearch(index1Ptr, index2Ptr, tagPtr, &search);	}    }    if ((add != 0) ^ oldState) {	segPtr = (TkTextSegment *) ckalloc(TSEG_SIZE);	segPtr->typePtr = (add) ? &tkTextToggleOffType : &tkTextToggleOnType;	prevPtr = SplitSeg(index2Ptr);	if (prevPtr == NULL) {	    segPtr->nextPtr = index2Ptr->linePtr->segPtr;	    index2Ptr->linePtr->segPtr = segPtr;	} else {	    segPtr->nextPtr = prevPtr->nextPtr;	    prevPtr->nextPtr = segPtr;	}	segPtr->size = 0;	segPtr->body.toggle.tagPtr = tagPtr;	segPtr->body.toggle.inNodeCounts = 0;    }    /*     * Cleanup cleanupLinePtr and the last line of the range, if     * these are different.     */    CleanupLine(cleanupLinePtr);    if (cleanupLinePtr != index2Ptr->linePtr) {	CleanupLine(index2Ptr->linePtr);    }    if (tkBTreeDebug) {	TkBTreeCheck(index1Ptr->tree);    }}/* *---------------------------------------------------------------------- * * ChangeNodeToggleCount -- * *	This procedure increments or decrements the toggle count for *	a particular tag in a particular node and all its ancestors *	up to the per-tag root node. * * Results: *	None. * * Side effects: *	The toggle count for tag is adjusted up or down by "delta" in *	nodePtr.  This routine maintains the tagRootPtr that identifies *	the root node for the tag, moving it up or down the tree as needed. * *---------------------------------------------------------------------- */static voidChangeNodeToggleCount(nodePtr, tagPtr, delta)    register Node *nodePtr;		/* Node whose toggle count for a tag					 * must be changed. */    TkTextTag *tagPtr;			/* Information about tag. */    int delta;				/* Amount to add to current toggle					 * count for tag (may be negative). */{    register Summary *summaryPtr, *prevPtr;    register Node *node2Ptr;    int rootLevel;			/* Level of original tag root */    tagPtr->toggleCount += delta;    if (tagPtr->tagRootPtr == (Node *) NULL) {	tagPtr->tagRootPtr = nodePtr;	return;    }    /*     * Note the level of the existing root for the tag so we can detect     * if it needs to be moved because of the toggle count change.     */    rootLevel = tagPtr->tagRootPtr->level;    /*     * Iterate over the node and its ancestors up to the tag root, adjusting     * summary counts at each node and moving the tag's root upwards if     * necessary.     */    for ( ; nodePtr != tagPtr->tagRootPtr; nodePtr = nodePtr->parentPtr) {	/*	 * See if there's already an entry for this tag for this node.  If so,	 * perhaps all we have to do is adjust its count.	 */    	for (prevPtr = NULL, summaryPtr = nodePtr->summaryPtr;		summaryPtr != NULL;		prevPtr = summaryPtr, summaryPtr = summaryPtr->nextPtr) {	    if (summaryPtr->tagPtr == tagPtr) {		break;	    }	}	if (summaryPtr != NULL) {	    summaryPtr->toggleCount += delta;	    if (summaryPtr->toggleCount > 0 &&		    summaryPtr->toggleCount < tagPtr->toggleCount) {		continue;	    }	    if (summaryPtr->toggleCount != 0) {		/*		 * Should never find a node with max toggle count at this		 * point (there shouldn't have been a summary entry in the		 * first place).		 */		panic("ChangeNodeToggleCount: bad toggle count (%d) max (%d)",		    summaryPtr->toggleCount, tagPtr->toggleCount);	    }    	    /*	     * Zero toggle count;  must remove this tag from the list.	     */	    if (prevPtr == NULL) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -