#include "../h/cdefs.h"
#include "linkedList.h"

extern void *malloc();
ListElem *freeElems;

ListElem *listLinkAfter(list, p, ptr)
ListDesc *list;
ListElem *p;
void *ptr;
{
	/* Create an element for 'ptr' and link it into the 'list'
	   after the element 'p'. If p is NULL, then the element
	   will be linked in at the list head. */

	ListElem *e;

	if (!(e = freeElems))
	 { e = (ListElem*)malloc(sizeof(ListElem));
	 }
	else
	 { freeElems = e->next;
	 }
	if (p)
	 { if (p->next)
	    { p->next->prev = e;
	    }
	   else
	    { list->tail = e;
	    }
	   e->next = p->next;
	   p->next = e;
	 }
	else
	 { if (list->head)
	    { list->head->prev = e;
	    }
	   else
	    { list->tail = e;
	    }
	   e->next = list->head;
	   list->head = e;
	 }
	e->prev = p;
	e->ptr = ptr;
	return (e);
}

ListElem *listLinkBefore(list, p, ptr)
ListDesc *list;
ListElem *p;
void *ptr;
{
	/* Create an element for 'ptr' and link it into the 'list'
	   before the element 'p'. If p is NULL, then the element
	   will be linked in at the list tail. */

	ListElem *e;

	if (!(e = freeElems))
	 { e = (ListElem*)malloc(sizeof(ListElem));
	 }
	else
	 { freeElems = e->next;
	 }
	if (p)
	 { if (p->prev)
	    { p->prev->next = e;
	    }
	   else
	    { list->head = e;
	    }
	   e->prev = p->prev;
	   p->prev = e;
	 }
	else
	 { if (list->tail)
	    { list->tail->next = e;
	    }
	   else
	    { list->head = e;
	    }
	   e->prev = list->tail;
	   list->tail = e;
	 }
	e->next = p;
	e->ptr = ptr;
	return (e);
}

listUnlink(list, e)
ListDesc *list;
ListElem *e;
{
	/* Unlink the element 'e' from the 'list'. */

	if (e->prev)
	 { e->prev->next = e->next;
	 }
	else
	 { list->head = e->next;
	 }
	if (e->next)
	 { e->next->prev = e->prev;
	 }
	else
	 { list->tail = e->prev;
	 }
	e->next = freeElems;
	freeElems = e;
}

ListElem *listGetFirst(list, ptr)
ListDesc *list;
void *ptr;
{
	/* return the first element in 'list' which refers to 'ptr'. */
	ListElem *e;

	for (e=list->head; e; e=e->next)
	 { if (e->ptr == ptr)
	    { return (e);
	    }
	 }
	return (0);
}

ListElem *listGetLast(list, ptr)
ListDesc *list;
void *ptr;
{
	/* return the last element in 'list' which refers to 'ptr'. */
	ListElem *e;

	for (e=list->tail; e; e=e->prev)
	 { if (e->ptr == ptr)
	    { return (e);
	    }
	 }
	return (0);
}
