OpenFPGA/vpr7_x2p/libarchfpgavpr7/SRC/linkedlist.c

201 lines
4.3 KiB
C

/**
* Filename : linkedlist.c
* Author : Xifan TANG, EPFL
* Description : Define most useful functions for a general purpose linked list
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "util.h"
/* Data structures*/
#include "linkedlist.h"
/**
* Create, insert, delete, cat
* General purpose linked list
*/
/**
* Create fixed length of Linked list
* Node struct must have a pointor named after "next"!
*/
t_llist* create_llist(int len) {
t_llist* head;
t_llist* tmp_head;
int ind;
/* Create a scout, this is a blank node*/
head = (t_llist*)my_malloc(sizeof(t_llist));
head->next = NULL;
for (ind=0; ind<(len-1); ind++) {
/* Create a node ahead of the current*/
tmp_head = (t_llist*)my_malloc(sizeof(t_llist));
tmp_head->next = head;
head = tmp_head;
}
return head;
}
/**
* Insert a node inside the linked list
* Cur is pointer which a new node will be inserted after.
* If Cur is a NULL pointer, we create a linked-list head
* If Cur is not NULL, we add a node after the tail of linked-list
*/
t_llist* insert_llist_node(t_llist* cur) {
t_llist* cur_next;
/* Store the current next*/
cur_next = cur->next;
/* Allocate new node*/
cur->next = (t_llist*)my_malloc(sizeof(t_llist));
/* Configure the new node*/
cur->next->next = cur_next;
return cur->next;
}
/**
* Insert a node inside the linked list
* The inserted node will be before the old head, becoming the new head
*/
t_llist* insert_llist_node_before_head(t_llist* old_head) {
/* Allocate new node*/
t_llist* new_head = (t_llist*)my_malloc(sizeof(t_llist));
/* Store the current next*/
new_head->next = old_head;
return new_head;
}
/**
* Romove a node from linked list
* cur is the node whose next node is to be removed
*/
void remove_llist_node(t_llist* cur) {
t_llist* rm_node = cur->next;
/* Connect the next next node*/
cur->next = cur->next->next;
/* free the node*/
free(rm_node);
}
/**
* Cat the linked list
* head2 is connected to the tail of head1
* return head1
*/
t_llist* cat_llists(t_llist* head1,
t_llist* head2) {
t_llist* tmp = head1;
/* Reach the tail of head1*/
while(tmp->next != NULL) {
tmp = tmp->next;
}
/* Cat*/
tmp->next = head2->next;
/* Free head2*/
free(head2);
return head1;
}
t_llist* search_llist_tail(t_llist* head) {
t_llist* temp = head;
if (NULL == temp) {
return temp;
}
while(temp->next != NULL) {
temp = temp->next;
}
return temp;
}
int find_length_llist(t_llist* head) {
int length = 0;
t_llist* temp = head;
if (NULL == temp) {
/* A NULL head means zero length */
return length;
} else {
/* Otherwise, we have already one element */
length++;
}
while (temp->next != NULL) {
length++;
temp = temp->next;
}
return length;
}
/* Search the linked list and check if dptr has been stored in a node */
boolean check_dptr_exist_in_llist(t_llist* head, void* data_ptr) {
t_llist* temp = head;
if (NULL == temp) {
/* A NULL head means zero length */
return FALSE;
}
while (temp != NULL) {
if (data_ptr == temp->dptr) {
return TRUE;
}
temp = temp->next;
}
return FALSE;
}
/* Free a linked list, Make sure before this function,
* the dptr has been freed! I cannot free them here!!!
*/
void free_llist(t_llist* head) {
t_llist* temp = head;
t_llist* node_to_free = NULL;
/* From the head to tail,
* free each linked node and move on to the next
*/
while(temp) { /*Until we reach the tail, which is a null pointer*/
if (NULL != temp->dptr) {
printf("ERROR: The data pointer in linked list is not NULL!\n");
printf(" It is possible that the data pointer is not freed!\n");
exit(1);
}
/* Store the current node to be freed*/
node_to_free = temp;
/* Move on to the next*/
temp = temp->next;
/* Now it is time to free*/
free(node_to_free);
}
return;
}
/* Reverse a linked list and return the new head */
t_llist* reverse_llist(t_llist* head) {
t_llist* temp = head;
t_llist* next = NULL;
t_llist* last = NULL; /* pointor to the last-visited llist node */
while (NULL != temp) {
/* Modify the next pointor of current node */
next = temp->next;
temp->next = last;
/* Update the last node */
last = temp;
/* Go to next */
temp = next;
}
return last;
}