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:
44
src/stdlib.c
44
src/stdlib.c
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user