Add tree search test
Some checks failed
libakstdlib CI Build / cmake_build (push) Failing after 2m41s

This commit is contained in:
2026-06-27 13:13:17 -04:00
parent 57929be1af
commit 5793f6a178
5 changed files with 141 additions and 33 deletions

View File

@@ -79,5 +79,9 @@ add_executable(test_linkedlist tests/test_linkedlist.c)
target_link_libraries(test_linkedlist PRIVATE akstdlib)
add_test(NAME linkedlist COMMAND test_linkedlist)
add_executable(test_tree tests/test_tree.c)
target_link_libraries(test_tree PRIVATE akstdlib)
add_test(NAME tree COMMAND test_tree)
# pkgconfig

View File

@@ -57,7 +57,7 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_realpath(const char *restrict path, char
akerr_ErrorContext AKERR_NOIGNORE *aksl_strhash_djb2(char *str, size_t len, uint32_t *hashval);
// Linked list functions
akerr_ErrorContext AKERR_NOIGNORE *aksl_list_push(aksl_ListNode *list, aksl_ListNode *obj);
akerr_ErrorContext AKERR_NOIGNORE *aksl_list_append(aksl_ListNode *list, aksl_ListNode *obj);
akerr_ErrorContext AKERR_NOIGNORE *aksl_list_pop(aksl_ListNode *node);
akerr_ErrorContext AKERR_NOIGNORE *aksl_list_iterate(aksl_ListNode *list, aksl_ListNodeIterator iter, void *data);

View File

@@ -266,9 +266,10 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_tree_iterate(
if ( lfree == NULL ) {
lfree = &aksl_free;
}
ATTEMPT {
switch ( searchmode ) {
case AKSL_TREE_SEARCH_DFS_PREORDER:
PASS(e, iter(root, data));
CATCH(e, iter(root, data));
if ( root->left != NULL ) {
PASS(e, aksl_tree_iterate(root->left, iter, lalloc, lfree, searchmode, data, NULL));
}
@@ -283,13 +284,13 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_tree_iterate(
if ( root-> right != NULL ) {
PASS(e, aksl_tree_iterate(root->right, iter, lalloc, lfree, searchmode, data, NULL));
}
PASS(e, iter(root, data));
CATCH(e, iter(root, data));
break;
case AKSL_TREE_SEARCH_DFS_INORDER:
if ( root->left != NULL ) {
PASS(e, aksl_tree_iterate(root->left, iter, lalloc, lfree, searchmode, data, NULL));
}
PASS(e, iter(root, data));
CATCH(e, iter(root, data));
if ( root-> right != NULL ) {
PASS(e, aksl_tree_iterate(root->right, iter, lalloc, lfree, searchmode, data, NULL));
}
@@ -299,6 +300,12 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_tree_iterate(
FAIL_RETURN(e, AKERR_NOT_IMPLEMENTED, "Searchmode %d", searchmode);
break;
}
} CLEANUP {
} PROCESS(e) {
} HANDLE(e, AKERR_ITERATOR_BREAK) {
// This is not an error condition, it's just telling us to stop early
SUCCEED_RETURN(e);
} FINISH(e, true);
SUCCEED_RETURN(e);
}

View File

@@ -35,6 +35,7 @@ int main(void)
{
PREPARE_ERROR(e);
int idx = 0;
int count = 0;
aksl_ListNode mylist;
aksl_ListNode node1;
aksl_ListNode node2;

96
tests/test_tree.c Normal file
View File

@@ -0,0 +1,96 @@
#include <stdio.h>
#include <akstdlib.h>
#define MAX_LEAVES 7
typedef struct TreeSearchParams
{
void *value;
int steps;
aksl_TreeNode *node;
} TreeSearchParams;
// This iterator does nothing but print the node names it is visiting
akerr_ErrorContext AKERR_NOIGNORE *myiter(aksl_TreeNode *node, void *data)
{
int count = 0;
TreeSearchParams *parms = NULL;
PREPARE_ERROR(e);
FAIL_ZERO_RETURN(e, node, AKERR_NULLPOINTER, "node");
FAIL_ZERO_RETURN(e, data, AKERR_NULLPOINTER, "data");
parms = (TreeSearchParams *)data;
parms->steps += 1;
if ( node->leaf == parms->value ) {
parms->node = node;
FAIL_RETURN(e, AKERR_ITERATOR_BREAK, "stop");
}
SUCCEED_RETURN(e);
}
int main(void)
{
PREPARE_ERROR(e);
aksl_TreeNode tree[MAX_LEAVES];
TreeSearchParams parms = {
.value = (void *)17336,
.steps = 0,
.node = NULL
};
ATTEMPT {
memset((void *)&tree, 0x00, sizeof(aksl_TreeNode) * MAX_LEAVES);
/*
* Here we build a 3 level tree
*
* LEFT RIGHT
* TREE[0]
* +--------^^---------+
* | |
* TREE[1] TREE[2]
* +---^^---+ +---^^---+
* | | | |
*TREE[3] TREE[4] TREE[5] TREE[6]
*/
tree[0].left = &tree[1];
tree[0].right = &tree[2];
tree[1].left = &tree[3];
tree[1].right = &tree[4];
tree[2].left = &tree[5];
tree[2].right = &tree[6];
// Hide a value in tree[6]
tree[6].leaf = (void *)17336;
// Search for the value 17336 using DFS_PREORDER
CATCH(e, aksl_tree_iterate(&tree[0], &myiter, NULL, NULL, AKSL_TREE_SEARCH_DFS_PREORDER, &parms, NULL));
if ( parms.node != &tree[6] ) {
FAIL_BREAK(e, AKERR_API, "DFS_PREORDER_SEARCH didn't find the node");
}
if ( parms.steps != 7 ) {
FAIL_BREAK(e, AKERR_API, "DFS_PREORDER_SEARCH should've found the node in 7 steps, instead took %d", parms.steps);
}
// Search for the value 17336 using DFS_INORDER
CATCH(e, aksl_tree_iterate(&tree[0], &myiter, NULL, NULL, AKSL_TREE_SEARCH_DFS_INORDER, &parms, NULL));
if ( parms.node != &tree[6] ) {
FAIL_BREAK(e, AKERR_API, "DFS_INORDER_SEARCH didn't find the node");
}
if ( parms.steps != 7 ) {
FAIL_BREAK(e, AKERR_API, "DFS_INORDER_SEARCH should've found the node in 7 steps, instead took %d", parms.steps);
}
// Search for the value 17336 using DFS_PREORDER
CATCH(e, aksl_tree_iterate(&tree[0], &myiter, NULL, NULL, AKSL_TREE_SEARCH_DFS_POSTORDER, &parms, NULL));
if ( parms.node != &tree[6] ) {
FAIL_BREAK(e, AKERR_API, "DFS_POSTORDER_SEARCH didn't find the node");
}
if ( parms.steps != 7 ) {
FAIL_BREAK(e, AKERR_API, "DFS_POSTORDER_SEARCH should've found the node in 7 steps, instead took %d", parms.steps);
}
} CLEANUP {
} PROCESS(e) {
} FINISH_NORETURN(e);
return 0;
}