/* Library: chain Created: 22.10.2001 Author : Peter Turczak 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 #include 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); }