/* viDOOM - level editor for DOOM Copyright (C) 2000 Ian Cowburn (ianc@noddybox.demon.co.uk) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ------------------------------------------------------------------------- Provides a double linked list */ static const char rcs_id[]="$Id$"; #include "config.h" #include #include #include "list.h" #include "mem.h" struct VIDOOM_Elem { char *data; struct VIDOOM_Elem *next; struct VIDOOM_Elem *prev; }; struct VIDOOM_List { int no; int size; struct VIDOOM_Elem *head; struct VIDOOM_Elem *tail; }; struct VIDOOM_Iterator { List l; struct VIDOOM_Elem *e; }; /* ---------------------------------------- */ List ListNew(int type_size) { List nl; nl=Grab(sizeof(struct VIDOOM_List)); nl->no=0; nl->size=type_size; nl->head=NULL; nl->tail=NULL; return(nl); } List ListClear(List l) { struct VIDOOM_Elem *e,*d; if (l) { e=l->head; while(e) { d=e; e=e->next; Release(d->data); Release(d); } Release(l); } return(NULL); } List ListEmpty(List l) { struct VIDOOM_Elem *e,*d; if (l) { e=l->head; while(e) { d=e; e=e->next; Release(d->data); Release(d); } l->no=0; l->head=NULL; l->tail=NULL; } return(l); } int ListSize(List l) { if (l) return(l->no); else return(0); } Iterator ListIterator(List l) { struct VIDOOM_Iterator *i; if (!l->head) return(NULL); i=Grab(sizeof(struct VIDOOM_Iterator)); i->l=l; i->e=l->head; return(i); } Iterator IteratorClear(Iterator i) { if (i) Release(i); return(NULL); } void *IteratorData(Iterator i) { if (i) return(i->e->data); else return(NULL); } Iterator IteratorNext(Iterator i) { if (i) if (!(i->e=i->e->next)) { Release(i); i=NULL; } return(i); } Iterator IteratorPrev(Iterator i) { if (i) if (!(i->e=i->e->prev)) { Release(i); i=NULL; } return(i); } Iterator IteratorUpdate(Iterator i,void *data) { if (i) { Release(i->e->data); i->e->data=Copy(data,i->l->size); } return(i); } Iterator IteratorDelete(Iterator i) { struct VIDOOM_Elem *e; e=i->e; i->e=i->e->next; i->l->no--; if (e==i->l->head) i->l->head=e->next; if (e==i->l->tail) i->l->tail=e->prev; if (e->next) e->next->prev=e->prev; if (e->prev) e->prev->next=e->next; Release(e->data); Release(e); if (!(i->e)) { Release(i); i=NULL; } return(i); } void ListAppend(List l,void *data) { struct VIDOOM_Elem *e; e=Grab(sizeof(struct VIDOOM_Elem)); e->next=NULL; e->prev=l->tail; e->data=Copy(data,l->size); l->no++; if (l->head) { l->tail->next=e; l->tail=e; } else l->head=l->tail=e; } void ListInsert(List l,void *data) { struct VIDOOM_Elem *e; e=Grab(sizeof(struct VIDOOM_Elem)); e->prev=NULL; e->next=l->head; e->data=Copy(data,l->size); l->no++; if (l->head) { l->head->prev=e; l->head=e; } else l->head=l->tail=e; } Iterator ListFindElem(List l,int (*pred)(void *, void *),void *data) { Iterator i; struct VIDOOM_Elem *e; i=NULL; e=l->head; while((e)&&(!i)) { if ((*pred)(e->data,data)) { i=ListIterator(l); i->e=e; } e=e->next; } return(i); } /* END OF FILE */