diff --git a/include/linkedlist.h b/include/linkedlist.h index 9884c74..ff461f6 100644 --- a/include/linkedlist.h +++ b/include/linkedlist.h @@ -17,10 +17,10 @@ typedef enum { LinkedListErr linkedlist_create(LinkedList **out, size_t elem_size); LinkedListErr linkedlist_destroy(LinkedList *ll); -LinkedListErr linkedlist_append(LinkedList *ll, void *data); +LinkedListErr linkedlist_append(LinkedList *ll, void *val); LinkedListErr linkedlist_delete(LinkedList *ll, size_t index); LinkedListErr linkedlist_pop(LinkedList *ll, size_t index, void *out); -LinkedListErr linkedlist_insert(LinkedList *ll, size_t index, void *out); +LinkedListErr linkedlist_insert(LinkedList *ll, size_t index, void *val); LinkedListErr linkedlist_get(const LinkedList *ll, size_t index, void *out); LinkedListErr linkedlist_len(const LinkedList *ll, size_t *out); diff --git a/src/linkedlist.c b/src/linkedlist.c index 57e9556..8ca6901 100644 --- a/src/linkedlist.c +++ b/src/linkedlist.c @@ -98,12 +98,12 @@ LinkedListErr linkedlist_append(LinkedList *ll, void *data) { return LLIST_OK; } -LinkedListErr linkedlist_get(const LinkedList *ll, size_t index, void *out) { +LinkedListErr linkedlist_get(const LinkedList *ll, size_t index, void *val) { if (ll == NULL) { return LLIST_NULL; } - if (out == NULL) { + if (val == NULL) { return LLIST_NULL_ARG; } @@ -116,7 +116,7 @@ LinkedListErr linkedlist_get(const LinkedList *ll, size_t index, void *out) { current = current->next; } - memcpy(out, current->data, ll->elem_size); + memcpy(val, current->data, ll->elem_size); return LLIST_OK; } @@ -154,6 +154,46 @@ LinkedListErr linkedlist_delete(LinkedList *ll, size_t index) { return LLIST_OK; } +LinkedListErr linkedlist_insert(LinkedList *ll, size_t index, void *val) { + if (ll == NULL) { + return LLIST_NULL; + } + + if (index >= ll->len) { + return LLIST_OUT_OF_BOUNDS; + } + + Node *new_node = malloc(sizeof(Node)); + if (new_node == NULL) { + return LLIST_ALLOC; + } + + new_node->data = malloc(ll->elem_size); + if (new_node->data == NULL) { + free(new_node); + return LLIST_ALLOC; + } + + memcpy(new_node->data, val, ll->elem_size); + + Node *current = ll->head; + for (size_t i = 0; i < ll->len; i++) { + current = current->next; + } + + // is head + if (current == NULL) { + ll->head = new_node; + ll->head->next = NULL; + } else { // also works for the end althoug append should be used for that i guess + Node *next = current->next; + current->next = new_node; + new_node->next = next; + } + + return LLIST_OK; +} + LinkedListErr linkedlist_len(const LinkedList *ll, size_t *out) { if (ll == NULL) { return LLIST_NULL; diff --git a/tests/test_linkedlist.c b/tests/test_linkedlist.c index e7743e0..088ecd6 100644 --- a/tests/test_linkedlist.c +++ b/tests/test_linkedlist.c @@ -43,10 +43,60 @@ static void linkedlist_test_delete_head(void **state) { linkedlist_destroy(ll); } +static void linkedlist_test_delete_end(void **state) { + (void) state; + + LinkedList *ll; + linkedlist_create(&ll, sizeof(int)); + for (int i = 0; i < 3; i++) { + linkedlist_append(ll, &i); + } + + linkedlist_delete(ll, 2); + + size_t len; + linkedlist_len(ll, &len); + assert_int_equal(len, 2); + + for (int i = 0; i < 2; i++) { + int n; + linkedlist_get(ll, i, &n); + assert_int_equal(n, i); + } + linkedlist_destroy(ll); +} + +static void linkedlist_test_delete_middle(void **state) { + (void) state; + + LinkedList *ll; + linkedlist_create(&ll, sizeof(int)); + for (int i = 0; i < 3; i++) { + linkedlist_append(ll, &i); + } + + linkedlist_delete(ll, 1); + + size_t len; + linkedlist_len(ll, &len); + assert_int_equal(len, 2); + + int n1; + int n2; + linkedlist_get(ll, 0, &n1); + linkedlist_get(ll, 1, &n2); + assert_int_equal(n1, 0); + assert_int_equal(n2, 2); + + linkedlist_destroy(ll); +} + int main(void) { const struct CMUnitTest tests[] = { cmocka_unit_test(linkedlist_test_append_3_int), cmocka_unit_test(linkedlist_test_delete_head), + cmocka_unit_test(linkedlist_test_delete_end), + cmocka_unit_test(linkedlist_test_delete_middle), }; return cmocka_run_group_tests(tests, NULL, NULL);