summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2013-06-12 15:38:41 +0200
committerJérémy Zurcher <jeremy@asynk.ch>2013-06-12 15:38:41 +0200
commite2763b98b4ee2bf73d18ecdb100a051e68d5965c (patch)
treee71c49c6548e1201494e8aae34868dd27ce84a6b
parent579e58fb4ae15766a64181abd645ca1dd33015a6 (diff)
downloadefl-devs/jeyzu/eina-WIP.tar.gz
add EAPI eina_list_remove_duplicates(Eina_List *list, Eina_Bool keep_first)devs/jeyzu/eina-WIP
-rw-r--r--src/lib/eina/eina_list.c56
-rw-r--r--src/lib/eina/eina_list.h17
-rw-r--r--src/tests/eina/eina_test_list.c63
3 files changed, 136 insertions, 0 deletions
diff --git a/src/lib/eina/eina_list.c b/src/lib/eina/eina_list.c
index 5c8b1f8c41..fa3670b3f0 100644
--- a/src/lib/eina/eina_list.c
+++ b/src/lib/eina/eina_list.c
@@ -752,6 +752,62 @@ eina_list_remove_list(Eina_List *list, Eina_List *remove_list)
}
EAPI Eina_List *
+eina_list_remove_duplicates(Eina_List *list, Eina_Bool keep_first)
+{
+ Eina_List *itr1, *itr2, *itr3;
+
+ if (!list)
+ return NULL;
+
+ if (keep_first)
+ {
+ itr1 = list;
+ while (itr1)
+ {
+ itr2 = itr1->next;
+
+ while (itr2)
+ {
+ itr3 = itr2->next;
+
+ if (itr1->data == itr2->data)
+ {
+ list = eina_list_remove_list(list, itr2);
+ }
+
+ itr2 = itr3;
+ }
+
+ itr1 = itr1->next;
+ }
+ }
+ else
+ {
+ itr1 = list->accounting->last;
+ while (itr1)
+ {
+ itr2 = itr1->prev;
+
+ while (itr2)
+ {
+ itr3 = itr2->prev;
+
+ if (itr1->data == itr2->data)
+ {
+ list = eina_list_remove_list(list, itr2);
+ }
+
+ itr2 = itr3;
+ }
+
+ itr1 = itr1->prev;
+ }
+ }
+
+ return list;
+}
+
+EAPI Eina_List *
eina_list_free(Eina_List *list)
{
Eina_List *l, *free_l;
diff --git a/src/lib/eina/eina_list.h b/src/lib/eina/eina_list.h
index a3c17d32e0..4f7e0ff6b0 100644
--- a/src/lib/eina/eina_list.h
+++ b/src/lib/eina/eina_list.h
@@ -620,6 +620,23 @@ EAPI Eina_List *eina_list_remove_list(Eina_List *list, Eina_List *rem
/**
+ * @brief Remove duplicated list nodes.
+ *
+ * @param list The given linked list.
+ * @param keep_first Keep the first or last occurence
+ * @return A list pointer.
+ *
+ * This function removes multiple node occurences that have the same data.
+ * It keeps the first or last occurence depending of @p keep_first.
+ * If @p list is @c NULL, @c NULL is returned, otherwise a new list pointer
+ * that should be used in place of the one passed to this function.
+ *
+ * @warning @p list must be a pointer to the first element of the list.
+ */
+EAPI Eina_List *eina_list_remove_duplicates(Eina_List *list, Eina_Bool keep_first) EINA_WARN_UNUSED_RESULT;
+
+
+/**
* @brief Move the specified data to the head of the list.
*
* @param list The list handle to move the data.
diff --git a/src/tests/eina/eina_test_list.c b/src/tests/eina/eina_test_list.c
index 7d5bf1bd32..d884469158 100644
--- a/src/tests/eina/eina_test_list.c
+++ b/src/tests/eina/eina_test_list.c
@@ -435,6 +435,68 @@ START_TEST(eina_test_shuffle)
}
END_TEST
+START_TEST(eina_test_duplicates)
+{
+ unsigned int i;
+ unsigned int *p;
+ Eina_List *list = NULL;
+ Eina_List *item = NULL;
+ unsigned int data[] = { 0, 1, 2, 3, 4, 5, 6, 7};
+ unsigned int result1[] = { 0, 1, 2, 3, 4, 5, 6, 7};
+ unsigned int result2[] = { 2, 3, 4, 1, 5, 6, 7, 0};
+
+ eina_init();
+
+ list = eina_list_append(list, &data[0]);
+ list = eina_list_append(list, &data[1]);
+ list = eina_list_append(list, &data[1]);
+ list = eina_list_append(list, &data[2]);
+ list = eina_list_append(list, &data[3]);
+ list = eina_list_append(list, &data[4]);
+ list = eina_list_append(list, &data[1]);
+ list = eina_list_append(list, &data[5]);
+ list = eina_list_append(list, &data[6]);
+ list = eina_list_append(list, &data[7]);
+ list = eina_list_append(list, &data[0]);
+ list = eina_list_append(list, &data[0]);
+ fail_if(eina_list_count(list) != 12);
+
+ list = eina_list_remove_duplicates(list, EINA_TRUE);
+ fail_if( i != eina_list_count(list));
+ for (i = 0; i < 8; i++)
+ {
+ p = eina_list_nth(list,i);
+ fail_if(*p != result1[i]);
+ }
+ list = eina_list_free(list);
+
+ list = eina_list_append(list, &data[0]);
+ list = eina_list_append(list, &data[1]);
+ list = eina_list_append(list, &data[1]);
+ list = eina_list_append(list, &data[2]);
+ list = eina_list_append(list, &data[3]);
+ list = eina_list_append(list, &data[4]);
+ list = eina_list_append(list, &data[1]);
+ list = eina_list_append(list, &data[5]);
+ list = eina_list_append(list, &data[6]);
+ list = eina_list_append(list, &data[7]);
+ list = eina_list_append(list, &data[0]);
+ list = eina_list_append(list, &data[0]);
+ fail_if(eina_list_count(list) != 12);
+
+ list = eina_list_remove_duplicates(list, EINA_FALSE);
+ fail_if( i != eina_list_count(list));
+ for (i = 0; i < 8; i++)
+ {
+ p = eina_list_nth(list,i);
+ fail_if(*p != result2[i]);
+ }
+ list = eina_list_free(list);
+
+ eina_shutdown();
+}
+END_TEST
+
void
eina_test_list(TCase *tc)
{
@@ -443,4 +505,5 @@ eina_test_list(TCase *tc)
tcase_add_test(tc, eina_test_sorted_insert);
tcase_add_test(tc, eina_test_list_split);
tcase_add_test(tc, eina_test_shuffle);
+ tcase_add_test(tc, eina_test_duplicates);
}