First commit, fixed appending, create, destroy and get, all working fine
This commit is contained in:
54
.gitignore
vendored
Normal file
54
.gitignore
vendored
Normal file
@@ -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
|
||||
*~
|
||||
|
||||
36
CMakeLists.txt
Normal file
36
CMakeLists.txt
Normal file
@@ -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)
|
||||
|
||||
26
include/linkedlist.h
Normal file
26
include/linkedlist.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef LINKEDLIST_H
|
||||
#define LINKEDLIST_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
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 */
|
||||
122
src/linkedlist.c
Normal file
122
src/linkedlist.c
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "linkedlist.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
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;
|
||||
}
|
||||
23
tests/CMakeLists.txt
Normal file
23
tests/CMakeLists.txt
Normal file
@@ -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)
|
||||
|
||||
32
tests/test_linkedlist.c
Normal file
32
tests/test_linkedlist.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "linkedlist.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user