From c4b92572bf00afedfdebb26cb6ca2d0e35e7d17f Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Sun, 17 Apr 2016 13:50:26 -0400 Subject: [PATCH] Implementing ex32 List copy, split, and join --- lcthw-remnants-2/liblcthw/src/lcthw/list.c | 67 ++++++++++++- lcthw-remnants-2/liblcthw/src/lcthw/list.h | 4 + .../liblcthw/tests/lcthw/list_tests.c | 93 +++++++++++++++++++ 3 files changed, 163 insertions(+), 1 deletion(-) diff --git a/lcthw-remnants-2/liblcthw/src/lcthw/list.c b/lcthw-remnants-2/liblcthw/src/lcthw/list.c index de8483e..2500261 100644 --- a/lcthw-remnants-2/liblcthw/src/lcthw/list.c +++ b/lcthw-remnants-2/liblcthw/src/lcthw/list.c @@ -129,7 +129,7 @@ void *List_remove(List *list, ListNode *node) list->first->prev = NULL; } else if(node == list->last) { list->last = node->prev; - check(list->last != NULL, "INvalid list, somehow got a next that is NULL."); + check(list->last != NULL, "Invalid list, somehow got a next that is NULL."); list->last->next = NULL; } else { ListNode *after = node->next; @@ -145,3 +145,68 @@ void *List_remove(List *list, ListNode *node) error: return result; } + + +List *List_copy(List *list) +{ + List_validate(list); + + List *out = List_create(); + LIST_FOREACH(list, first, next, cur) { + List_push(out, cur->value); + } + + return out; +} + + +int List_split(List *list, void *split, List *a, List *b) +{ + List_validate(list); + + check(list->first && list->last, "List is empty."); + check(split, "split can't be NULL"); + + if(split == list->last->value || (split == list->first->value && split == list->last->value)) { + (*a) = *List_copy(list); + return 0; + } else if(split == list->first->value) { + (*b) = *List_copy(list); + List_push(a, List_shift(b)); + return 0; + } else { + int past_split = 0; + LIST_FOREACH(list, first, next, cur) { + if(past_split) { + List_push(b, cur->value); + continue; + } + + if(cur->value == split) { + past_split = 1; + } + + List_push(a, cur->value); + } + } + + return 0; + +error: + return -1; +} + + +void List_join(List *list, List *b) +{ + List_validate(list); + List_validate(b); + + List *tail = List_copy(b); + + list->last->next = tail->first; + list->count += tail->count; + free(tail); + + return; +} diff --git a/lcthw-remnants-2/liblcthw/src/lcthw/list.h b/lcthw-remnants-2/liblcthw/src/lcthw/list.h index c7de1ab..1e13a05 100644 --- a/lcthw-remnants-2/liblcthw/src/lcthw/list.h +++ b/lcthw-remnants-2/liblcthw/src/lcthw/list.h @@ -35,6 +35,10 @@ void *List_shift(List *list); void *List_remove(List *list, ListNode *node); +List *List_copy(List *list); +int List_split(List *list, void *split, List *a, List *b); +void List_join(List *list, List *b); + #define List_validate(A) (assert(A != NULL && List_count(A) > -1 &&\ (List_count(A) > 0 && List_first(A) != NULL) && "invalid *List")) diff --git a/lcthw-remnants-2/liblcthw/tests/lcthw/list_tests.c b/lcthw-remnants-2/liblcthw/tests/lcthw/list_tests.c index 6a4a10c..29e9337 100644 --- a/lcthw-remnants-2/liblcthw/tests/lcthw/list_tests.c +++ b/lcthw-remnants-2/liblcthw/tests/lcthw/list_tests.c @@ -6,6 +6,7 @@ static List *list = NULL; char *test1 = "test1 data"; char *test2 = "test2 data"; char *test3 = "test3 data"; +char *test4 = "test4 data"; char *test_create() @@ -95,6 +96,95 @@ char *test_shift() } +char *test_copy() +{ + list = List_create(); + + mu_assert(List_count(list) == 0, "Wrong count before copy."); + List_push(list, test1); + List_push(list, test2); + List_push(list, test3); + List_push(list, test4); + + mu_assert(List_count(list) == 4, "Wrong count after push."); + + List *copy = List_copy(list); + mu_assert(copy != list, "Copy and list have same address."); + mu_assert(List_count(copy) == 4, "Copy has wrong count."); + + return NULL; +} + + +char *test_split() +{ + mu_assert(List_count(list) == 4, "Wrong count before split."); + + List *a = List_create(); + List *b = List_create(); + List *tmp = List_copy(list); + + int rc = -1; + rc = List_split(tmp, test2, a, b); + mu_assert(rc == 0, "Failed to split."); + mu_assert(List_count(a) == 2, "List 'a' has wrong count."); + mu_assert(List_count(b) == 2, "List 'b' has wrong count."); + + List_destroy(a); + List_destroy(b); + + a = List_create(); + b = List_create(); + tmp = List_copy(list); + + rc = List_split(tmp, test1, a, b); + mu_assert(rc == 0, "Failed to split."); + mu_assert(List_count(a) == 1, "List 'a' has wrong count."); + mu_assert(List_count(b) == 3, "List 'b' has wrong count."); + + List_destroy(a); + List_destroy(b); + + a = List_create(); + b = List_create(); + tmp = List_copy(list); + + rc = List_split(tmp, test3, a, b); + mu_assert(rc == 0, "Failed to split."); + mu_assert(List_count(a) == 3, "List 'a' has wrong count."); + mu_assert(List_count(b) == 1, "List 'b' has wrong count."); + + List_destroy(a); + List_destroy(b); + + a = List_create(); + b = List_create(); + tmp = List_copy(list); + + rc = List_split(tmp, test4, a, b); + mu_assert(rc == 0, "Failed to split."); + mu_assert(List_count(a) == 4, "List 'a' has wrong count."); + mu_assert(List_count(b) == 0, "List 'b' has wrong count."); + + return NULL; +} + + +char *test_join() +{ + mu_assert(List_count(list) == 4, "Wrong count before join."); + + List *b = List_create(); + List_push(b, test4); + mu_assert(List_count(b) == 1, "List 'b' has wrong count."); + + List_join(list, b); + mu_assert(List_count(list) == 5, "Wrong count after join."); + + return NULL; +} + + char *all_tests() { mu_suite_start(); @@ -105,6 +195,9 @@ char *all_tests() { mu_run_test(test_remove); mu_run_test(test_shift); mu_run_test(test_destroy); + mu_run_test(test_copy); + mu_run_test(test_split); + mu_run_test(test_join); return NULL; }