Fix the cycle detection in iterate() and rename push() to append()
Some checks failed
libakstdlib CI Build / cmake_build (push) Failing after 2m40s

This commit is contained in:
2026-06-27 12:11:27 -04:00
parent 3e3ea41dc8
commit 57929be1af
5 changed files with 100 additions and 39 deletions

View File

@@ -191,7 +191,7 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_strhash_djb2(char *str, size_t len, uint
SUCCEED_RETURN(e);
}
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)
{
PREPARE_ERROR(e);
FAIL_ZERO_RETURN(e, list, AKERR_NULLPOINTER, "list");
@@ -199,19 +199,20 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_list_push(aksl_ListNode *list, aksl_List
aksl_ListNode *slow = list;
aksl_ListNode *fast = list;
aksl_ListNode *tail = list;
do {
if ( fast != NULL && fast->next != NULL ) {
fast = fast->next->next;
}
while ( fast != NULL && fast->next != NULL ) {
tail = slow;
slow = slow->next;
if ( fast != NULL && fast == slow) {
FAIL(e, AKERR_CIRCULAR_REFERENCE, "%p", list);
fast = fast->next->next;
if ( fast == slow) {
FAIL_RETURN(e, AKERR_CIRCULAR_REFERENCE, "%p", list);
}
} while ( slow != NULL || (fast != NULL && fast->next != NULL) );
}
if ( fast != NULL ) {
tail = fast;
}
tail->next = obj;
obj->next = NULL;
obj->prev = slow;
obj->prev = tail;
SUCCEED_RETURN(e);
}
@@ -320,16 +321,23 @@ akerr_ErrorContext AKERR_NOIGNORE *aksl_list_iterate(aksl_ListNode *list, aksl_L
FAIL_ZERO_RETURN(e, iter, AKERR_NULLPOINTER, "iter");
aksl_ListNode *slow = list;
aksl_ListNode *fast = list;
aksl_ListNode *tail = list;
do {
if ( fast != NULL && fast->next != NULL ) {
fast = fast->next->next;
}
PASS(e, iter(slow, data));
while ( fast != NULL && fast->next != NULL ) {
slow = slow->next;
if ( fast != NULL && fast == slow) {
FAIL(e, AKERR_CIRCULAR_REFERENCE, "%p", list);
fast = fast->next->next;
if ( fast == slow) {
FAIL_RETURN(e, AKERR_CIRCULAR_REFERENCE, "%p", list);
}
} while ( slow != NULL || (fast != NULL && fast->next != NULL) );
}
while ( slow != NULL ) {
ATTEMPT {
CATCH(e, iter(slow, data));
slow = slow->next;
} 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);
}