crafting-interpreters/1/HelloWorldC/main.c
2020-10-12 20:46:11 -07:00

297 lines
7.5 KiB
C

#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <string.h>
struct double_linked_list {
struct double_linked_list *prev;
struct double_linked_list *next;
char *data;
};
struct double_linked_list *
make_double_linked_list(char *data)
{
struct double_linked_list *list =
(struct double_linked_list *)malloc(sizeof(struct double_linked_list));
list->data = data;
list->prev = NULL;
list->next = NULL;
return list;
}
void
insert_double_linked_list_before(struct double_linked_list *list, char *data)
{
struct double_linked_list *prev = make_double_linked_list(data);
if (list->prev != NULL) {
prev->prev = list->prev;
}
list->prev = prev;
}
void
insert_double_linked_list_after(struct double_linked_list *list, char *data)
{
struct double_linked_list *next = make_double_linked_list(data);
if (list->next != NULL) {
next->next = list->next;
}
list->next = next;
}
void
free_double_linked_list(struct double_linked_list *list)
{
if (list != NULL) {
if (list->data != NULL) {
free(list->data);
}
struct double_linked_list *prev = list->prev;
while (prev != NULL) {
struct double_linked_list *inner = prev;
prev = prev->prev;
free(inner->data);
free(inner);
}
struct double_linked_list *next = list->next;
while (next != NULL) {
struct double_linked_list *inner = next;
next = next->next;
free(inner->data);
free(inner);
}
free(list);
}
}
static void
test_double_linked_list_initialized_prev_null(void **state)
{
(void)state;
char *data = (char *)malloc(sizeof(char) * 4);
strcpy(data, "foo");
struct double_linked_list *list = make_double_linked_list(data);
assert_null(list->prev);
free_double_linked_list(list);
}
static void
test_double_linked_list_initialized_next_null(void **state)
{
(void)state;
char *data = (char *)malloc(sizeof(char) * 4);
strcpy(data, "foo");
struct double_linked_list *list = make_double_linked_list(data);
assert_null(list->next);
free_double_linked_list(list);
}
static void
test_double_linked_list_initialized_with_data(void **state)
{
(void)state;
char *data = (char *)malloc(sizeof(char) * 4);
strcpy(data, "foo");
struct double_linked_list *list = make_double_linked_list(data);
assert_string_equal(list->data, "foo");
free_double_linked_list(list);
}
static void
test_double_linked_list_insert_before_prev_not_null(void **state)
{
(void)state;
char *data = (char *)malloc(sizeof(char) * 4);
strcpy(data, "foo");
struct double_linked_list *list = make_double_linked_list(data);
char *beforeData = (char *)malloc(sizeof(char) * 4);
strcpy(data, "bar");
insert_double_linked_list_before(list, beforeData);
assert_non_null(list->prev);
free_double_linked_list(list);
}
static void
test_double_linked_list_insert_before_prev_is_inserted_data(void **state)
{
(void)state;
char *data = (char *)malloc(sizeof(char) * 4);
strcpy(data, "foo");
struct double_linked_list *list = make_double_linked_list(data);
char *beforeData = (char *)malloc(sizeof(char) * 4);
strcpy(beforeData, "bar");
insert_double_linked_list_before(list, beforeData);
assert_string_equal(list->prev->data, "bar");
free_double_linked_list(list);
}
static void
test_double_linked_list_insert_multiple_prev_adds_data(void **state)
{
(void)state;
char *data = (char *)malloc(sizeof(char) * 4);
strcpy(data, "foo");
struct double_linked_list *list = make_double_linked_list(data);
char *beforeBeforeData = (char *)malloc(sizeof(char) * 4);
strcpy(beforeBeforeData, "bar");
char *beforeData = (char *)malloc(sizeof(char) * 4);
strcpy(beforeData, "qux");
insert_double_linked_list_before(list, beforeBeforeData);
insert_double_linked_list_before(list, beforeData);
assert_non_null(list->prev->prev);
free_double_linked_list(list);
}
static void
test_double_linked_list_insert_multiple_prev_adds_data_with_data(void **state)
{
(void)state;
char *data = (char *)malloc(sizeof(char) * 4);
strcpy(data, "foo");
struct double_linked_list *list = make_double_linked_list(data);
char *beforeBeforeData = (char *)malloc(sizeof(char) * 4);
strcpy(beforeBeforeData, "bar");
char *beforeData = (char *)malloc(sizeof(char) * 4);
strcpy(beforeData, "qux");
insert_double_linked_list_before(list, beforeBeforeData);
insert_double_linked_list_before(list, beforeData);
assert_string_equal(list->prev->prev->data, "bar");
free_double_linked_list(list);
}
static void
test_double_linked_list_insert_after_next_not_null(void **state)
{
(void)state;
char *data = (char *)malloc(sizeof(char) * 4);
strcpy(data, "foo");
struct double_linked_list *list = make_double_linked_list(data);
char *afterData = (char *)malloc(sizeof(char) * 4);
strcpy(data, "bar");
insert_double_linked_list_after(list, afterData);
assert_non_null(list->next);
free_double_linked_list(list);
}
static void
test_double_linked_list_insert_after_next_is_inserted_data(void **state)
{
(void)state;
char *data = (char *)malloc(sizeof(char) * 4);
strcpy(data, "foo");
struct double_linked_list *list = make_double_linked_list(data);
char *afterData = (char *)malloc(sizeof(char) * 4);
strcpy(afterData, "bar");
insert_double_linked_list_after(list, afterData);
assert_string_equal(list->next->data, "bar");
free_double_linked_list(list);
}
static void
test_double_linked_list_insert_multiple_next_adds_data(void **state)
{
(void)state;
char *data = (char *)malloc(sizeof(char) * 4);
strcpy(data, "foo");
struct double_linked_list *list = make_double_linked_list(data);
char *afterAfterData = (char *)malloc(sizeof(char) * 4);
strcpy(afterAfterData, "bar");
char *afterData = (char *)malloc(sizeof(char) * 4);
strcpy(afterData, "qux");
insert_double_linked_list_after(list, afterAfterData);
insert_double_linked_list_after(list, afterData);
assert_non_null(list->next->next);
free_double_linked_list(list);
}
static void
test_double_linked_list_insert_multiple_next_adds_data_with_data(void **state)
{
(void)state;
char *data = (char *)malloc(sizeof(char) * 4);
strcpy(data, "foo");
struct double_linked_list *list = make_double_linked_list(data);
char *afterAfterData = (char *)malloc(sizeof(char) * 4);
strcpy(afterAfterData, "bar");
char *afterData = (char *)malloc(sizeof(char) * 4);
strcpy(afterData, "qux");
insert_double_linked_list_after(list, afterAfterData);
insert_double_linked_list_after(list, afterData);
assert_string_equal(list->next->next->data, "bar");
free_double_linked_list(list);
}
int
main()
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_double_linked_list_initialized_prev_null),
cmocka_unit_test(test_double_linked_list_initialized_next_null),
cmocka_unit_test(test_double_linked_list_initialized_with_data),
cmocka_unit_test(test_double_linked_list_insert_before_prev_not_null),
cmocka_unit_test(test_double_linked_list_insert_before_prev_is_inserted_data),
cmocka_unit_test(test_double_linked_list_insert_multiple_prev_adds_data),
cmocka_unit_test(test_double_linked_list_insert_multiple_prev_adds_data_with_data),
cmocka_unit_test(test_double_linked_list_insert_after_next_not_null),
cmocka_unit_test(test_double_linked_list_insert_after_next_is_inserted_data),
cmocka_unit_test(test_double_linked_list_insert_multiple_next_adds_data),
cmocka_unit_test(test_double_linked_list_insert_multiple_next_adds_data_with_data),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}