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