BLI: Add basic validation tool for ListBase.

Mainly a debug tool, makes it very easy to detect broken listbase.
This commit is contained in:
2023-05-12 18:46:15 +02:00
parent d9f5ce2546
commit d87d2dd4ba
2 changed files with 45 additions and 0 deletions

View File

@@ -285,6 +285,10 @@ BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
lb->first = lb->last = (void *)0;
}
/** Validate the integrity of a given ListBase, returns `true` if evrything is OK, false otherwise.
*/
bool BLI_listbase_validate(struct ListBase *lb);
/**
* Equality check for ListBase.
*

View File

@@ -871,6 +871,47 @@ void BLI_listbase_rotate_last(ListBase *lb, void *vlink)
((Link *)lb->last)->next = nullptr;
}
bool BLI_listbase_validate(ListBase *lb)
{
if (lb->first == nullptr && lb->last == nullptr) {
/* Empty list. */
return true;
}
if (ELEM(nullptr, lb->first, lb->last)) {
/* If one of the pointer is null, but not this other, this is a corrupted listbase. */
return false;
}
/* Walk the list in bot directions to ensure all next & prev pointers are valid and consistent.
*/
for (Link *lb_link = static_cast<Link *>(lb->first); lb_link; lb_link = lb_link->next) {
if (lb_link == lb->first) {
if (lb_link->prev != nullptr) {
return false;
}
}
if (lb_link == lb->last) {
if (lb_link->next != nullptr) {
return false;
}
}
}
for (Link *lb_link = static_cast<Link *>(lb->last); lb_link; lb_link = lb_link->prev) {
if (lb_link == lb->last) {
if (lb_link->next != nullptr) {
return false;
}
}
if (lb_link == lb->first) {
if (lb_link->prev != nullptr) {
return false;
}
}
}
return true;
}
LinkData *BLI_genericNodeN(void *data)
{
LinkData *ld;