From 7611096e13a2dba44eaae1cc077bf24601ff50da Mon Sep 17 00:00:00 2001 From: LaEntropiaa Date: Thu, 12 Feb 2026 10:47:46 -0600 Subject: [PATCH] First commit, fixed appending, create, destroy and get, all working fine --- .gitignore | 54 ++++++++++++++++++ CMakeLists.txt | 36 ++++++++++++ include/linkedlist.h | 26 +++++++++ src/linkedlist.c | 122 ++++++++++++++++++++++++++++++++++++++++ tests/CMakeLists.txt | 23 ++++++++ tests/test_linkedlist.c | 32 +++++++++++ 6 files changed, 293 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 include/linkedlist.h create mode 100644 src/linkedlist.c create mode 100644 tests/CMakeLists.txt create mode 100644 tests/test_linkedlist.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..157dd82 --- /dev/null +++ b/.gitignore @@ -0,0 +1,54 @@ +# Directories +build/ +build-*/ +cmake-build-*/ +.cache/ +out/ +out/Debug/ +out/Release/ + +# Cmake files +CMakeCache.txt +CMakeFiles/ +cmake_install.cmake +CTestTestfile.cmake +Testing/ +compile_commands.json +../compile_commands.json +build/compile_commands.json + +# Make / Ninja +Makefile +*.ninja +*.ninja_deps +*.ninja_log +rules.ninja + +# Object files +*.o +*.obj +*.lo +*.la + +# Binaries +*.out +*.exe +*.dll +*.so +*.so.* +*.dylib +*.a + +# Debug / Sanitizer +*.dSYM/ +*.gcno +*.gcda +*.gcov + +# Editors +.vscode/ +.idea/ +*.swp +*.swo +*~ + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..951448c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.16) +project(linkedlist VERSION 1.0 LANGUAGES C) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) + +# Export compile_commands.json (para clangd) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +# Warnings globales +add_compile_options( + -Wall + -Wextra + -Wpedantic +) + +# ------------------------ +# Library +# ------------------------ + +add_library(linkedlist + src/linkedlist.c +) + +target_include_directories(linkedlist + PUBLIC + ${PROJECT_SOURCE_DIR}/include +) + +# ------------------------ +# Testing +# ------------------------ + +enable_testing() +add_subdirectory(tests) + diff --git a/include/linkedlist.h b/include/linkedlist.h new file mode 100644 index 0000000..0f3df0a --- /dev/null +++ b/include/linkedlist.h @@ -0,0 +1,26 @@ +#ifndef LINKEDLIST_H +#define LINKEDLIST_H + +#include + +typedef struct LinkedList LinkedList; + +typedef enum { + LLIST_OK = 0, + LLIST_ALLOC, + LLIST_NULL, + LLIST_NULL_ARG, + LLIST_OUT_OF_BOUNDS, + LLIST_INVALID_SIZE, +} LinkedListErr; + +LinkedListErr linkedlist_create(LinkedList **out, size_t elem_size); +LinkedListErr linkedlist_destroy(LinkedList *ll); + +LinkedListErr linkedlist_append(LinkedList *ll, void *data); +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_get(const LinkedList *ll, size_t index, void *out); + +#endif /* ifndef LINKEDLIST_H */ diff --git a/src/linkedlist.c b/src/linkedlist.c new file mode 100644 index 0000000..82cc14d --- /dev/null +++ b/src/linkedlist.c @@ -0,0 +1,122 @@ +#include "linkedlist.h" +#include +#include +#include + +typedef struct Node { + void *data; + struct Node *next; +} Node; + +struct LinkedList { + size_t len; + size_t elem_size; + Node *head; +}; + +LinkedListErr linkedlist_create(LinkedList **out, size_t elem_size) { + if (out == NULL) { + return LLIST_NULL; + } + + if (elem_size < 1) { + return LLIST_INVALID_SIZE; + } + + LinkedList *new = malloc(sizeof(LinkedList)); + if (new == NULL) { + return LLIST_ALLOC; + } + new->elem_size = elem_size; + new->len = 0; + new->head = NULL; + + *out = new; + return LLIST_OK; +} + +LinkedListErr linkedlist_destroy(LinkedList *ll) { + if (ll == NULL) { + return LLIST_NULL; + } + + Node *current = ll->head; + if (ll->head == NULL) { + free(ll); + return LLIST_OK; + } + while(current->next != NULL) { + free(current->data); + Node *next = current->next; + free(current); + current = next; + } + free(current->data); + free(current); + free(ll); + + return LLIST_OK; +} + +LinkedListErr linkedlist_append(LinkedList *ll, void *data) { + if (ll == NULL) { + return LLIST_NULL; + } + + if (data == NULL) { + return LLIST_NULL_ARG; + } + + Node *current = ll->head; + if (ll->head != NULL) { + while(current->next != NULL) { + current = current->next; + } + } + + 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, data, ll->elem_size); + new_node->next = NULL; + + if (ll->head == NULL) { + ll->head = new_node; + } else { + current->next = new_node; + } + ll->len = ll->len + 1; + + return LLIST_OK; +} + +LinkedListErr linkedlist_get(const LinkedList *ll, size_t index, void *out) { + if (ll == NULL) { + return LLIST_NULL; + } + + if (out == NULL) { + return LLIST_NULL_ARG; + } + + if (index >= ll->len) { + return LLIST_OUT_OF_BOUNDS; + } + + Node *current = ll->head; + for (size_t i = 0; i < index; i++) { + current = current->next; + } + + memcpy(out, current->data, ll->elem_size); + + return LLIST_OK; +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..aa4f215 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,23 @@ +find_package(cmocka REQUIRED) + +add_executable(test_linkedlist + test_linkedlist.c +) + +target_link_libraries(test_linkedlist + PRIVATE + linkedlist + cmocka +) + +target_compile_options(test_linkedlist PRIVATE + -fsanitize=address +) + +target_link_options(test_linkedlist PRIVATE + -fsanitize=address +) + +add_test(NAME linkedlist_tests + COMMAND test_linkedlist) + diff --git a/tests/test_linkedlist.c b/tests/test_linkedlist.c new file mode 100644 index 0000000..dc429e4 --- /dev/null +++ b/tests/test_linkedlist.c @@ -0,0 +1,32 @@ +#include "linkedlist.h" +#include +#include +#include +#include +#include +#include +#include + +static void linkedlist_test_append(void **state) { + (void) state; + + LinkedList *ll; + linkedlist_create(&ll, sizeof(int)); + for (int i = 10; i < 13; i++) { + linkedlist_append(ll, &i); + } + for (int i = 0; i < 3; i++) { + int n; + linkedlist_get(ll, i, &n); + assert_int_equal(n, i + 10); + } + linkedlist_destroy(ll); +} + +int main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(linkedlist_test_append), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +}