Compare commits
2 Commits
main
...
55c3e451a6
| Author | SHA1 | Date | |
|---|---|---|---|
|
55c3e451a6
|
|||
|
22414addd3
|
@@ -1,28 +0,0 @@
|
|||||||
name: libakstdlib CI Build
|
|
||||||
run-name: ${{ gitea.actor }} libakstdlib test
|
|
||||||
on: [push]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
cmake_build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- run: echo "Triggered by ${{ gitea.event_name }} from ${{ gitea.repository }}@${{ gitea.ref }}. Building on ${{ runner.os }}."
|
|
||||||
- name: Check out repository code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: dependencies
|
|
||||||
run: |
|
|
||||||
sudo apt-get update -y
|
|
||||||
sudo apt-get install -y cmake gcc moreutils
|
|
||||||
# Depends on libakerror@main
|
|
||||||
git clone https://source.starfort.tech/andrew/libakerror.git
|
|
||||||
cd libakerror
|
|
||||||
cmake -S . -B build
|
|
||||||
cmake --build build
|
|
||||||
cmake --install build
|
|
||||||
- name: build and test
|
|
||||||
run: |
|
|
||||||
cmake -S . -B build
|
|
||||||
cmake --build build
|
|
||||||
sudo cmake --install build
|
|
||||||
cmake --build build --target test
|
|
||||||
- run: echo "🍏 This job's status is ${{ job.status }}."
|
|
||||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +0,0 @@
|
|||||||
[submodule "deps/libakerror"]
|
|
||||||
path = deps/libakerror
|
|
||||||
url = https://source.starfort.tech/andrew/libakerror.git
|
|
||||||
@@ -1,10 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(akstdlib LANGUAGES C)
|
project(akstdlib LANGUAGES C)
|
||||||
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -ggdb -pg")
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -g -ggdb -pg")
|
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -g -ggdb -pg")
|
|
||||||
|
|
||||||
if(TARGET akerror::akerror)
|
if(TARGET akerror::akerror)
|
||||||
message(STATUS "FOUND akerror::akerror")
|
message(STATUS "FOUND akerror::akerror")
|
||||||
else()
|
else()
|
||||||
@@ -15,14 +11,10 @@ include(CTest)
|
|||||||
include(GNUInstallDirs)
|
include(GNUInstallDirs)
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
|
||||||
add_subdirectory(deps/libakerror EXCLUDE_FROM_ALL)
|
|
||||||
else()
|
|
||||||
if(NOT TARGET akerror::akerror)
|
if(NOT TARGET akerror::akerror)
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
find_package(akerror REQUIRED)
|
find_package(akerror REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
|
||||||
|
|
||||||
set(akstdlib_install_cmakedir "${CMAKE_INSTALL_LIBDIR}/cmake/akstdlib")
|
set(akstdlib_install_cmakedir "${CMAKE_INSTALL_LIBDIR}/cmake/akstdlib")
|
||||||
set(prefix ${CMAKE_INSTALL_PREFIX})
|
set(prefix ${CMAKE_INSTALL_PREFIX})
|
||||||
@@ -75,13 +67,4 @@ install(FILES
|
|||||||
DESTINATION ${akstdlib_install_cmakedir}
|
DESTINATION ${akstdlib_install_cmakedir}
|
||||||
)
|
)
|
||||||
|
|
||||||
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
|
# pkgconfig
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
# README
|
|
||||||
|
|
||||||

