Work on getting queue closer to compile.
This commit is contained in:
parent
07f27486dd
commit
e1e301fa14
|
@ -20,6 +20,10 @@
|
||||||
#define QUEUE_C
|
#define QUEUE_C
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
#endif /* QUEUE_C */
|
#endif /* QUEUE_C */
|
||||||
|
/* Include dependencies from linked list. */
|
||||||
|
#ifndef SINGLE_LINKED_LIST_H
|
||||||
|
#include "single_linked_list.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Function implementations. */
|
/* Function implementations. */
|
||||||
|
|
||||||
|
@ -33,14 +37,14 @@ queue_t *initialize_queue() {
|
||||||
result = (queue_t*) malloc(sizeof(queue_t));
|
result = (queue_t*) malloc(sizeof(queue_t));
|
||||||
|
|
||||||
/* Check if the allocation failed. */
|
/* Check if the allocation failed. */
|
||||||
if (result == NULL)
|
if (!result)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Allocate the internal list struct. */
|
/* Allocate the internal list struct. */
|
||||||
result->list = (list_t*) malloc(sizeof(list_t));
|
result->list = (linked_list_t*) malloc(sizeof(linked_list_t));
|
||||||
|
|
||||||
/* Check if the allocation failed. */
|
/* Check if the allocation failed. */
|
||||||
if (result->list == NULL) {
|
if (!(result->list)) {
|
||||||
free(result);
|
free(result);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -59,12 +63,12 @@ queue_t *initialize_queue() {
|
||||||
/* Note that if either the queue or node pointer are NULL, the function will automatically fail. */
|
/* Note that if either the queue or node pointer are NULL, the function will automatically fail. */
|
||||||
int enqueue(queue_t *queue, node_t *node) {
|
int enqueue(queue_t *queue, node_t *node) {
|
||||||
/* Input sanity check. */
|
/* Input sanity check. */
|
||||||
if (queue == NULL || queue->list == NULL || node == NULL || ((queue->list->head == NULL && queue->tail != NULL) || (queue->list->head != NULL && queue->tail == NULL)))
|
if (!queue || !(queue->list) || !node || ((!(queue->list->head) && queue->tail) || (queue->list->head && !(queue->tail))))
|
||||||
return FAILURE_CODE_QUEUE_C;
|
return FAILURE_CODE_QUEUE_C;
|
||||||
|
|
||||||
/* Attempt to enqueue the node. */
|
/* Attempt to enqueue the node. */
|
||||||
/* Check if the queue is empty. */
|
/* Check if the queue is empty. */
|
||||||
if (queue->list->head == NULL) {
|
if (!(queue->list->head)) {
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
queue->tail = node;
|
queue->tail = node;
|
||||||
} else
|
} else
|
||||||
|
@ -86,17 +90,17 @@ int enqueue_data(queue_t *queue, void *data) {
|
||||||
node_t *node;
|
node_t *node;
|
||||||
|
|
||||||
/* Input sanity check. */
|
/* Input sanity check. */
|
||||||
if (queue == NULL || queue->list == NULL || ((queue->list->head == NULL && queue->tail != NULL) || (queue->list->head != NULL && queue->tail == NULL)))
|
if (!queue || !(queue->list) || ((!(queue->list->head) && queue->tail) || (queue->list->head && !(queue->tail))))
|
||||||
return FAILURE_CODE_QUEUE_C;
|
return FAILURE_CODE_QUEUE_C;
|
||||||
|
|
||||||
/* Attempt to allocate the node. */
|
/* Attempt to allocate the node. */
|
||||||
node = (node_t) malloc(sizeof(node));
|
node = (node_t*) malloc(sizeof(node));
|
||||||
if (node == NULL)
|
if (!node)
|
||||||
return FAILURE_CODE_QUEUE_C;
|
return FAILURE_CODE_QUEUE_C;
|
||||||
|
|
||||||
/* Attempt to enqueue the node. */
|
/* Attempt to enqueue the node. */
|
||||||
/* Check if the queue is empty. */
|
/* Check if the queue is empty. */
|
||||||
if (queue->list->head == NULL) {
|
if (!(queue->list->head)) {
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
queue->tail = node;
|
queue->tail = node;
|
||||||
} else
|
} else
|
||||||
|
@ -111,7 +115,7 @@ int enqueue_data(queue_t *queue, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function dequeues a node. */
|
/* This function dequeues a node. */
|
||||||
/* This function attempts to dequeues a node from the given queue, on success will return a pointer to the dequeued node - otherwise returns NULL. */
|
/* This function attempts to dequeue a node from the given queue, on success will return a pointer to the dequeued node - otherwise returns NULL. */
|
||||||
/* Note that if either the queue or node pointer are NULL, the function will automatically fail. */
|
/* Note that if either the queue or node pointer are NULL, the function will automatically fail. */
|
||||||
node_t *dequeue(queue_t *queue) {
|
node_t *dequeue(queue_t *queue) {
|
||||||
/* Variables. */
|
/* Variables. */
|
||||||
|
@ -119,12 +123,12 @@ node_t *dequeue(queue_t *queue) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Input sanity check. */
|
/* Input sanity check. */
|
||||||
if (queue == NULL || queue->list == NULL || ((queue->list->head == NULL && queue->tail != NULL) || (queue->list->head != NULL && queue->tail == NULL)))
|
if (!queue || !(queue->list) || ((!(queue->list->head) && queue->tail) || (queue->list->head && !(queue->tail))))
|
||||||
return NULL;
|
return FAILURE_CODE_QUEUE_C;
|
||||||
|
|
||||||
/* Attempt to dequeue the node. */
|
/* Attempt to dequeue the node. */
|
||||||
/* Check if the queue is empty. */
|
/* Check if the queue is empty. */
|
||||||
if (queue->list->head == NULL)
|
if (!(queue->list->head))
|
||||||
return NULL;
|
return NULL;
|
||||||
else if (queue->list->length == 1) {
|
else if (queue->list->length == 1) {
|
||||||
/* A queue that is of length 1. */
|
/* A queue that is of length 1. */
|
||||||
|
@ -146,19 +150,19 @@ node_t *dequeue(queue_t *queue) {
|
||||||
/* Decrease the length. */
|
/* Decrease the length. */
|
||||||
(queue->list->length)--;
|
(queue->list->length)--;
|
||||||
|
|
||||||
/* Success. */
|
/* Return the node. */
|
||||||
return SUCCESS_CODE_QUEUE_C;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function frees all the nodes of the given queue and the queue itself (setting it to NULL). */
|
/* This function frees all the nodes of the given queue and the queue itself (setting it to NULL). */
|
||||||
/* Note that it doesn't touch the data stored within the queue's nodes, returns 1 on success and 0 on failure - in the latter case might exhibit undefined behavior. */
|
/* Note that it doesn't touch the data stored within the queue's nodes, returns 1 on success and 0 on failure - in the latter case might exhibit undefined behavior. */
|
||||||
int clear_queue(queue_t **queue) {
|
int clear_queue(queue_t **queue) {
|
||||||
/* Sanity check. */
|
/* Sanity check. */
|
||||||
if (queue == NULL || *queue == NULL)
|
if (!queue || !(*queue))
|
||||||
return FAILURE_CODE_QUEUE_C;
|
return FAILURE_CODE_QUEUE_C;
|
||||||
|
|
||||||
/* Delegate to implementation (linked list). */
|
/* Delegate to implementation (linked list). */
|
||||||
if (!clear_single_linked_list(&((*queue)->list)))
|
if (!clear_list_single_linked_list(&((*queue)->list)))
|
||||||
return FAILURE_CODE_QUEUE_C;
|
return FAILURE_CODE_QUEUE_C;
|
||||||
|
|
||||||
/* Successfully cleared the internal structure, just free the queue struct and set the pointer to NULL. */
|
/* Successfully cleared the internal structure, just free the queue struct and set the pointer to NULL. */
|
||||||
|
@ -170,13 +174,13 @@ int clear_queue(queue_t **queue) {
|
||||||
/* This function frees all the nodes of the given queue and the queue itself (setting it to NULL).*/
|
/* This function frees all the nodes of the given queue and the queue itself (setting it to NULL).*/
|
||||||
/* Note that it does free the stored data, returns 1 on success and 0 on failure - in the latter case might exhibit undefined behavior. */
|
/* Note that it does free the stored data, returns 1 on success and 0 on failure - in the latter case might exhibit undefined behavior. */
|
||||||
/* If free_function is NULL, then it the standard library's free() call is used. */
|
/* If free_function is NULL, then it the standard library's free() call is used. */
|
||||||
int clear_queue(queue_t **queue, void (*free_func)()) {
|
int clear_queue_data(queue_t **queue, void (*free_func)()) {
|
||||||
/* Sanity check. */
|
/* Sanity check. */
|
||||||
if (queue == NULL || *queue == NULL)
|
if (!queue || !(*queue))
|
||||||
return FAILURE_CODE_QUEUE_C;
|
return FAILURE_CODE_QUEUE_C;
|
||||||
|
|
||||||
/* Delegate to implementation (linked list). */
|
/* Delegate to implementation (linked list). */
|
||||||
if (!clear_single_linked_list(&((*queue)->list), free_function))
|
if (!clear_list_data_single_linked_list(&((*queue)->list), free_func))
|
||||||
return FAILURE_CODE_QUEUE_C;
|
return FAILURE_CODE_QUEUE_C;
|
||||||
|
|
||||||
/* Successfully cleared the internal structure, just free the queue struct and set the pointer to NULL. */
|
/* Successfully cleared the internal structure, just free the queue struct and set the pointer to NULL. */
|
||||||
|
@ -189,11 +193,11 @@ int clear_queue(queue_t **queue, void (*free_func)()) {
|
||||||
/* Note that it'll return NULL on allocation failure or invalid input - in the former case it'll set the correct length in the specified pointer, in the second it will set -1. */
|
/* Note that it'll return NULL on allocation failure or invalid input - in the former case it'll set the correct length in the specified pointer, in the second it will set -1. */
|
||||||
void **serialize_queue(queue_t *queue, int *length) {
|
void **serialize_queue(queue_t *queue, int *length) {
|
||||||
/* Sanity check. */
|
/* Sanity check. */
|
||||||
if (queue == NULL) {
|
if (!queue) {
|
||||||
*length = -1;
|
*length = -1;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delegate. */
|
/* Delegate. */
|
||||||
return serialize_list(queue->list, length);
|
return serialize_linked_list(queue->list, length);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
/* The linked list's struct. */
|
/* The linked list's struct. */
|
||||||
typedef struct queue {
|
typedef struct queue {
|
||||||
/* Single linked list as the backbone. */
|
/* Single linked list as the backbone. */
|
||||||
single_linked_list_t *list;
|
linked_list_t *list;
|
||||||
/* Keep the tail for fast access. */
|
/* Keep the tail for fast access. */
|
||||||
node_t *tail;
|
node_t *tail;
|
||||||
} queue_t;
|
} queue_t;
|
||||||
|
|
|
@ -16,6 +16,9 @@ bubble_sort_tests.o: bubble_sort_tests.c
|
||||||
double_linked_list_tests.out: double_linked_list_tests.c
|
double_linked_list_tests.out: double_linked_list_tests.c
|
||||||
gcc -g -fsanitize=address -fsanitize=leak -fsanitize=undefined double_linked_list_tests.c -o double_linked_list_tests.out
|
gcc -g -fsanitize=address -fsanitize=leak -fsanitize=undefined double_linked_list_tests.c -o double_linked_list_tests.out
|
||||||
|
|
||||||
|
queue_tests.out: queue_tests.c
|
||||||
|
gcc -g -I ../linked_lists/ -fsanitize=address -fsanitize=leak -fsanitize=undefined queue_tests.c -o queue_tests.out
|
||||||
|
|
||||||
quick_sort_tests.out: array_print.o quick_sort_tests.o
|
quick_sort_tests.out: array_print.o quick_sort_tests.o
|
||||||
gcc -g -fanalyzer -Wanalyzer-too-complex -fanalyzer-call-summaries -fsanitize=address -fsanitize=leak -fsanitize=undefined array_print.o quick_sort_tests.o -o quick_sort_tests.out
|
gcc -g -fanalyzer -Wanalyzer-too-complex -fanalyzer-call-summaries -fsanitize=address -fsanitize=leak -fsanitize=undefined array_print.o quick_sort_tests.o -o quick_sort_tests.out
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ int test_queues();
|
||||||
/* Starting point. */
|
/* Starting point. */
|
||||||
int main() {
|
int main() {
|
||||||
printf(PRINT_INFO_TESTING_START);
|
printf(PRINT_INFO_TESTING_START);
|
||||||
if (test_linked_lists()) {
|
if (test_queues()) {
|
||||||
printf(SOME_TEST_FAILED);
|
printf(SOME_TEST_FAILED);
|
||||||
}
|
}
|
||||||
printf(PRINT_INFO_TESTING_END);
|
printf(PRINT_INFO_TESTING_END);
|
||||||
|
@ -54,8 +54,8 @@ node_t* generate_random_node() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function generates a long list with random values in the nodes, returns NULL on failures. */
|
/* This function generates a long queue with random values in the nodes, returns NULL on failures. */
|
||||||
/* Length denotes the length of the list. */
|
/* Length denotes the length of the queue. */
|
||||||
queue_t* generate_long_random_queue(int length) {
|
queue_t* generate_long_random_queue(int length) {
|
||||||
/* Sanity check. */
|
/* Sanity check. */
|
||||||
if (length <= 0)
|
if (length <= 0)
|
||||||
|
@ -103,13 +103,13 @@ queue_t* generate_long_random_queue(int length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function checks the actual length of a queue. */
|
/* This function checks the actual length of a queue. */
|
||||||
int queue_count_length(linked_list_t *list) {
|
int queue_count_length(queue_t *queue) {
|
||||||
if (list == NULL || list->head == NULL)
|
if (!queue || !queue->list || !queue->list->head)
|
||||||
return 0;
|
return 0;
|
||||||
/* Loop and count. */
|
/* Loop and count. */
|
||||||
node_t *current = list->head;
|
node_t *current = queue->list->head;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
while (current != NULL) {
|
while (current) {
|
||||||
count++;
|
count++;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ int queue_count_length(linked_list_t *list) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function attempts to allocate a list, fill it, then serialize it. */
|
/* This function attempts to allocate a queue, fill it, then serialize it. */
|
||||||
int test_serialization() {
|
int test_serialization() {
|
||||||
/* Local variables. */
|
/* Local variables. */
|
||||||
int i, length;
|
int i, length;
|
||||||
|
@ -129,12 +129,11 @@ int test_serialization() {
|
||||||
/* Allocations. */
|
/* Allocations. */
|
||||||
/* Initialize the queue. */
|
/* Initialize the queue. */
|
||||||
queue_t *queue = initialize_queue();
|
queue_t *queue = initialize_queue();
|
||||||
if (list == NULL) {
|
if (queue == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill the queue. */
|
/* Fill the queue. */
|
||||||
for (i = 0; i < SERIALIZATION_TEST_LIST_LENGTH; i++) {
|
for (i = 0; i < SERIALIZATION_TEST_QUEUE_LENGTH; i++) {
|
||||||
/* Allocate the value store. */
|
/* Allocate the value store. */
|
||||||
value = (int*) malloc(sizeof(int));
|
value = (int*) malloc(sizeof(int));
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
|
@ -151,11 +150,11 @@ int test_serialization() {
|
||||||
enqueue_data(queue, value);
|
enqueue_data(queue, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Serialize the list. */
|
/* Serialize the queue. */
|
||||||
array = serialize_queue(queue, &length);
|
array = serialize_queue(queue, &length);
|
||||||
/* Check if the serialization failed. */
|
/* Check if the serialization failed. */
|
||||||
if (length == -1 || length != list->length) {
|
if (length == -1 || length != queue->list->length) {
|
||||||
/* Clear the list. */
|
/* Clear the queue. */
|
||||||
clear_queue_data(&queue, NULL);
|
clear_queue_data(&queue, NULL);
|
||||||
/* Free the array. */
|
/* Free the array. */
|
||||||
free(array);
|
free(array);
|
||||||
|
@ -164,9 +163,9 @@ int test_serialization() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the values. */
|
/* Check the values. */
|
||||||
for (i = 0; i < SERIALIZATION_TEST_LIST_LENGTH; i++) {
|
for (i = 0; i < SERIALIZATION_TEST_QUEUE_LENGTH; i++) {
|
||||||
if (*((int *)(array[i])) != i) {
|
if (*((int *)(array[i])) != i) {
|
||||||
/* Clear the list. */
|
/* Clear the queue. */
|
||||||
clear_queue_data(&queue, NULL);
|
clear_queue_data(&queue, NULL);
|
||||||
/* Free the array. */
|
/* Free the array. */
|
||||||
free(array);
|
free(array);
|
||||||
|
@ -176,7 +175,7 @@ int test_serialization() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Passed the tests. */
|
/* Passed the tests. */
|
||||||
/* Clear the list. */
|
/* Clear the queue. */
|
||||||
clear_queue_data(&queue, NULL);
|
clear_queue_data(&queue, NULL);
|
||||||
/* Free the array. */
|
/* Free the array. */
|
||||||
free(array);
|
free(array);
|
||||||
|
@ -191,12 +190,12 @@ int test_queues() {
|
||||||
node_t *node, *tail;
|
node_t *node, *tail;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
/* Initialize an empty list. */
|
/* Initialize an empty queue. */
|
||||||
queue = initialize_queue();
|
queue = initialize_queue();
|
||||||
/* Check that it was correctly created. */
|
/* Check that it was correctly created. */
|
||||||
assert(queue != NULL);
|
assert(queue != NULL);
|
||||||
assert(queue->length == INITIAL_QUEUE_LENGTH);
|
|
||||||
assert(queue->list != NULL);
|
assert(queue->list != NULL);
|
||||||
|
assert(queue->list->length == INITIAL_QUEUE_LENGTH);
|
||||||
assert(queue->list->head == NULL);
|
assert(queue->list->head == NULL);
|
||||||
assert(queue->tail == NULL);
|
assert(queue->tail == NULL);
|
||||||
|
|
||||||
|
@ -212,18 +211,19 @@ int test_queues() {
|
||||||
assert(get_node_i_single_linked_list(queue->list, 0, &error) == node);
|
assert(get_node_i_single_linked_list(queue->list, 0, &error) == node);
|
||||||
assert(get_node_index_pointer_single_linked_list(queue->list, node) == 0);
|
assert(get_node_index_pointer_single_linked_list(queue->list, node) == 0);
|
||||||
|
|
||||||
/* Attempt to free the nodes and then the list. */
|
/* Attempt to free the nodes and then the queue. */
|
||||||
node = dequeue(queue);
|
node = dequeue(queue);
|
||||||
assert(queue->list->length == INITIAL_QUEUE_LENGTH);
|
assert(queue->list->length == INITIAL_QUEUE_LENGTH);
|
||||||
assert(queue->list->head == NULL);
|
assert(queue->list->head == NULL);
|
||||||
assert(queue->tail == NULL);
|
assert(queue->tail == NULL);
|
||||||
node = NULL;
|
node = NULL;
|
||||||
free(list);
|
free(queue->list);
|
||||||
list = NULL;
|
free(queue);
|
||||||
|
queue = NULL;
|
||||||
|
|
||||||
/* Attempt to allocate a long list. */
|
/* Attempt to allocate a long queue. */
|
||||||
list = generate_long_random_list(QUEUE_LENGTH_LONG_TEST);
|
queue = generate_long_random_queue(QUEUE_LENGTH_LONG_TEST);
|
||||||
if (list == NULL) {
|
if (queue == NULL) {
|
||||||
printf(ERROR_TEXT_RANDOM_QUEUE_FAIL_ALLOCATION);
|
printf(ERROR_TEXT_RANDOM_QUEUE_FAIL_ALLOCATION);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue