Cleaned up the double linked lists code, now does minimal checking at runtime and levareges assertions for wider checks in debug mode.
This commit is contained in:
parent
56e195c9b4
commit
4c394f94b5
|
@ -25,7 +25,7 @@
|
|||
/* Function implementations. */
|
||||
|
||||
/* This function initializes a new double-linked list, returns NULL on failure. */
|
||||
double_linked_list_t* initialize_double_linked_list() {
|
||||
static inline double_linked_list_t* initialize_double_linked_list() {
|
||||
/* Local variables. */
|
||||
double_linked_list_t* list;
|
||||
|
||||
|
@ -33,7 +33,7 @@ double_linked_list_t* initialize_double_linked_list() {
|
|||
list = (double_linked_list_t*) malloc(sizeof(double_linked_list_t));
|
||||
|
||||
/* Check if the allocation failed. */
|
||||
if (list == NULL)
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
/* Initialize the internal fields. */
|
||||
|
@ -46,11 +46,9 @@ double_linked_list_t* initialize_double_linked_list() {
|
|||
}
|
||||
|
||||
/* This function appends a node to the given linked list. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
int append_node_double_linked_list(double_linked_list_t *list, double_node_t *node){
|
||||
static inline void append_node_double_linked_list(double_linked_list_t *list, double_node_t *node){
|
||||
/* Sanity check - make sure input is not NULL and list state is defined! */
|
||||
if (!list || !node || (list->head && !(list->tail)) || (!(list->head) && list->tail))
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && node && ((list->head && list->tail) || (!(list->head) && !(list->tail))));
|
||||
|
||||
/* Set the next node to NULL. */
|
||||
node->next = NULL;
|
||||
|
@ -64,7 +62,7 @@ int append_node_double_linked_list(double_linked_list_t *list, double_node_t *no
|
|||
list->head = node;
|
||||
list->tail = node;
|
||||
list->length = 1;
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Connect the nodes and update the tail. */
|
||||
|
@ -72,15 +70,12 @@ int append_node_double_linked_list(double_linked_list_t *list, double_node_t *no
|
|||
node->previous = list->tail;
|
||||
list->tail = node;
|
||||
(list->length)++;
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function prepends a node the the given linked list. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
int prepend_node_double_linked_list(double_linked_list_t *list, double_node_t *node){
|
||||
static inline void prepend_node_double_linked_list(double_linked_list_t *list, double_node_t *node){
|
||||
/* Sanity check - make sure input is not NULL and list state is defined! */
|
||||
if (!list || !node || (list->head && !(list->tail)) || (!(list->head) && list->tail))
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && node && ((list->head && list->tail) || (!(list->head) && !(list->tail))));
|
||||
|
||||
/* Set the previous node to NULL. */
|
||||
node->previous = NULL;
|
||||
|
@ -94,7 +89,7 @@ int prepend_node_double_linked_list(double_linked_list_t *list, double_node_t *n
|
|||
list->head = node;
|
||||
list->tail = node;
|
||||
list->length = 1;
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Connect the nodes and update the head. */
|
||||
|
@ -102,15 +97,13 @@ int prepend_node_double_linked_list(double_linked_list_t *list, double_node_t *n
|
|||
node->next = list->head;
|
||||
list->tail = node;
|
||||
(list->length)++;
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function creates and appends a node to the given linked list. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
int append_node_data_double_linked_list(double_linked_list_t *list, void *data){
|
||||
static inline int append_node_data_double_linked_list(double_linked_list_t *list, void *data){
|
||||
/* Sanity check - make sure input is not NULL and list state is defined! */
|
||||
if (!list || (list->head && !(list->tail)) || (!(list->head) && list->tail))
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))));
|
||||
|
||||
/* Local variables. */
|
||||
double_node_t* node;
|
||||
|
@ -124,15 +117,15 @@ int append_node_data_double_linked_list(double_linked_list_t *list, void *data){
|
|||
node->data = data;
|
||||
|
||||
/* Delegate. */
|
||||
return append_node_double_linked_list(list, node);
|
||||
append_node_double_linked_list(list, node);
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function creates and prepends a node to the given linked list. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
int prepend_node_data_double_linked_list(double_linked_list_t *list, void *data){
|
||||
static inline int prepend_node_data_double_linked_list(double_linked_list_t *list, void *data){
|
||||
/* Sanity check - make sure input is not NULL and list state is defined! */
|
||||
if (!list || (list->head && !(list->tail)) || (!(list->head) && list->tail))
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))));
|
||||
|
||||
/* Local variables. */
|
||||
double_node_t* node;
|
||||
|
@ -146,21 +139,24 @@ int prepend_node_data_double_linked_list(double_linked_list_t *list, void *data)
|
|||
node->data = data;
|
||||
|
||||
/* Delegate. */
|
||||
return prepend_node_double_linked_list(list, node);
|
||||
prepend_node_double_linked_list(list, node);
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function inserts a node at the ith place. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
int add_node_i_double_linked_list(double_linked_list_t *list, double_node_t *node, size_t i) {
|
||||
static inline void add_node_i_double_linked_list(double_linked_list_t *list, double_node_t *node, size_t i) {
|
||||
/* Sanity check - make sure input is not NULL, list state is defined and index is valid. */
|
||||
if (!list || !node || (list->head && !(list->tail)) || (!(list->head) && list->tail) || i > list->length)
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && node && ((list->head && list->tail) || (!(list->head) && !(list->tail))) && i < list->length);
|
||||
|
||||
/* Deal with special "easy" cases. */
|
||||
if (!i)
|
||||
return prepend_node_double_linked_list(list, node);
|
||||
if (i == list->length)
|
||||
return append_node_double_linked_list(list, node);
|
||||
if (!i) {
|
||||
prepend_node_double_linked_list(list, node);
|
||||
return;
|
||||
}
|
||||
if (i == list->length) {
|
||||
append_node_double_linked_list(list, node);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Local variables. */
|
||||
size_t index;
|
||||
|
@ -178,17 +174,13 @@ int add_node_i_double_linked_list(double_linked_list_t *list, double_node_t *nod
|
|||
|
||||
/* Increase the length. */
|
||||
(list->length)++;
|
||||
|
||||
/* Inserted. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function creates and inserts a node at the ith place. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
int add_node_data_i_double_linked_list(double_linked_list_t *list, void *data, size_t i) {
|
||||
static inline int add_node_data_i_double_linked_list(double_linked_list_t *list, void *data, size_t i) {
|
||||
/* Sanity check - make sure list state is defined and index is valid. */
|
||||
if (!list || (list->head && !(list->tail)) || (!(list->head) && list->tail) || i > list->length)
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))) && i < list->length);
|
||||
|
||||
/* Local variables. */
|
||||
double_node_t* node;
|
||||
|
@ -202,20 +194,15 @@ int add_node_data_i_double_linked_list(double_linked_list_t *list, void *data, s
|
|||
node->data = data;
|
||||
|
||||
/* Delegate. */
|
||||
return add_node_i_double_linked_list(list, node, i);
|
||||
add_node_i_double_linked_list(list, node, i);
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function reads the data at the ith node. */
|
||||
/* Returns NULL on failure! (Even if NULL can be a legitimate value). */
|
||||
/* Sets error to SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
void* read_node_i_double_linked_list(double_linked_list_t *list, size_t i, int *error) {
|
||||
static inline void* read_node_i_double_linked_list(double_linked_list_t *list, size_t i) {
|
||||
/* Sanity check - make sure list state is defined and index is valid. */
|
||||
if (!error)
|
||||
return NULL;
|
||||
if (!list || (list->head && !(list->tail)) || (!(list->head) && list->tail) || i > list->length) {
|
||||
*error = FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return NULL;
|
||||
}
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))) && i < list->length);
|
||||
|
||||
/* Local variables. */
|
||||
size_t index;
|
||||
|
@ -226,24 +213,15 @@ void* read_node_i_double_linked_list(double_linked_list_t *list, size_t i, int *
|
|||
for (index = 0L; index < i; index++)
|
||||
current = current->next;
|
||||
|
||||
/* Set the error code. */
|
||||
*error = SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
|
||||
/* Return the data. */
|
||||
return current->data;
|
||||
}
|
||||
|
||||
/* This function retrieves a pointer to the ith node. */
|
||||
/* Returns NULL on failure! */
|
||||
/* Sets error to SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
double_node_t* get_node_i_double_linked_list(double_linked_list_t *list, size_t i, int *error) {
|
||||
static inline double_node_t* get_node_i_double_linked_list(double_linked_list_t *list, size_t i) {
|
||||
/* Sanity check - make sure list state is defined and index is valid. */
|
||||
if (!error)
|
||||
return NULL;
|
||||
if (!list || (list->head && !(list->tail)) || (!(list->head) && list->tail != NULL) || i > list->length) {
|
||||
*error = FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return NULL;
|
||||
}
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))) && i < list->length);
|
||||
|
||||
/* Local variables. */
|
||||
size_t index;
|
||||
|
@ -254,20 +232,15 @@ double_node_t* get_node_i_double_linked_list(double_linked_list_t *list, size_t
|
|||
for (index = 0L; index < i; index++)
|
||||
current = current->next;
|
||||
|
||||
/* Set the error code. */
|
||||
*error = SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
|
||||
/* Return the node pointer. */
|
||||
return current;
|
||||
}
|
||||
|
||||
/* This function attempts to find the index of a given node, by pointer. */
|
||||
/* Returns INDEX_NOT_FOUND_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
size_t get_node_index_pointer_double_linked_list(double_linked_list_t *list, double_node_t *node) {
|
||||
static inline size_t get_node_index_pointer_double_linked_list(double_linked_list_t *list, double_node_t *node) {
|
||||
/* Sanity check. */
|
||||
if (!list || (list->head && !(list->tail)) || (!(list->head) && list->tail) || !node)
|
||||
return INDEX_NOT_FOUND_CODE_DOUBLE_LINKED_LIST_C;
|
||||
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))) && node);
|
||||
|
||||
/* Local variables. */
|
||||
size_t index = 0L;
|
||||
|
@ -284,11 +257,9 @@ size_t get_node_index_pointer_double_linked_list(double_linked_list_t *list, dou
|
|||
}
|
||||
|
||||
/* This function deletes the ith node, leaves the data AS IS! */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
int remove_node_i_double_linked_list(double_linked_list_t *list, size_t i) {
|
||||
static inline void remove_node_i_double_linked_list(double_linked_list_t *list, size_t i) {
|
||||
/* Sanity check - make sure list state is defined and index is valid. */
|
||||
if (!list || (list->head && !(list->tail)) || (!(list->head) && list->tail) || i > list->length)
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))) && i < list->length);
|
||||
|
||||
/* Local variables. */
|
||||
double_node_t* current;
|
||||
|
@ -297,7 +268,7 @@ int remove_node_i_double_linked_list(double_linked_list_t *list, size_t i) {
|
|||
/* Special case of an empty list. */
|
||||
if (!(list->length)) {
|
||||
/* Do nothing. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Special case of a list with a single node. */
|
||||
|
@ -309,7 +280,7 @@ int remove_node_i_double_linked_list(double_linked_list_t *list, size_t i) {
|
|||
list->tail = NULL;
|
||||
list->length = 0L;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Loop till we get to the desired node. */
|
||||
|
@ -331,7 +302,7 @@ int remove_node_i_double_linked_list(double_linked_list_t *list, size_t i) {
|
|||
/* Update length. */
|
||||
(list->length)--;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
if (!(current->next)) {
|
||||
/* Update tail. */
|
||||
|
@ -343,7 +314,7 @@ int remove_node_i_double_linked_list(double_linked_list_t *list, size_t i) {
|
|||
/* Update length. */
|
||||
(list->length)--;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* General (middle) case. */
|
||||
|
@ -355,17 +326,13 @@ int remove_node_i_double_linked_list(double_linked_list_t *list, size_t i) {
|
|||
current = NULL;
|
||||
/* Update length. */
|
||||
(list->length)--;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function deletes the ith node and the data stored within. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
/* If free_function is NULL, will use the stdlib's free(). */
|
||||
int remove_node_i_data_double_linked_list(double_linked_list_t *list, size_t i, void (*free_function)(const void*)) {
|
||||
static inline void remove_node_i_data_double_linked_list(double_linked_list_t *list, size_t i, void (*free_function)(const void*)) {
|
||||
/* Sanity check - make sure list state is defined and index is valid. */
|
||||
if (!list || (list->head && !(list->tail)) || (!(list->head) && list->tail) || i > list->length)
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))) && i < list->length);
|
||||
|
||||
/* Local variables. */
|
||||
double_node_t* current;
|
||||
|
@ -374,7 +341,7 @@ int remove_node_i_data_double_linked_list(double_linked_list_t *list, size_t i,
|
|||
/* Special case of an empty list. */
|
||||
if (!(list->length)) {
|
||||
/* Done nothing. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Special case of a list with a single node. */
|
||||
|
@ -391,7 +358,7 @@ int remove_node_i_data_double_linked_list(double_linked_list_t *list, size_t i,
|
|||
list->tail = NULL;
|
||||
list->length = 0L;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Loop till we get to the desired node. */
|
||||
|
@ -414,7 +381,7 @@ int remove_node_i_data_double_linked_list(double_linked_list_t *list, size_t i,
|
|||
/* Update length. */
|
||||
(list->length)--;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
if (!(current->next)) {
|
||||
/* Update tail. */
|
||||
|
@ -430,7 +397,7 @@ int remove_node_i_data_double_linked_list(double_linked_list_t *list, size_t i,
|
|||
/* Update length. */
|
||||
(list->length)--;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* General (middle) case. */
|
||||
|
@ -446,42 +413,36 @@ int remove_node_i_data_double_linked_list(double_linked_list_t *list, size_t i,
|
|||
current = NULL;
|
||||
/* Update length. */
|
||||
(list->length)--;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function reads the data at the first node. */
|
||||
/* Returns NULL on error or empty list. */
|
||||
void* read_node_head_double_linked_list(double_linked_list_t *list) {
|
||||
static inline void* read_node_head_double_linked_list(double_linked_list_t *list) {
|
||||
/* Sanity check. */
|
||||
if (!list || !(list->length) || !(list->head))
|
||||
return NULL;
|
||||
assert(list);
|
||||
|
||||
/* Return the data. */
|
||||
return list->head->data;
|
||||
return (list->head) ? list->head->data : NULL;
|
||||
}
|
||||
|
||||
/* This function retrieves the first node. */
|
||||
/* Returns NULL on error or empty list. */
|
||||
double_node_t* get_node_head_double_linked_list(double_linked_list_t *list) {
|
||||
static inline double_node_t* get_node_head_double_linked_list(double_linked_list_t *list) {
|
||||
/* Sanity check. */
|
||||
if (!list || !(list->length))
|
||||
return NULL;
|
||||
assert(list);
|
||||
|
||||
/* Return the data. */
|
||||
return list->head;
|
||||
}
|
||||
|
||||
/* This function deletes the first node. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
int remove_node_head_double_linked_list(double_linked_list_t *list) {
|
||||
static inline void remove_node_head_double_linked_list(double_linked_list_t *list) {
|
||||
/* Sanity check. */
|
||||
if (!list || (list->head && !(list->tail)) || (!(list->head) && list->tail))
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))));
|
||||
|
||||
/* Check if we have to do anything at all. */
|
||||
if (!(list->head))
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
|
||||
/* Split into cases. */
|
||||
if (list->length == 1L) {
|
||||
|
@ -492,7 +453,7 @@ int remove_node_head_double_linked_list(double_linked_list_t *list) {
|
|||
list->tail = NULL;
|
||||
list->length = 0L;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Length over one. */
|
||||
|
@ -508,22 +469,17 @@ int remove_node_head_double_linked_list(double_linked_list_t *list) {
|
|||
|
||||
/* Change the length. */
|
||||
(list->length)--;
|
||||
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function deletes the first node and the data thereof. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
/* If free_function is NULL, will use the stdlib's free(). */
|
||||
int remove_node_head_data_double_linked_list(double_linked_list_t *list, void (*free_function)(const void*)) {
|
||||
static inline void remove_node_head_data_double_linked_list(double_linked_list_t *list, void (*free_function)(const void*)) {
|
||||
/* Sanity check. */
|
||||
if (!list || (list->head && !(list->tail)) || (!(list->head) && list->tail))
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))));
|
||||
|
||||
/* Check if we have to do anything at all. */
|
||||
if (!(list->head))
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
|
||||
/* Split into cases. */
|
||||
if (list->length == 1L) {
|
||||
|
@ -538,7 +494,7 @@ int remove_node_head_data_double_linked_list(double_linked_list_t *list, void (*
|
|||
list->tail = NULL;
|
||||
list->length = 0L;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Length over one. */
|
||||
|
@ -558,52 +514,47 @@ int remove_node_head_data_double_linked_list(double_linked_list_t *list, void (*
|
|||
|
||||
/* Change the length. */
|
||||
(list->length)--;
|
||||
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function reads the data at the last node. */
|
||||
/* Returns NULL on error or empty list. */
|
||||
void* read_node_tail_double_linked_list(double_linked_list_t *list) {
|
||||
static inline void* read_node_tail_double_linked_list(double_linked_list_t *list) {
|
||||
/* Sanity check. */
|
||||
if (!list || !(list->length) || !(list->tail))
|
||||
return NULL;
|
||||
assert(list);
|
||||
|
||||
/* Return the data. */
|
||||
return list->tail->data;
|
||||
return (list->tail) ? list->tail->data : NULL;
|
||||
}
|
||||
|
||||
/* This function retrieves the last node. */
|
||||
/* Returns NULL on error or empty list. */
|
||||
double_node_t* get_node_tail_double_linked_list(double_linked_list_t *list) {
|
||||
static inline double_node_t* get_node_tail_double_linked_list(double_linked_list_t *list) {
|
||||
/* Sanity check. */
|
||||
if (!list || !(list->length))
|
||||
return NULL;
|
||||
assert(list);
|
||||
|
||||
/* Return the data. */
|
||||
return list->tail;
|
||||
}
|
||||
|
||||
/* This function deletes the last node. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
/* Failure is also when the list state isn't properly defined! */
|
||||
int remove_node_tail_double_linked_list(double_linked_list_t *list) {
|
||||
static inline void remove_node_tail_double_linked_list(double_linked_list_t *list) {
|
||||
/* Sanity check. */
|
||||
if (!list || !(list->length) || (list->head && !(list->tail)) || (!(list->head) && list->tail))
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))));
|
||||
|
||||
/* Local variables. */
|
||||
double_node_t *current;
|
||||
|
||||
/* Split cases. */
|
||||
/* Empty list. */
|
||||
if (!(list->length))
|
||||
return;
|
||||
/* Single node case. */
|
||||
if (list->length == 1L) {
|
||||
free(list->tail);
|
||||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
list->length = 0L;
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* General case. */
|
||||
|
@ -613,22 +564,21 @@ int remove_node_tail_double_linked_list(double_linked_list_t *list) {
|
|||
list->tail = current->previous;
|
||||
free(current);
|
||||
(list->length)--;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function deletes the last node and the data thereof. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
/* If free_function is NULL, will use the stdlib's free(). */
|
||||
int remove_node_tail_data_double_linked_list(double_linked_list_t *list, void (*free_function)(const void*)) {
|
||||
static inline void remove_node_tail_data_double_linked_list(double_linked_list_t *list, void (*free_function)(const void*)) {
|
||||
/* Sanity check. */
|
||||
if (!list || !(list->length) || (list->head && !(list->tail)) || (!(list->head) && list->tail))
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert(list && ((list->head && list->tail) || (!(list->head) && !(list->tail))));
|
||||
|
||||
/* Local variables. */
|
||||
double_node_t *current;
|
||||
|
||||
/* Split cases. */
|
||||
/* Empty list. */
|
||||
if (!(list->length))
|
||||
return;
|
||||
/* Single node case. */
|
||||
if (list->length == 1L) {
|
||||
/* Free the data. */
|
||||
|
@ -641,7 +591,7 @@ int remove_node_tail_data_double_linked_list(double_linked_list_t *list, void (*
|
|||
list->head = NULL;
|
||||
list->tail = NULL;
|
||||
list->length = 0L;
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* General case. */
|
||||
|
@ -657,20 +607,16 @@ int remove_node_tail_data_double_linked_list(double_linked_list_t *list, void (*
|
|||
list->tail = current->previous;
|
||||
free(current);
|
||||
(list->length)--;
|
||||
/* Done. */
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function deletes all the nodes of the given list and the list itself. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
int clear_list_double_linked_list(double_linked_list_t **list) {
|
||||
static inline void clear_list_double_linked_list(double_linked_list_t **list) {
|
||||
/* Sanity check. */
|
||||
if (!list || !(*list))
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
|
||||
/* Invalid state. */
|
||||
if (((*list)->head && !((*list)->tail)) || (!((*list)->head) && (*list)->tail))
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert((((*list)->head) && ((*list)->tail)) || (!((*list)->head) && !((*list)->tail)));
|
||||
|
||||
/* Variables. */
|
||||
double_node_t *current, *next;
|
||||
|
@ -680,7 +626,7 @@ int clear_list_double_linked_list(double_linked_list_t **list) {
|
|||
/* Free the list, and set the pointer. */
|
||||
free(*list);
|
||||
*list = NULL;
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* General case, free all nodes then the list. */
|
||||
|
@ -696,21 +642,18 @@ int clear_list_double_linked_list(double_linked_list_t **list) {
|
|||
/* Free the list, and set the pointer. */
|
||||
free(*list);
|
||||
*list = NULL;
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
|
||||
/* This function deletes all the nodes and data stored within of the given list and the list itself. */
|
||||
/* Returns SUCCESS_CODE_DOUBLE_LINKED_LIST_C on success, and FAILURE_CODE_DOUBLE_LINKED_LIST_C on failure. */
|
||||
/* If free_function is NULL, will use the stdlib's free(). */
|
||||
int clear_list_data_double_linked_list(double_linked_list_t **list, void (*free_function)(const void*)) {
|
||||
static inline void clear_list_data_double_linked_list(double_linked_list_t **list, void (*free_function)(const void*)) {
|
||||
/* Sanity check. */
|
||||
if (!list || !(*list))
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
|
||||
/* Invalid state. */
|
||||
if (((*list)->head && !((*list)->tail)) || (!((*list)->head) && (*list)->tail))
|
||||
return FAILURE_CODE_DOUBLE_LINKED_LIST_C;
|
||||
assert((((*list)->head) && ((*list)->tail)) || (!((*list)->head) && !((*list)->tail)));
|
||||
|
||||
/* Variables. */
|
||||
double_node_t *current, *next;
|
||||
|
@ -720,7 +663,7 @@ int clear_list_data_double_linked_list(double_linked_list_t **list, void (*free_
|
|||
/* Free the list, and set the pointer. */
|
||||
free(*list);
|
||||
*list = NULL;
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
return;
|
||||
}
|
||||
|
||||
/* General case, free all nodes then the list. */
|
||||
|
@ -741,28 +684,22 @@ int clear_list_data_double_linked_list(double_linked_list_t **list, void (*free_
|
|||
/* Free the list, and set the pointer. */
|
||||
free(*list);
|
||||
*list = NULL;
|
||||
return SUCCESS_CODE_DOUBLE_LINKED_LIST_C;
|
||||
}
|
||||
|
||||
/* This function attempts to serialize a doubly-linked list into an array. */
|
||||
/* Note that the array has to be allocated by the caller. */
|
||||
/* The array setting function is used to set the values at an index, takes the pointer to the array, index and value to put. */
|
||||
void *serialize_double_linked_list(double_linked_list_t *list, void (*array_setting_function)(void*, size_t, void*), void *array) {
|
||||
static inline void *serialize_double_linked_list(double_linked_list_t *list, void (*array_setting_function)(void*, size_t, void*), void *array) {
|
||||
/* Local variables. */
|
||||
double_node_t *current;
|
||||
size_t i = 0L;
|
||||
|
||||
/* Sanity check. */
|
||||
if (!list || !(list->head) || list->length <= 0 || !array || !array_setting_function)
|
||||
return NULL;
|
||||
assert(list && (list->head) && array && array_setting_function);
|
||||
|
||||
/* Loop and add the elements. */
|
||||
for (current = list->head; current; i++) {
|
||||
/* Set the ith value. */
|
||||
for (current = list->head; current; i++, current = current->next)
|
||||
array_setting_function(array, i, current->data);
|
||||
/* Advance the pointer. */
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
/* Return the result. */
|
||||
return array;
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
#ifndef DOUBLE_LINKED_LIST_H
|
||||
#define DOUBLE_LINKED_LIST_H
|
||||
#include "../nodes/double_node.h"
|
||||
/* Include assert.h to allow code generation, but only run with debug flag. */
|
||||
#ifndef DEBUG
|
||||
#define NDEBUG
|
||||
#endif /* DEBUG. */
|
||||
#include <assert.h>
|
||||
|
||||
/* Constants. */
|
||||
/* Function errror/return code on success. */
|
||||
|
@ -46,49 +51,49 @@ typedef struct double_linked_list {
|
|||
} double_linked_list_t;
|
||||
|
||||
/* This function initializes a new linked list. */
|
||||
double_linked_list_t* initialize_double_linked_list();
|
||||
static inline double_linked_list_t* initialize_double_linked_list();
|
||||
/* This function appends a node to the given linked list. */
|
||||
int append_node_double_linked_list(double_linked_list_t *list, double_node_t *node);
|
||||
static inline void append_node_double_linked_list(double_linked_list_t *list, double_node_t *node);
|
||||
/* This function prepends a node the the given linked list. */
|
||||
int prepend_node_double_linked_list(double_linked_list_t *list, double_node_t *node);
|
||||
static inline void prepend_node_double_linked_list(double_linked_list_t *list, double_node_t *node);
|
||||
/* This function creates and appends a node to the given linked list. */
|
||||
int append_node_data_double_linked_list(double_linked_list_t *list, void *data);
|
||||
static inline int append_node_data_double_linked_list(double_linked_list_t *list, void *data);
|
||||
/* This function creates and prepends a node to the given linked list. */
|
||||
int prepend_node_data_double_linked_list(double_linked_list_t *list, void *data);
|
||||
static inline int prepend_node_data_double_linked_list(double_linked_list_t *list, void *data);
|
||||
/* This function inserts a node at the ith place. */
|
||||
int add_node_i_double_linked_list(double_linked_list_t *list, double_node_t *node, size_t i);
|
||||
static inline void add_node_i_double_linked_list(double_linked_list_t *list, double_node_t *node, size_t i);
|
||||
/* This function creates and inserts a node at the ith place. */
|
||||
int add_node_data_i_double_linked_list(double_linked_list_t *list, void *data, size_t i);
|
||||
static inline int add_node_data_i_double_linked_list(double_linked_list_t *list, void *data, size_t i);
|
||||
/* This function reads the data at the ith node. */
|
||||
void* read_node_i_double_linked_list(double_linked_list_t *list, size_t i, int *error);
|
||||
static inline void* read_node_i_double_linked_list(double_linked_list_t *list, size_t i);
|
||||
/* This function retrieves a pointer to the ith node. */
|
||||
double_node_t* get_node_i_double_linked_list(double_linked_list_t *list, size_t i, int *error);
|
||||
static inline double_node_t* get_node_i_double_linked_list(double_linked_list_t *list, size_t i);
|
||||
/* This function attempts to find the index of a given node, by pointer. */
|
||||
size_t get_node_index_pointer_double_linked_list(double_linked_list_t *list, double_node_t *node);
|
||||
static inline size_t get_node_index_pointer_double_linked_list(double_linked_list_t *list, double_node_t *node);
|
||||
/* This function deletes the ith node. */
|
||||
int remove_node_i_double_linked_list(double_linked_list_t *list, size_t i);
|
||||
static inline void remove_node_i_double_linked_list(double_linked_list_t *list, size_t i);
|
||||
/* This function deletes the ith node and the data stored within. */
|
||||
int remove_node_i_data_double_linked_list(double_linked_list_t *list, size_t i, void (*free_function)(const void*));
|
||||
static inline void remove_node_i_data_double_linked_list(double_linked_list_t *list, size_t i, void (*free_function)(const void*));
|
||||
/* This function reads the data at the first node. */
|
||||
void* read_node_head_double_linked_list(double_linked_list_t *list);
|
||||
static inline void* read_node_head_double_linked_list(double_linked_list_t *list);
|
||||
/* This function retrieves the first node. */
|
||||
double_node_t* get_node_head_double_linked_list(double_linked_list_t *list);
|
||||
static inline double_node_t* get_node_head_double_linked_list(double_linked_list_t *list);
|
||||
/* This function deletes the first node. */
|
||||
int remove_node_head_double_linked_list(double_linked_list_t *list);
|
||||
static inline void remove_node_head_double_linked_list(double_linked_list_t *list);
|
||||
/* This function deletes the first node and the data thereof. */
|
||||
int remove_node_head_data_double_linked_list(double_linked_list_t *list, void (*free_function)(const void*));
|
||||
static inline void remove_node_head_data_double_linked_list(double_linked_list_t *list, void (*free_function)(const void*));
|
||||
/* This function reads the data at the last node. */
|
||||
void* read_node_tail_double_linked_list(double_linked_list_t *list);
|
||||
static inline void* read_node_tail_double_linked_list(double_linked_list_t *list);
|
||||
/* This function retrieves the last node. */
|
||||
double_node_t* get_node_tail_double_linked_list(double_linked_list_t *list);
|
||||
static inline double_node_t* get_node_tail_double_linked_list(double_linked_list_t *list);
|
||||
/* This function deletes the last node. */
|
||||
int remove_node_tail_double_linked_list(double_linked_list_t *list);
|
||||
static inline void remove_node_tail_double_linked_list(double_linked_list_t *list);
|
||||
/* This function deletes the last node and the data thereof. */
|
||||
int remove_node_tail_data_double_linked_list(double_linked_list_t *list, void (*free_function)(const void*));
|
||||
static inline void remove_node_tail_data_double_linked_list(double_linked_list_t *list, void (*free_function)(const void*));
|
||||
/* This function deletes all the nodes of the given list and the list itself. */
|
||||
int clear_list_double_linked_list(double_linked_list_t **list);
|
||||
static inline void clear_list_double_linked_list(double_linked_list_t **list);
|
||||
/* This function deletes all the nodes and data stored within of the given list and the list itself. */
|
||||
int clear_list_data_double_linked_list(double_linked_list_t **list, void (*free_function)(const void*));
|
||||
static inline void clear_list_data_double_linked_list(double_linked_list_t **list, void (*free_function)(const void*));
|
||||
/* This function serializes the list, it relies on an array setting function and an allocated array/buffer. */
|
||||
static inline void *serialize_double_linked_list(double_linked_list_t *list, void (*array_setting_function)(void*, size_t, void*), void *array);
|
||||
#endif /* DOUBLE_LINKED_LIST_H */
|
||||
|
|
|
@ -81,23 +81,13 @@ double_linked_list_t* generate_long_random_list(int length) {
|
|||
return NULL;
|
||||
}
|
||||
/* Attempt to append. */
|
||||
if (!append_node_double_linked_list(list, current)) {
|
||||
free(current->data);
|
||||
free(current);
|
||||
free(list);
|
||||
return NULL;
|
||||
}
|
||||
append_node_double_linked_list(list, current);
|
||||
|
||||
/* Loop and add the rest. */
|
||||
for (i = 1; i < length; i++) {
|
||||
/* Generate and attempt to append. */
|
||||
current = generate_random_node();
|
||||
if (!append_node_double_linked_list(list, current)) {
|
||||
/* Abort. */
|
||||
free(current->data);
|
||||
free(current);
|
||||
clear_list_data_double_linked_list(&list, NULL);
|
||||
return NULL;
|
||||
}
|
||||
append_node_double_linked_list(list, current);
|
||||
}
|
||||
|
||||
/* Update the list's length. */
|
||||
|
|
Loading…
Reference in New Issue