|
|
||||||
1
deps/libakerror
vendored
1
deps/libakerror
vendored
Submodule deps/libakerror deleted from 4fad0cec59
@@ -43,6 +43,7 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_memset(void *s, int c, size_t n);
|
|||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_memcpy(void *d, void *s, size_t n);
|
akerr_ErrorContext AKERR_NOIGNORE *aksl_memcpy(void *d, void *s, size_t n);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_free(void *ptr);
|
akerr_ErrorContext AKERR_NOIGNORE *aksl_free(void *ptr);
|
||||||
|
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_printf(int *count, const char *restrict format, ...);
|
akerr_ErrorContext AKERR_NOIGNORE *aksl_printf(int *count, const char *restrict format, ...);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_fprintf(int *count, FILE *restrict stream, const char *restrict format, ...);
|
akerr_ErrorContext AKERR_NOIGNORE *aksl_fprintf(int *count, FILE *restrict stream, const char *restrict format, ...);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_sprintf(int *count, char *restrict str, const char *restrict format, ...);
|
akerr_ErrorContext AKERR_NOIGNORE *aksl_sprintf(int *count, char *restrict str, const char *restrict format, ...);
|
||||||
@@ -54,10 +55,8 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_atof(const char *nptr, double *dest);
|
|||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_realpath(const char *restrict path, char *restrict resolved_path);
|
akerr_ErrorContext AKERR_NOIGNORE *aksl_realpath(const char *restrict path, char *restrict resolved_path);
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_strhash_djb2(char *str, size_t len, uint32_t *hashval);
|
|
||||||
|
|
||||||
// Linked list functions
|
// Linked list functions
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_list_append(aksl_ListNode *list, aksl_ListNode *obj);
|
akerr_ErrorContext AKERR_NOIGNORE *aksl_list_push(aksl_ListNode *list, aksl_ListNode *obj);
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_list_pop(aksl_ListNode *node);
|
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);
|
akerr_ErrorContext AKERR_NOIGNORE *aksl_list_iterate(aksl_ListNode *list, aksl_ListNodeIterator iter, void *data);
|
||||||
|
|
||||||
|
|||||||
71
src/stdlib.c
71
src/stdlib.c
@@ -4,7 +4,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_malloc(size_t size, void **dst)
|
akerr_ErrorContext AKERR_NOIGNORE *aksl_malloc(size_t size, void **dst)
|
||||||
{
|
{
|
||||||
@@ -178,41 +177,25 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_realpath(const char *restrict path, char
|
|||||||
SUCCEED_RETURN(e);
|
SUCCEED_RETURN(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_strhash_djb2(char *str, size_t len, uint32_t *hashval)
|
akerr_ErrorContext AKERR_NOIGNORE *aksl_list_push(aksl_ListNode *list, aksl_ListNode *obj)
|
||||||
{
|
|
||||||
PREPARE_ERROR(e);
|
|
||||||
FAIL_ZERO_RETURN(e, str, AKERR_NULLPOINTER, "str");
|
|
||||||
FAIL_ZERO_RETURN(e, hashval, AKERR_NULLPOINTER, "hashval");
|
|
||||||
uint32_t h = 5381;
|
|
||||||
while (len--) {
|
|
||||||
h = ((h << 5) + h) + *str++;
|
|
||||||
}
|
|
||||||
*hashval = h;
|
|
||||||
SUCCEED_RETURN(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *aksl_list_append(aksl_ListNode *list, aksl_ListNode *obj)
|
|
||||||
{
|
{
|
||||||
PREPARE_ERROR(e);
|
PREPARE_ERROR(e);
|
||||||
FAIL_ZERO_RETURN(e, list, AKERR_NULLPOINTER, "list");
|
FAIL_ZERO_RETURN(e, list, AKERR_NULLPOINTER, "list");
|
||||||
FAIL_ZERO_RETURN(e, obj, AKERR_NULLPOINTER, "obj");
|
FAIL_ZERO_RETURN(e, obj, AKERR_NULLPOINTER, "obj");
|
||||||
aksl_ListNode *slow = list;
|
aksl_ListNode *slow = list;
|
||||||
aksl_ListNode *fast = list;
|
aksl_ListNode *fast = list;
|
||||||
aksl_ListNode *tail = list;
|
while ( slow->next != NULL || fast->next != NULL ) {
|
||||||
while ( fast != NULL && fast->next != NULL ) {
|
if ( fast->next != NULL ) {
|
||||||
tail = slow;
|
|
||||||
slow = slow->next;
|
|
||||||
fast = fast->next->next;
|
fast = fast->next->next;
|
||||||
|
}
|
||||||
|
slow = slow->next;
|
||||||
if ( fast == slow ) {
|
if ( fast == slow ) {
|
||||||
FAIL_RETURN(e, AKERR_CIRCULAR_REFERENCE, "%p", list);
|
FAIL(e, AKERR_CIRCULAR_REFERENCE, "%p", list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( fast != NULL ) {
|
slow->next = obj;
|
||||||
tail = fast;
|
|
||||||
}
|
|
||||||
tail->next = obj;
|
|
||||||
obj->next = NULL;
|
obj->next = NULL;
|
||||||
obj->prev = tail;
|
obj->prev = slow;
|
||||||
SUCCEED_RETURN(e);
|
SUCCEED_RETURN(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,12 +203,9 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_list_pop(aksl_ListNode *node)
|
|||||||
{
|
{
|
||||||
PREPARE_ERROR(e);
|
PREPARE_ERROR(e);
|
||||||
FAIL_ZERO_RETURN(e, node, AKERR_NULLPOINTER, "node");
|
FAIL_ZERO_RETURN(e, node, AKERR_NULLPOINTER, "node");
|
||||||
if ( node->prev != NULL ) {
|
FAIL_ZERO_RETURN(e, node->prev, AKERR_NULLPOINTER, "node->prev");
|
||||||
node->prev->next = node->next;
|
node->prev->next = node->next;
|
||||||
}
|
|
||||||
if ( node->next != NULL ) {
|
|
||||||
node->next->prev = node->prev;
|
node->next->prev = node->prev;
|
||||||
}
|
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
node->prev = NULL;
|
node->prev = NULL;
|
||||||
SUCCEED_RETURN(e);
|
SUCCEED_RETURN(e);
|
||||||
@@ -266,10 +246,9 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_tree_iterate(
|
|||||||
if ( lfree == NULL ) {
|
if ( lfree == NULL ) {
|
||||||
lfree = &aksl_free;
|
lfree = &aksl_free;
|
||||||
}
|
}
|
||||||
ATTEMPT {
|
|
||||||
switch ( searchmode ) {
|
switch ( searchmode ) {
|
||||||
case AKSL_TREE_SEARCH_DFS_PREORDER:
|
case AKSL_TREE_SEARCH_DFS_PREORDER:
|
||||||
CATCH(e, iter(root, data));
|
PASS(e, iter(root, data));
|
||||||
if ( root->left != NULL ) {
|
if ( root->left != NULL ) {
|
||||||
PASS(e, aksl_tree_iterate(root->left, iter, lalloc, lfree, searchmode, data, NULL));
|
PASS(e, aksl_tree_iterate(root->left, iter, lalloc, lfree, searchmode, data, NULL));
|
||||||
}
|
}
|
||||||
@@ -284,13 +263,13 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_tree_iterate(
|
|||||||
if ( root-> right != NULL ) {
|
if ( root-> right != NULL ) {
|
||||||
PASS(e, aksl_tree_iterate(root->right, iter, lalloc, lfree, searchmode, data, NULL));
|
PASS(e, aksl_tree_iterate(root->right, iter, lalloc, lfree, searchmode, data, NULL));
|
||||||
}
|
}
|
||||||
CATCH(e, iter(root, data));
|
PASS(e, iter(root, data));
|
||||||
break;
|
break;
|
||||||
case AKSL_TREE_SEARCH_DFS_INORDER:
|
case AKSL_TREE_SEARCH_DFS_INORDER:
|
||||||
if ( root->left != NULL ) {
|
if ( root->left != NULL ) {
|
||||||
PASS(e, aksl_tree_iterate(root->left, iter, lalloc, lfree, searchmode, data, NULL));
|
PASS(e, aksl_tree_iterate(root->left, iter, lalloc, lfree, searchmode, data, NULL));
|
||||||
}
|
}
|
||||||
CATCH(e, iter(root, data));
|
PASS(e, iter(root, data));
|
||||||
if ( root-> right != NULL ) {
|
if ( root-> right != NULL ) {
|
||||||
PASS(e, aksl_tree_iterate(root->right, iter, lalloc, lfree, searchmode, data, NULL));
|
PASS(e, aksl_tree_iterate(root->right, iter, lalloc, lfree, searchmode, data, NULL));
|
||||||
}
|
}
|
||||||
@@ -300,12 +279,6 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_tree_iterate(
|
|||||||
FAIL_RETURN(e, AKERR_NOT_IMPLEMENTED, "Searchmode %d", searchmode);
|
FAIL_RETURN(e, AKERR_NOT_IMPLEMENTED, "Searchmode %d", searchmode);
|
||||||
break;
|
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);
|
SUCCEED_RETURN(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,23 +301,15 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_list_iterate(aksl_ListNode *list, aksl_L
|
|||||||
FAIL_ZERO_RETURN(e, iter, AKERR_NULLPOINTER, "iter");
|
FAIL_ZERO_RETURN(e, iter, AKERR_NULLPOINTER, "iter");
|
||||||
aksl_ListNode *slow = list;
|
aksl_ListNode *slow = list;
|
||||||
aksl_ListNode *fast = list;
|
aksl_ListNode *fast = list;
|
||||||
while ( fast != NULL && fast->next != NULL ) {
|
while ( slow->next != NULL || fast->next != NULL ) {
|
||||||
slow = slow->next;
|
if ( fast->next != NULL ) {
|
||||||
fast = fast->next->next;
|
fast = fast->next->next;
|
||||||
if ( fast == slow) {
|
|
||||||
FAIL_RETURN(e, AKERR_CIRCULAR_REFERENCE, "%p", list);
|
|
||||||
}
|
}
|
||||||
}
|
PASS(e, iter(slow, data));
|
||||||
while ( slow != NULL ) {
|
|
||||||
ATTEMPT {
|
|
||||||
CATCH(e, iter(slow, data));
|
|
||||||
slow = slow->next;
|
slow = slow->next;
|
||||||
} CLEANUP {
|
if ( fast == slow && fast->next != NULL ) {
|
||||||
} PROCESS(e) {
|
FAIL(e, AKERR_CIRCULAR_REFERENCE, "%p", list);
|
||||||
} 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);
|
SUCCEED_RETURN(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <akstdlib.h>
|
|
||||||
|
|
||||||
|
|
||||||
// This iterator does nothing but print the node names it is visiting
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *myiter(aksl_ListNode *node, void *data)
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
PREPARE_ERROR(e);
|
|
||||||
FAIL_ZERO_RETURN(e, node, AKERR_NULLPOINTER, "node");
|
|
||||||
FAIL_ZERO_RETURN(e, node->data, AKERR_NULLPOINTER, "node->data");
|
|
||||||
PASS(e, aksl_fprintf(&count, stderr, "Visiting node : %s\n", node->data));
|
|
||||||
SUCCEED_RETURN(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This iterator function exits early once the index in `(int *)data` is reached
|
|
||||||
akerr_ErrorContext AKERR_NOIGNORE *myiter_earlyhalt(aksl_ListNode *node, void *data)
|
|
||||||
{
|
|
||||||
int *idx;
|
|
||||||
int count = 0;
|
|
||||||
PREPARE_ERROR(e);
|
|
||||||
FAIL_ZERO_RETURN(e, node, AKERR_NULLPOINTER, "node");
|
|
||||||
FAIL_ZERO_RETURN(e, node->data, AKERR_NULLPOINTER, "node->data");
|
|
||||||
FAIL_ZERO_RETURN(e, data, AKERR_NULLPOINTER, "data");
|
|
||||||
idx = (int *)data;
|
|
||||||
if ( *idx == 1 ) {
|
|
||||||
// This exception is eaten by the iterator, we will never see it
|
|
||||||
FAIL_RETURN(e, AKERR_ITERATOR_BREAK, "stop");
|
|
||||||
}
|
|
||||||
*idx += 1;
|
|
||||||
SUCCEED_RETURN(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
PREPARE_ERROR(e);
|
|
||||||
int idx = 0;
|
|
||||||
int count = 0;
|
|
||||||
aksl_ListNode mylist;
|
|
||||||
aksl_ListNode node1;
|
|
||||||
aksl_ListNode node2;
|
|
||||||
|
|
||||||
ATTEMPT {
|
|
||||||
memset((void *)&mylist, 0x00, sizeof(aksl_ListNode));
|
|
||||||
memset((void *)&node1, 0x00, sizeof(aksl_ListNode));
|
|
||||||
memset((void *)&node2, 0x00, sizeof(aksl_ListNode));
|
|
||||||
|
|
||||||
mylist.data = "Root";
|
|
||||||
|
|
||||||
node1.data = "Node 1";
|
|
||||||
CATCH(e, aksl_list_append(&mylist, &node1));
|
|
||||||
|
|
||||||
node2.data = "Node 2";
|
|
||||||
CATCH(e, aksl_list_append(&mylist, &node2));
|
|
||||||
|
|
||||||
// Iterate over all nodes in the list using the myiter() function
|
|
||||||
CATCH(e, aksl_list_iterate(&mylist, &myiter, NULL));
|
|
||||||
|
|
||||||
// Iterate over up to the first 2 nodes in the list and then exit early
|
|
||||||
idx = 0;
|
|
||||||
CATCH(e, aksl_list_iterate(&mylist, &myiter_earlyhalt, &idx));
|
|
||||||
CATCH(e, aksl_fprintf(&count, stderr, "Iterator exited early at index %d\n", idx));
|
|
||||||
|
|
||||||
// Break the list with a circular reference, and iterate it again
|
|
||||||
node2.next = &mylist;
|
|
||||||
CATCH(e, aksl_list_iterate(&mylist, &myiter, NULL));
|
|
||||||
|
|
||||||
} CLEANUP {
|
|
||||||
} PROCESS(e) {
|
|
||||||
} HANDLE(e, AKERR_CIRCULAR_REFERENCE) {
|
|
||||||
fprintf(stderr, "Circular reference error caught\n");
|
|
||||||
} FINISH_NORETURN(e);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
#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;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user