Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <bastien@blender.org>2021-11-19 18:10:28 +0300
committerBastien Montagne <bastien@blender.org>2021-11-19 18:10:28 +0300
commitec71054a9b7bf0d2218fa230855fc9af2e71bcc2 (patch)
tree742c6c9c97b95936f7d6b9897f9ce350dbdabb8c /source/blender/blenlib
parent330290d2a80d6b78f323cd1df9f3ea333d1cdb53 (diff)
parent33c5e7bcd5e5b790ee95caaa0c4d917996341266 (diff)
Merge branch 'blender-v3.0-release'
Conflicts: source/blender/blenkernel/BKE_blender_version.h source/blender/blenloader/intern/versioning_300.c
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_listbase.h4
-rw-r--r--source/blender/blenlib/intern/listbase.c31
-rw-r--r--source/blender/blenlib/tests/BLI_listbase_test.cc58
3 files changed, 93 insertions, 0 deletions
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 345d9d93d03..cf525d1c2af 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -55,6 +55,10 @@ void *BLI_listbase_bytes_find(const ListBase *listbase,
const void *bytes,
const size_t bytes_size,
const int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2);
+void *BLI_listbase_string_or_index_find(const struct ListBase *listbase,
+ const char *string,
+ const size_t string_offset,
+ const int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
/* find backwards */
void *BLI_rfindlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index 1b16f6b0aee..443bef42cc2 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -826,6 +826,37 @@ void *BLI_listbase_bytes_rfind(const ListBase *listbase,
}
/**
+ * Find the first item in the list that matches the given string, or the given index as fallback.
+ *
+ * \note The string is only used is non-NULL and non-empty.
+ *
+ * \return The found item, or NULL.
+ */
+void *BLI_listbase_string_or_index_find(const ListBase *listbase,
+ const char *string,
+ const size_t string_offset,
+ const int index)
+{
+ Link *link = NULL;
+ Link *link_at_index = NULL;
+
+ int index_iter;
+ for (link = listbase->first, index_iter = 0; link; link = link->next, index_iter++) {
+ if (string != NULL && string[0] != '\0') {
+ const char *string_iter = ((const char *)link) + string_offset;
+
+ if (string[0] == string_iter[0] && STREQ(string, string_iter)) {
+ return link;
+ }
+ }
+ if (index_iter == index) {
+ link_at_index = link;
+ }
+ }
+ return link_at_index;
+}
+
+/**
* Returns the 0-based index of the first element of listbase which contains the specified
* null-terminated string at the specified offset, or -1 if not found.
*/
diff --git a/source/blender/blenlib/tests/BLI_listbase_test.cc b/source/blender/blenlib/tests/BLI_listbase_test.cc
index 0ba08a0cd48..d66eb214902 100644
--- a/source/blender/blenlib/tests/BLI_listbase_test.cc
+++ b/source/blender/blenlib/tests/BLI_listbase_test.cc
@@ -96,6 +96,64 @@ TEST(listbase, FindLinkOrIndex)
BLI_freelistN(&lb);
}
+TEST(listbase, FindLinkFromStringOrPointer)
+{
+ struct TestLink {
+ struct TestLink *prev, *next;
+ char name[64];
+ const void *ptr;
+ };
+
+ const char *const link1_name = "Link1";
+ const char *const link2_name = "Link2";
+ const void *const link1_ptr = nullptr;
+ const void *const link2_ptr = link2_name;
+
+ const size_t name_offset = offsetof(struct TestLink, name);
+ const size_t ptr_offset = offsetof(struct TestLink, ptr);
+
+ ListBase lb;
+ struct TestLink *link1 = (struct TestLink *)MEM_callocN(sizeof(TestLink), "link1");
+ BLI_strncpy(link1->name, link1_name, sizeof(link1->name));
+ link1->ptr = link1_ptr;
+ struct TestLink *link2 = (struct TestLink *)MEM_callocN(sizeof(TestLink), "link2");
+ BLI_strncpy(link2->name, link2_name, sizeof(link2->name));
+ link2->ptr = link2_ptr;
+
+ /* Empty list */
+ BLI_listbase_clear(&lb);
+ EXPECT_EQ(BLI_findptr(&lb, link1_ptr, ptr_offset), (void *)nullptr);
+ EXPECT_EQ(BLI_findstring(&lb, link1_name, name_offset), (void *)nullptr);
+ EXPECT_EQ(BLI_rfindptr(&lb, link1_ptr, ptr_offset), (void *)nullptr);
+ EXPECT_EQ(BLI_rfindstring(&lb, link1_name, name_offset), (void *)nullptr);
+ EXPECT_EQ(BLI_listbase_string_or_index_find(&lb, link1_name, name_offset, 0), (void *)nullptr);
+
+ /* One link */
+ BLI_addtail(&lb, link1);
+ EXPECT_EQ(BLI_findptr(&lb, link1_ptr, ptr_offset), (void *)link1);
+ EXPECT_EQ(BLI_findstring(&lb, link1_name, name_offset), (void *)link1);
+ EXPECT_EQ(BLI_rfindptr(&lb, link1_ptr, ptr_offset), (void *)link1);
+ EXPECT_EQ(BLI_rfindstring(&lb, link1_name, name_offset), (void *)link1);
+ EXPECT_EQ(BLI_listbase_string_or_index_find(&lb, link1_name, name_offset, 0), (void *)link1);
+ EXPECT_EQ(BLI_listbase_string_or_index_find(&lb, "", name_offset, 0), (void *)link1);
+ EXPECT_EQ(BLI_listbase_string_or_index_find(&lb, nullptr, name_offset, 0), (void *)link1);
+ EXPECT_EQ(BLI_listbase_string_or_index_find(&lb, nullptr, name_offset, 1), (void *)nullptr);
+
+ /* Two links */
+ BLI_addtail(&lb, link2);
+ EXPECT_EQ(BLI_findptr(&lb, link1_ptr, ptr_offset), (void *)link1);
+ EXPECT_EQ(BLI_findstring(&lb, link1_name, name_offset), (void *)link1);
+ EXPECT_EQ(BLI_rfindptr(&lb, link1_ptr, ptr_offset), (void *)link1);
+ EXPECT_EQ(BLI_rfindstring(&lb, link1_name, name_offset), (void *)link1);
+ EXPECT_EQ(BLI_listbase_string_or_index_find(&lb, link1_name, name_offset, 0), (void *)link1);
+ EXPECT_EQ(BLI_listbase_string_or_index_find(&lb, link2_name, name_offset, 0), (void *)link2);
+ EXPECT_EQ(BLI_listbase_string_or_index_find(&lb, nullptr, name_offset, 0), (void *)link1);
+ EXPECT_EQ(BLI_listbase_string_or_index_find(&lb, nullptr, name_offset, 1), (void *)link2);
+ EXPECT_EQ(BLI_listbase_string_or_index_find(&lb, nullptr, name_offset, -1), (void *)nullptr);
+
+ BLI_freelistN(&lb);
+}
+
/* -------------------------------------------------------------------- */
/* Sort utilities & test */