Fix the cycle detection in iterate() and rename push() to append()
Some checks failed
libakstdlib CI Build / cmake_build (push) Failing after 2m40s
Some checks failed
libakstdlib CI Build / cmake_build (push) Failing after 2m40s
This commit is contained in:
@@ -1,33 +1,74 @@
|
||||
#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)
|
||||
{
|
||||
PREPARE_ERROR(e);
|
||||
int count;
|
||||
FAIL_ZERO_RETURN(e, node, AKERR_NULLPOINTER, "node");
|
||||
FAIL_ZERO_RETURN(e, node->data, AKERR_NULLPOINTER, "node->data");
|
||||
// This function doesn't use *data so we don't check it
|
||||
|
||||
PASS(e, aksl_fprintf(&count, stderr, "Visiting node : %s", node->data));
|
||||
SUCCEED_RETURN(e);
|
||||
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;
|
||||
aksl_ListNode mylist;
|
||||
char *node1str = "Node 1";
|
||||
aksl_ListNode node1;
|
||||
char *node2str = "Node 2";
|
||||
aksl_ListNode node2;
|
||||
|
||||
node1->data = (void *)&node1str;
|
||||
PASS(e, aksl_list_push(&mylist, &node1));
|
||||
ATTEMPT {
|
||||
memset((void *)&mylist, 0x00, sizeof(aksl_ListNode));
|
||||
memset((void *)&node1, 0x00, sizeof(aksl_ListNode));
|
||||
memset((void *)&node2, 0x00, sizeof(aksl_ListNode));
|
||||
|
||||
node2->data = (void *)&node2str;
|
||||
PASS(e, aksl_list_push(&mylist, &node2));
|
||||
|
||||
PASS(e, aksl_list_iterate(&mylist, &myiter, NULL));
|
||||
|
||||
SUCCEED_RETURN(e);
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user