diff options
author | Johnny Richard <johnny@johnnyrichard.com> | 2023-05-09 19:55:01 +0200 |
---|---|---|
committer | Carlos Maniero <carlos@maniero.me> | 2023-05-09 16:05:09 -0300 |
commit | 3842de0e22d72075f06bd8cc44b8744e86c21725 (patch) | |
tree | 8377ec7c1d35d4aabb592a9abeb91652fc1ea53d | |
parent | aba7302e7e98fd7bca2056d8ad622d9ca81c495f (diff) |
utils: Create linked list data structure
This is a simple implementation of a general propose single-linked list.
There is only the *prepend* function implemented at this moment. We can
alway revisit the code and implement new missing functionality on demand.
Signed-off-by: Johnny Richard <johnny@johnnyrichard.com>
-rw-r--r-- | src/list.c | 69 | ||||
-rw-r--r-- | src/list.h | 40 | ||||
-rw-r--r-- | test/Makefile | 3 | ||||
-rw-r--r-- | test/list_test.c | 64 |
4 files changed, 176 insertions, 0 deletions
diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000..b73280f --- /dev/null +++ b/src/list.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2023 Johnny Richard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ +#include "list.h" + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +static list_t * +list_alloc(void) +{ + list_t *list = (list_t *)malloc(sizeof(list_t)); + if (list == NULL) { + fprintf(stderr, "list_alloc: Out of memory %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + return list; +} + +list_t * +list_new(void) +{ + return NULL; +} + +void +list_prepend(list_t **list, void *data) +{ + list_t *new_list = list_alloc(); + new_list->data = data; + new_list->next = *list; + *list = new_list; +} + +size_t +list_get_size(list_t *list) +{ + size_t size = 0; + while (list != NULL) { + list = list->next; + size++; + } + return size; +} + +void +list_destroy(list_t *list) +{ + while (list != NULL) { + list_t *previous = list; + list = list->next; + free(previous); + } +} diff --git a/src/list.h b/src/list.h new file mode 100644 index 0000000..efe5720 --- /dev/null +++ b/src/list.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2023 Johnny Richard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ +#ifndef LIST_H +#define LIST_H + +#include <stdlib.h> + +typedef struct list_t +{ + void *data; + struct list_t *next; +} list_t; + +list_t * +list_new(void); + +void +list_prepend(list_t **list, void *data); + +size_t +list_get_size(list_t *list); + +void +list_destroy(list_t *list); + +#endif /* LIST_H */ diff --git a/test/Makefile b/test/Makefile index 1655f06..6bdec12 100644 --- a/test/Makefile +++ b/test/Makefile @@ -28,6 +28,9 @@ string_view_test: munit.o ../build/string_view.o string_view_test.o vector_test: munit.o ../build/vector.o vector_test.o $(CC) $? $(CFLAGS) -o $@ +list_test: munit.o ../build/list.o list_test.o + $(CC) $? $(CFLAGS) -o $@ + lexer_test: munit.o ../build/string_view.o ../build/lexer.o lexer_test.o $(CC) $? $(CFLAGS) -o $@ diff --git a/test/list_test.c b/test/list_test.c new file mode 100644 index 0000000..041ceec --- /dev/null +++ b/test/list_test.c @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2023 Johnny Richard + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ +#define MUNIT_ENABLE_ASSERT_ALIASES +#include "list.h" +#include "munit.h" + +static MunitResult +test_create_new(const MunitParameter params[], void *user_data_or_fixture) +{ + list_t *list = list_new(); + + assert_null(list); + + list_destroy(list); + + return MUNIT_OK; +} + +static MunitResult +test_list_prepend(const MunitParameter params[], void *user_data_or_fixture) +{ + list_t *list = list_new(); + + int number1 = 1; + int number2 = 2; + + list_prepend(&list, (void *)&number1); + list_prepend(&list, (void *)&number2); + + assert_int(list_get_size(list), ==, 2); + assert_int(*((int *)list->data), ==, number2); + assert_int(*((int *)list->next->data), ==, number1); + + list_destroy(list); + + return MUNIT_OK; +} + +static MunitTest tests[] = { { "/test_create_new", test_create_new, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }, + { "/test_list_prepend", test_list_prepend, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL }, + { NULL, NULL, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL } }; + +static const MunitSuite suite = { "/list", tests, NULL, 1, MUNIT_SUITE_OPTION_NONE }; + +int +main(int argc, char *argv[]) +{ + return munit_suite_main(&suite, NULL, argc, argv); + return EXIT_SUCCESS; +} |