mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-23 06:38:05 +01:00
WINGs: tree enhancements
- add WMFindInTreeWithDepthLimit, which is like WMFindInTree, but does not descend down more than a set limit. - add WMTreeWalk, which will walk a WMTreeNode, running a callback function on each node. Signed-off-by: Tamas TEVESZ <ice@extreme.hu>
This commit is contained in:
committed by
Carlos R. Mafra
parent
9a2732a4c3
commit
210bcec4de
@@ -117,6 +117,7 @@ typedef void WMInputProc(int fd, int mask, void *clientData);
|
|||||||
|
|
||||||
|
|
||||||
typedef int WMCompareDataProc(const void *item1, const void *item2);
|
typedef int WMCompareDataProc(const void *item1, const void *item2);
|
||||||
|
typedef void WMTreeWalkProc(WMTreeNode *aNode, void *data);
|
||||||
|
|
||||||
typedef void WMFreeDataProc(void *data);
|
typedef void WMFreeDataProc(void *data);
|
||||||
|
|
||||||
@@ -642,9 +643,16 @@ void WMSortTree(WMTreeNode *aNode, WMCompareDataProc *comparer);
|
|||||||
/* Returns the first node which matches node's data with cdata by 'match' */
|
/* Returns the first node which matches node's data with cdata by 'match' */
|
||||||
WMTreeNode* WMFindInTree(WMTreeNode *aTree, WMMatchDataProc *match, void *cdata);
|
WMTreeNode* WMFindInTree(WMTreeNode *aTree, WMMatchDataProc *match, void *cdata);
|
||||||
|
|
||||||
|
/* Returns the first node where node's data matches cdata by 'match' and node is
|
||||||
|
* at most `limit' depths down from `aTree'. */
|
||||||
|
WMTreeNode *WMFindInTreeWithDepthLimit(WMTreeNode * aTree, WMMatchDataProc * match, void *cdata, int limit);
|
||||||
|
|
||||||
/* Returns first tree node that has data == cdata */
|
/* Returns first tree node that has data == cdata */
|
||||||
#define WMGetFirstInTree(aTree, cdata) WMFindInTree(aTree, NULL, cdata)
|
#define WMGetFirstInTree(aTree, cdata) WMFindInTree(aTree, NULL, cdata)
|
||||||
|
|
||||||
|
/* Walk every node of aNode with `walk' */
|
||||||
|
void WMTreeWalk(WMTreeNode *aNode, WMTreeWalkProc * walk, void *data, Bool DepthFirst);
|
||||||
|
|
||||||
/* ---[ WINGs/data.c ]---------------------------------------------------- */
|
/* ---[ WINGs/data.c ]---------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
54
WINGs/tree.c
54
WINGs/tree.c
@@ -196,27 +196,22 @@ void WMSortTree(WMTreeNode * aNode, WMCompareDataProc * comparer)
|
|||||||
sortLeavesForNode(aNode, comparer);
|
sortLeavesForNode(aNode, comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WMTreeNode *findNodeInTree(WMTreeNode * aNode, WMMatchDataProc * match, void *cdata)
|
static WMTreeNode *findNodeInTree(WMTreeNode * aNode, WMMatchDataProc * match, void *cdata, int limit)
|
||||||
{
|
{
|
||||||
if (match == NULL) {
|
if (match == NULL && aNode->data == cdata)
|
||||||
if (aNode->data == cdata) {
|
return aNode;
|
||||||
return aNode;
|
else if ((*match) (aNode->data, cdata))
|
||||||
}
|
return aNode;
|
||||||
} else {
|
|
||||||
if ((*match) (aNode->data, cdata)) {
|
|
||||||
return aNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aNode->leaves) {
|
if (aNode->leaves && limit != 0) {
|
||||||
WMTreeNode *leaf;
|
WMTreeNode *leaf;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < WMGetArrayItemCount(aNode->leaves); i++) {
|
for (i = 0; i < WMGetArrayItemCount(aNode->leaves); i++) {
|
||||||
leaf = findNodeInTree(WMGetFromArray(aNode->leaves, i), match, cdata);
|
leaf = findNodeInTree(WMGetFromArray(aNode->leaves, i),
|
||||||
if (leaf) {
|
match, cdata, limit > 0 ? limit - 1 : limit);
|
||||||
|
if (leaf)
|
||||||
return leaf;
|
return leaf;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,5 +222,34 @@ WMTreeNode *WMFindInTree(WMTreeNode * aTree, WMMatchDataProc * match, void *cdat
|
|||||||
{
|
{
|
||||||
wassertrv(aTree != NULL, NULL);
|
wassertrv(aTree != NULL, NULL);
|
||||||
|
|
||||||
return findNodeInTree(aTree, match, cdata);
|
return findNodeInTree(aTree, match, cdata, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
WMTreeNode *WMFindInTreeWithDepthLimit(WMTreeNode * aTree, WMMatchDataProc * match, void *cdata, int limit)
|
||||||
|
{
|
||||||
|
wassertrv(aTree != NULL, NULL);
|
||||||
|
wassertrv(limit >= 0, NULL);
|
||||||
|
|
||||||
|
return findNodeInTree(aTree, match, cdata, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WMTreeWalk(WMTreeNode * aNode, WMTreeWalkProc * walk, void *data, Bool DepthFirst)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
WMTreeNode *leaf;
|
||||||
|
|
||||||
|
wassertr(aNode != NULL);
|
||||||
|
|
||||||
|
if (DepthFirst)
|
||||||
|
(*walk)(aNode, data);
|
||||||
|
|
||||||
|
if (aNode->leaves) {
|
||||||
|
for (i = 0; i < WMGetArrayItemCount(aNode->leaves); i++) {
|
||||||
|
leaf = (WMTreeNode *)WMGetFromArray(aNode->leaves, i);
|
||||||
|
WMTreeWalk(leaf, walk, data, DepthFirst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DepthFirst)
|
||||||
|
(*walk)(aNode, data);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user