diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ef91a7..e8ea1c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,5 +7,6 @@ set(CMAKE_C_STANDARD_REQUIRED TRUE) add_subdirectory(test_1_1) add_subdirectory(test_1_2) add_subdirectory(test_2_1) +add_subdirectory(test_2_2) add_subdirectory(test_final) add_subdirectory(test_final_1) diff --git a/test_2_2/CMakeLists.txt b/test_2_2/CMakeLists.txt new file mode 100644 index 0000000..f13ff82 --- /dev/null +++ b/test_2_2/CMakeLists.txt @@ -0,0 +1,5 @@ +project(test_2_2) + +set(testName "${PROJECT_NAME}") + +add_subdirectory(task_1) diff --git a/test_2_2/task_1/CMakeLists.txt b/test_2_2/task_1/CMakeLists.txt new file mode 100644 index 0000000..c27e918 --- /dev/null +++ b/test_2_2/task_1/CMakeLists.txt @@ -0,0 +1,6 @@ +project("${testName}_task_1") + +add_library(linkedList linkedList.c) + +add_executable(${PROJECT_NAME}_test test.c) +target_link_libraries(${PROJECT_NAME}_test linkedList ) diff --git a/test_2_2/task_1/linkedList.c b/test_2_2/task_1/linkedList.c new file mode 100644 index 0000000..569c0cd --- /dev/null +++ b/test_2_2/task_1/linkedList.c @@ -0,0 +1,74 @@ +#include "linkedList.h" + +#include +#include + +typedef struct LinkedList { + LinkedListNode *first; + LinkedListNode *last; +} LinkedList; + +typedef struct LinkedListNode { + int value; + LinkedListNode *next; +} LinkedListNode; + +bool createList(LinkedList **list) { + *list = calloc(1, sizeof(LinkedList)); + return *list != NULL; +} + +bool addToList(LinkedList *list, int value) { + LinkedListNode *node = calloc(1, sizeof(LinkedListNode)); + if (node == NULL) { + return false; + } + + node->value = value; + + if (list->first == NULL) { + list->first = node; + } else { + list->last->next = node; + } + list->last = node; + + return true; +} + +void removeAllOddNodes(LinkedList *list) { + LinkedListNode *node = list->first; + while (node != NULL) { + LinkedListNode *next = node->next; + if (node->next == NULL) { + return; + } + + LinkedListNode *nextNext = next->next; + free(next); + node->next = nextNext; + node = nextNext; + } +} + +LinkedListNode *getFirst(LinkedList *list) { + return list->first; +} + +LinkedListNode *getNext(LinkedListNode *node) { + return node->next; +} + +int getValue(LinkedListNode *node) { + return node->value; +} + +void disposeList(LinkedList *list) { + LinkedListNode *node = list->first; + while (node != NULL) { + LinkedListNode *next = node->next; + free(node); + node = next; + } + free(list); +} diff --git a/test_2_2/task_1/linkedList.h b/test_2_2/task_1/linkedList.h new file mode 100644 index 0000000..c2ef8cd --- /dev/null +++ b/test_2_2/task_1/linkedList.h @@ -0,0 +1,43 @@ +#pragma once + +#include + +/// @brief Linked list that stores int values +typedef struct LinkedList LinkedList; + +/// @brief Node of a linked list +typedef struct LinkedListNode LinkedListNode; + +/// @brief Creates new linked list +/// @param list Pointer to store new list to +/// @return `true` if created successfully, `false` otherwise (allocation failed) +bool createList(LinkedList **list); + +/// @brief Adds value to list +/// @param list List to add value to +/// @param value Value to add to list +/// @return `true` if added successfully, `false` otherwise (allocation failed) +bool addToList(LinkedList *list, int value); + +/// @brief Removes all nodes placed at odd indicies +/// @param list List to remove nodes from +void removeAllOddNodes(LinkedList *list); + +/// @brief Gets first node of a list +/// @param list List to get first node from +/// @return Fist node of specified list +LinkedListNode *getFirst(LinkedList *list); + +/// @brief Gets node following specified node +/// @param node Node to get next one from +/// @return Node following specified node +LinkedListNode *getNext(LinkedListNode *node); + +/// @brief Gets value of a node +/// @param node Node to get value from +/// @return Value of specified node +int getValue(LinkedListNode *node); + +/// @brief Disposes list +/// @param list List to dispose +void disposeList(LinkedList *list); diff --git a/test_2_2/task_1/test.c b/test_2_2/task_1/test.c new file mode 100644 index 0000000..1ead6c8 --- /dev/null +++ b/test_2_2/task_1/test.c @@ -0,0 +1,71 @@ +#define CTEST_MAIN +#define CTEST_SEGFAULT +#include "../../ctest/ctest.h" + +#include + +#include "linkedList.h" + +int main(int argc, const char *argv[]) { + return ctest_main(argc, argv); +} + +void assertList(LinkedList *list, int *array, int arraySize) { + ASSERT_NOT_NULL(list); + LinkedListNode *node = getFirst(list); + for (int i = 0; i < arraySize; ++i) { + ASSERT_NOT_NULL(node); + ASSERT_EQUAL(getValue(node), array[i]); + node = getNext(node); + } + ASSERT_NULL(node); +} + +void assertAddToList(LinkedList *list, int *array, int arraySize) { + for (int i = 0; i < arraySize; ++i) { + ASSERT_TRUE(addToList(list, array[i])); + } +} + +LinkedList *createNewList(void) { + LinkedList *list = NULL; + ASSERT_TRUE(createList(&list)); + return list; +} + +void assertOddRemoving(int *arrayA, int arrayASize, int *arrayB, int arrayBSize) { + LinkedList *list = createNewList(); + assertAddToList(list, arrayA, arrayASize); + removeAllOddNodes(list); + assertList(list, arrayB, arrayBSize); + disposeList(list); +} + +CTEST(linkedListTest, emptyListTest) { + assertOddRemoving(NULL, 0, NULL, 0); +} + +CTEST(linkedListTest, singleElementTest) { + int array[1] = { 42 }; + assertOddRemoving( + array, sizeof(array) / sizeof(int), + array, sizeof(array) / sizeof(int)); +} + +CTEST(linkedListTest, twoElementsTest) { + int arrayA[2] = { 42, 96 }; + int arrayB[1] = { 42 }; + + assertOddRemoving( + arrayA, sizeof(arrayA) / sizeof(int), + arrayB, sizeof(arrayB) / sizeof(int)); +} + +CTEST(linkedListTest, someElementsTest) { + int arrayA[9] = { 42, 96, -1122, 53, 623, 734, 23446, 76756456, 87354 }; + int arrayB[5] = { 42, -1122, 623, 23446, 87354 }; + + assertOddRemoving( + arrayA, sizeof(arrayA) / sizeof(int), + arrayB, sizeof(arrayB) / sizeof(int)); +}