2016-12-29 15:09:39 +00:00
|
|
|
/*
|
|
|
|
* This is a cellular automaton library
|
|
|
|
*
|
|
|
|
* Copyright (C) 2016-2017 Antoine BARTUCCIO, Jean POREE DE RIDDER
|
|
|
|
*
|
|
|
|
* Licensed under the MIT License,(the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
* hhttps://opensource.org/licenses/MIT
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
* SOFTWARE.
|
|
|
|
*
|
|
|
|
*/
|
2016-12-10 01:28:10 +00:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
2016-12-10 04:04:13 +00:00
|
|
|
#include <CellElement.h>
|
2016-12-10 01:28:10 +00:00
|
|
|
#include <list.h>
|
|
|
|
|
|
|
|
#define SUCCESS 0
|
|
|
|
#define FAILURE 1
|
|
|
|
|
|
|
|
List * CreateList() {
|
|
|
|
List *list = malloc(sizeof(*list));
|
|
|
|
|
|
|
|
if(list != NULL){
|
|
|
|
list->head = NULL;
|
|
|
|
list->tail = NULL;
|
|
|
|
list->size = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
|
|
|
int unshift(List *list, cellElement *data){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
|
|
|
|
/* Create a new element */
|
|
|
|
|
|
|
|
ListElement *newElement = malloc(sizeof(*newElement));
|
2016-12-11 00:25:35 +00:00
|
|
|
if (list != NULL && newElement != NULL){
|
|
|
|
newElement->data = data;
|
2016-12-23 13:08:10 +00:00
|
|
|
newElement->pos = -1;
|
2016-12-10 01:28:10 +00:00
|
|
|
|
|
|
|
/* Insert the element at the begining of the list */
|
|
|
|
|
|
|
|
newElement->previous = NULL;
|
|
|
|
|
|
|
|
if (list->head != NULL){
|
|
|
|
list->head->previous = newElement;
|
|
|
|
} else {
|
|
|
|
list->tail = newElement;
|
|
|
|
}
|
|
|
|
newElement->next = list->head;
|
|
|
|
|
|
|
|
list->head = newElement;
|
|
|
|
list->size = list->size + 1;
|
|
|
|
} else {
|
|
|
|
if (newElement != NULL){
|
|
|
|
free(newElement);
|
|
|
|
}
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
int push(List *list, cellElement *data){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
|
|
|
|
ListElement *newElement = malloc(sizeof(*newElement));
|
2016-12-11 00:25:35 +00:00
|
|
|
if(list != NULL && newElement != NULL){
|
|
|
|
newElement->data = data;
|
2016-12-23 13:08:10 +00:00
|
|
|
newElement->pos = -1;
|
2016-12-10 01:28:10 +00:00
|
|
|
newElement->next = NULL;
|
|
|
|
if (list->tail == NULL){
|
|
|
|
list->tail = newElement;
|
|
|
|
list->head = newElement;
|
|
|
|
newElement->previous = NULL;
|
|
|
|
} else {
|
|
|
|
newElement->previous = list->tail;
|
|
|
|
list->tail->next = newElement;
|
|
|
|
list->tail = newElement;
|
|
|
|
}
|
|
|
|
list->size = list->size + 1;
|
|
|
|
} else {
|
|
|
|
if (newElement != NULL){
|
|
|
|
free(newElement);
|
|
|
|
}
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
ListElement * GetElement(List *list, int nb){
|
|
|
|
ListElement *current = NULL;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (list != NULL && (nb < list->size || -nb < list->size)){
|
|
|
|
if (nb == list->size -1 || nb == -1){
|
|
|
|
current = list->tail;
|
|
|
|
} else if (nb == 0){
|
|
|
|
current = list->head;
|
|
|
|
} else if (nb <= (list->size - 1)/2 && nb > 0){
|
|
|
|
i = 0;
|
|
|
|
current = list->head;
|
|
|
|
while(i<nb){
|
|
|
|
current = current->next;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
i = list->size - 1;
|
|
|
|
if (nb < 0){
|
|
|
|
nb = list->size + nb -1;
|
|
|
|
}
|
|
|
|
while(i>nb){
|
|
|
|
current = current->previous;
|
|
|
|
i = i - 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return current;
|
|
|
|
}
|
|
|
|
|
|
|
|
int PopPtnList(List *list, ListElement *element){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
|
|
|
|
if (list != NULL && element != NULL){
|
|
|
|
if (list->head == element && list->tail == element){
|
|
|
|
list->head = NULL;
|
|
|
|
list->tail = NULL;
|
|
|
|
} else if (list->head == element){
|
|
|
|
list->head = element->next;
|
|
|
|
element->previous = NULL;
|
|
|
|
} else if (list->tail == element){
|
|
|
|
list->tail = element->previous;
|
|
|
|
element->previous->next = NULL;
|
|
|
|
} else {
|
|
|
|
element->next->previous = element->previous;
|
|
|
|
element->previous->next = element->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (element->data != NULL){
|
2016-12-10 04:04:13 +00:00
|
|
|
FreeCellElement(element->data);
|
2016-12-10 01:28:10 +00:00
|
|
|
}
|
|
|
|
free(element);
|
|
|
|
list->size = list->size - 1;
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
int RemoveElement(List *list, int nb){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
ListElement *toDelete = GetElement(list, nb);
|
|
|
|
|
|
|
|
if (toDelete != NULL){
|
|
|
|
ok = PopPtnList(list, toDelete);
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
int shift(List *list){
|
|
|
|
return RemoveElement(list, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int pop(List *list){
|
|
|
|
return RemoveElement(list, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int DeleteListContent(List *list){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
ListElement * current = NULL;
|
|
|
|
ListElement * toDelete = NULL;
|
|
|
|
|
|
|
|
if (list != NULL){
|
|
|
|
current = list->head;
|
|
|
|
while (current != NULL){
|
|
|
|
toDelete = current;
|
|
|
|
current = current->next;
|
2016-12-25 23:06:54 +00:00
|
|
|
/*
|
2016-12-10 01:28:10 +00:00
|
|
|
if (toDelete->data != NULL){
|
2016-12-10 04:04:13 +00:00
|
|
|
FreeCellElement(toDelete->data);
|
2016-12-10 01:28:10 +00:00
|
|
|
}
|
2016-12-25 23:06:54 +00:00
|
|
|
*/
|
2016-12-10 04:04:13 +00:00
|
|
|
free(toDelete);
|
2016-12-10 01:28:10 +00:00
|
|
|
}
|
|
|
|
list->head = NULL;
|
|
|
|
list->tail = NULL;
|
|
|
|
list->size = 0;
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
int FreeList(List *list){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
|
|
|
|
if (list != NULL){
|
|
|
|
ok = DeleteListContent(list);
|
|
|
|
if (ok == SUCCESS){
|
|
|
|
free(list);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
2016-12-23 13:08:10 +00:00
|
|
|
|
|
|
|
ListElement * GetElementPos(List *list, int pos){
|
|
|
|
ListElement * el = list->head;
|
|
|
|
while (el != NULL && el->pos != pos){
|
|
|
|
el = el->next;
|
|
|
|
}
|
|
|
|
return el;
|
|
|
|
}
|
|
|
|
|
|
|
|
int RemoveElementPos(List *list, int pos){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
ListElement *toDelete = GetElementPos(list, pos);
|
|
|
|
|
|
|
|
if (toDelete != NULL){
|
|
|
|
ok = PopPtnList(list, toDelete);
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
int InsertBeforeElement(List *list, ListElement *eli, ListElement *elp){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
|
|
|
|
if (list != NULL){
|
|
|
|
if (elp->previous == NULL){
|
|
|
|
eli->next = elp;
|
|
|
|
eli->previous = NULL;
|
|
|
|
elp->previous = eli;
|
|
|
|
} else {
|
|
|
|
eli->next = elp;
|
|
|
|
eli->previous = elp->previous;
|
|
|
|
elp->previous->next = eli;
|
|
|
|
elp->previous = eli;
|
|
|
|
}
|
|
|
|
list->size = list->size + 1;
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
int InsertAfterElement(List *list, ListElement *eli, ListElement *elb){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
|
|
|
|
if (list != NULL){
|
|
|
|
if (elb->next == NULL){
|
|
|
|
eli->next = NULL;
|
|
|
|
eli->previous = elb;
|
|
|
|
elb->next = eli;
|
|
|
|
} else {
|
|
|
|
eli->previous = elb;
|
|
|
|
eli->next=elb->next;
|
|
|
|
elb->next->previous = eli;
|
|
|
|
elb->next = eli;
|
|
|
|
}
|
|
|
|
list->size = list->size + 1;
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
int InsertBefore(List *list, cellElement *data, int nb){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
ListElement *newElement = NULL;
|
|
|
|
ListElement *eli = GetElement(list, nb);
|
|
|
|
if (eli != NULL){
|
|
|
|
newElement = malloc(sizeof(*newElement));
|
|
|
|
if (newElement != NULL){
|
|
|
|
newElement->pos = -1;
|
|
|
|
newElement->data = data;
|
|
|
|
ok = InsertBeforeElement(list, newElement, eli);
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
int InsertAfter(List *list, cellElement *data, int nb){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
ListElement *newElement = NULL;
|
|
|
|
ListElement *elb = GetElement(list, nb);
|
|
|
|
if (elb != NULL){
|
|
|
|
newElement = malloc(sizeof(*newElement));
|
|
|
|
if (newElement != NULL){
|
|
|
|
newElement->pos = -1;
|
|
|
|
newElement->data = data;
|
|
|
|
ok = InsertAfterElement(list, newElement, elb);
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
int InsertBeforePos(List *list, cellElement *data, int pos){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
ListElement *newElement = NULL;
|
|
|
|
ListElement *eli = GetElementPos(list, pos);
|
|
|
|
if (eli != NULL){
|
|
|
|
newElement = malloc(sizeof(*newElement));
|
|
|
|
if (newElement != NULL){
|
|
|
|
newElement->pos = -1;
|
|
|
|
newElement->data = data;
|
|
|
|
ok = InsertBeforeElement(list, newElement, eli);
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
int InsertAfterPos(List *list, cellElement *data, int pos){
|
|
|
|
int ok = SUCCESS;
|
|
|
|
ListElement *newElement = NULL;
|
|
|
|
ListElement *elb = GetElementPos(list, pos);
|
|
|
|
if (elb != NULL){
|
|
|
|
newElement = malloc(sizeof(*newElement));
|
|
|
|
if (newElement != NULL){
|
|
|
|
newElement->pos = -1;
|
|
|
|
newElement->data = data;
|
|
|
|
ok = InsertAfterElement(list, newElement, elb);
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ok = FAILURE;
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|