/*
Library: chain
Created: 22.10.2001
Author : Peter Turczak <p_turczak@wiwa.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "chain.h"
#include <stdio.h>
#include <stdlib.h>
struct element* newchain()
{
struct element *newe;
newe=malloc(sizeof(element));
newe->next=NULL;
newe->prev=NULL;
newe->cur=NULL;
newe->head=newe;
return(newe);
}
struct element* addelement(void *newp, int size, struct element* chain)
{
struct element* newe;
void* temp;
newe=malloc(sizeof(element));
newe->prev=chain;
temp=chain->next;
chain->next=newe;
newe->next=temp;
newe->cur=malloc(size);
memcpy(newe->cur,newp,size);
if (newe->prev!=NULL)
newe->head=newe->prev->head;
else
newe->head=newe->next->head;
return(newe);
}
struct element* addelement_nocpy(void *newp, struct element* chain)
{
struct element* newe;
void* temp;
newe=malloc(sizeof(element));
newe->prev=chain;
temp=chain->next;
chain->next=newe;
newe->next=temp;
newe->cur=newp;
if (newe->prev!=NULL)
newe->head=newe->prev->head;
else
newe->head=newe->next->head;
return(newe);
}
struct element* unchain(struct element *chain)
{
struct element *tmp1;
struct element *tmp2;
tmp1=chain->prev; // Backup the two elements
tmp2=chain->next; // on the left and right
if (chain->cur!=NULL)
free(chain->cur); // Kill the content
free(chain); // Kill the chain element
if (tmp1!=NULL)
tmp1->next=tmp2; // Close the chain again
if (tmp2!=NULL)
tmp2->prev=tmp1; // (Cross-over the pointers..)
if (tmp1!=NULL)
return(tmp1); // Return the left value...
else
return(tmp2);
}
struct element* unchain_nofree(struct element *chain)
{
struct element *tmp1;
struct element *tmp2;
tmp1=chain->prev; // Backup the two elements
tmp2=chain->next; // on the left and right
free(chain); // Kill the chain element
if (tmp1!=NULL)
tmp1->next=tmp2; // Close the chain again
if (tmp2!=NULL)
tmp2->prev=tmp1; // (Cross-over the pointers..)
if (tmp1!=NULL)
return(tmp1); // Return the left value...
else
return(tmp2);
}
struct element* head(struct element *chain)
{
struct element *tmp;
/*
tmp=chain;
while (tmp->prev!=NULL)
{
tmp=tmp->prev;
}
*/
tmp=chain->head;
return(tmp);
}
struct element* tail(struct element *chain)
{
struct element *tmp;
tmp=chain;
while (tmp->next!=NULL)
{
tmp=tmp->next;
}
return(tmp);
}
void clearlst(struct element *chain)
{
struct element *tmp;
tmp=head(chain);
while (tmp->next!=NULL)
{
tmp=unchain(tmp);
}
unchain(tmp);
}
struct element* e_next(struct element *chain)
{
return(chain->next);
}
struct element* e_prev(struct element *chain)
{
return(chain->prev);
}
struct element* movelement(struct element *from, struct element *to)
{
addelement_nocpy(from->cur, to);
return(unchain_nofree(from));
}
int chainlen(struct element *chain)
{
struct element *e=head(chain);
int r=0;
while(e->next!=NULL)
{
e=e->next;
r++;
}
return(r);
}
struct element* r_next(struct element *chain)
{
struct element *r=NULL;
if (chain!=NULL)
{
r=(chain->next==NULL)?chain->head:chain->next;
}
return(r);
}
struct element* r_prev(struct element *chain)
{
struct element *r=NULL;
if (chain!=NULL)
{
r=(chain->prev==NULL)?tail(chain):chain->prev;
}
return(r);
}
syntax highlighted by Code2HTML, v. 0.9.1