/*
 * Copyright (c) 1993,1991,1990,1996  Arizona Board of Regents
 *
 * $RCSfile: scout_queue.c,v $
 *
 * HISTORY
 * $Log: scout_queue.c,v $
 * Revision 1.2  1997/04/29 22:52:26  rrp
 * minor changes from linux port
 *
 * Revision 1.1  1997/01/28  22:50:41  rrp
 * Initial revision
 *
 * Revision 1.1  1996/10/02 13:41:38  davidm
 * Initial revision
 *
 */
/*
 * General queue manager.  It is not safe for asynchronous usage.
 */
#include "xk_assert.h"
#include "scout_queue.h"


void
queueInit (Queue q)
{
    q->head = q->tail = 0;
}


void
queueAppend(Queue q, void * element)
{
    QueueEl el = element;

    xAssert(element);

    el->next = 0;
    if (q->tail) {
	q->tail->next = el;
    }
    q->tail = el;
    if (!q->head) {
	q->head = el;
    }
}


void
queueInsert(Queue q, void * afterElement, void * element)
{
    QueueEl after = afterElement;
    QueueEl el = element;

    xAssert(element && afterElement);
    if (after) {
	el->next = after->next;
	after->next = el;
	if (q->tail == after) {
	    q->tail = el;
	}
    } else {
	/* insert at head of queue: */
	if (q->head) {
	    el->next = q->head->next;
	}
	q->head = el;
	if (!q->tail) {
	    q->tail = el;
	}
    }
}


void *
queueRemove (Queue q)
{
    QueueEl el;

    if (!q->head) {
	/* cannot remove from empty queue: */
	return 0;
    }
    el = q->head;
    q->head = el->next;

    if (!q->head) {
	q->tail = 0;
    }
    return el;
}


void
queueDelete(Queue q, void * afterElement)
{
    QueueEl after = afterElement;
    QueueEl el;

    xAssert(afterElement);
    if (after) {
	el = after->next;
	if (el) {
	    after->next = el->next;
	    if (q->tail == el) {
		q->tail = after;
	    }
	}
    } else {
	/* remove first element in queue: */
	if (q->head) {
	    q->head = q->head->next;
	    if (!q->head) {
		q->tail = 0;
	    }
	}
    }
}

QueueEl
queueHead (Queue q)
{
    return q->head;
}

QueueEl
queueTail (Queue q)
{
    return q->tail;
}
