/*
 * Amiga Exec-type list support for UNIX
 *
 * Copyright (c) 1993 by Ezra Story.  All rights reserved.  Permission to
 * copy this program is given provided that the copy is not sold and that
 * this copyright notice is included.
 *
 */
static char rcsid[] = "$Id: lists.c 1.2 1994/06/06 22:38:20 Ezra_Story Exp $";

#include <sys/types.h>
#include "lists.h"

/* prepare a list for use */
NewList(l)
LIST *l;
{
    l->Head = (NODE *)(&l->Tail);
    l->Tail = (NODE *)0;
    l->TailPred = (NODE *)l;
}

/* add a node to the end of a list */
AddTail(l,n)
LIST *l;
NODE *n;
{
    n->Succ = (NODE *)(&l->Tail);
    n->Pred = l->TailPred;
    l->TailPred = n;
    n->Pred->Succ = n;
}

/* add node to the beginning of a list */
AddHead(l,n)
LIST *l;
NODE *n;
{
    n->Succ = l->Head;
    n->Pred = (NODE *)l;
    n->Succ->Pred = n;
    l->Head = n;
}

/* insert node after node "pn" in list "l" */
/* if pn == 0, insert at head of list      */
Insert(l,n,pn)
LIST *l;
NODE *n,*pn;
{
    if (pn == 0) pn = (NODE *)l;

    n->Succ = pn->Succ;
    n->Pred = pn;
    n->Succ->Pred = n;
    pn->Succ = n;
}

/* remove node from head of list */
/* returns ptr to node removed, or 0 if no node */
NODE *
RemHead(l)
LIST *l;
{
    NODE *n;

    if (IsListEmpty(l)) return(0);
    n = l->Head;
    Remove(n);
    return(n);
}

/* remove node from end of list */
/* returns ptr to node or 0 is list is empty */
NODE *
RemTail(l)
LIST *l;
{
    NODE *n;

    if (IsListEmpty(l)) return(0);

    n = l->TailPred;
    Remove(n);
    return(n);
}

/* removes node from the list it's in */
Remove(n)
NODE *n;
{
    n->Succ->Pred = n->Pred;
    n->Pred->Succ = n->Succ;
}

/* adds node to list in priority order                 */
/* node is added before first node of a lower priority */
Enqueue(l,n)
LIST *l;
NODE *n;
{
    NODE *sn;

    if (IsListEmpty(l))
        {
        AddHead(l,n);
        return;
        }

    for (sn = l->Head; sn->Succ  ; sn = sn->Succ)
        if (sn->Pri < n->Pri)
            {
            Insert(l,n,sn->Pred);
            return;
            }

    AddTail(l,n);
}

