
#define AROS_ALMOST_COMPATIBLE

#include <stdio.h>
#include <exec/lists.h>
#include <clib/exec_protos.h>

void PrintList (struct List * list)
{
    struct Node * node;

    assert (list);

    printf ("(struct List *)%p = { lh_Head=%p, lh_Tail=%p,\n"
	"lh_TailPred=%p }\n"
	, list
	, list->lh_Head
	, list->lh_Tail
	, list->lh_TailPred
	);

    for (node=GetHead(list); node; node=GetSucc(node))
    {
	assert (node);

	printf ("(struct Node *)%p = { ln_Succ=%p, ln_Pred=%p }\n"
	    , node
	    , node->ln_Succ
	    , node->ln_Pred
	    );
    }
}

int main (int argc, char ** argv)
{
    struct List list;
    struct Node nodes[5], * node;
    char names[5][10];
    int t;
    int error = 0;

    printf ("Test for exec-lists\n"
	"The correct addresses are:\n"
	"list=%p, nodes[0]=%p, nodes[1]=%p, nodes[2]=%p,\n"
	"nodes[3]=%p, nodes[4]=%p\n"
	, &list
	, &nodes[0]
	, &nodes[1]
	, &nodes[2]
	, &nodes[3]
	, &nodes[4]
	);

    /* Init list */
    NewList (&list);

    /* Print empty list */
    PrintList (&list);

    /* Insert some nodes */
    /* Test AddHead */
    Insert (&list, &nodes[2], NULL);

    /* Test AddHead with some other node already in the list */
    Insert (&list, &nodes[0], NULL);

    /* Test AddTail */
    Insert (&list, &nodes[4], &nodes[2]);

    /* Test Insert 2nd Node */
    Insert (&list, &nodes[1], &nodes[0]);

    /* Test Insert 2nd last Node */
    Insert (&list, &nodes[3], &nodes[2]);

    /* Print list with all 5 nodes */
    PrintList (&list);

    /* Check list */
    for (node=GetHead(&list),t=0; node; (node=GetSucc(node)),t++)
    {
	if (node != &nodes[t])
	{
	    error ++;
	    printf ("Insert: Node %d is wrong (Is: %p, Should: %p)\n"
		, t
		, node
		, &nodes[t]
		);
	}
    }

    /* Init list again */
    NewList (&list);

    /* Give nodes the pri 20, 10, 0, -10, -20 */
    for (t=0; t<5; t++)
    {
	nodes[t].ln_Pri = -20 + 10*t;
    }

    /* Put nodes in the list */
    Enqueue (&list, &nodes[2]); /* 0 */
    Enqueue (&list, &nodes[1]); /* -10 */
    Enqueue (&list, &nodes[4]); /* 20 */
    Enqueue (&list, &nodes[0]); /* -20 */
    Enqueue (&list, &nodes[3]); /* 10 */

    /* Check list */
    for (node=GetHead(&list),t=0; node; (node=GetSucc(node)),t++)
    {
	if (node != &nodes[t])
	{
	    error ++;
	    printf ("Enqueue: Node %d is wrong (Is: %p, Should: %p, Pri=%d)\n"
		, t
		, node
		, &nodes[t]
		, node->ln_Pri
		);
	}
    }

    /* Give nodes names */
    for (t=4; t>=0; t--)
    {
	sprintf (names[t], "node %d", t);
	nodes[t].ln_Name = names[t];
    }

    node = FindName (&list, "node 0");

    if (node != &nodes[0])
    {
	error ++;
	printf ("FindName: Node 0 is wrong (Is: %p, Should: %p)\n"
	    , node
	    , &nodes[0]
	    );
    }

    node = FindName (&list, "node 3");

    if (node != &nodes[3])
    {
	error ++;
	printf ("FindName: Node 3 is wrong (Is: %p, Should: %p)\n"
	    , node
	    , &nodes[3]
	    );
    }

    node = FindName (&list, "node 4");

    if (node != &nodes[4])
    {
	error ++;
	printf ("FindName: Node 4 is wrong (Is: %p, Should: %p)\n"
	    , node
	    , &nodes[4]
	    );
    }

    node = RemHead (&list);

    if (node != &nodes[0])
    {
	error ++;
	printf ("RemHead: Node 0 is wrong (Is: %p, Should: %p)\n"
	    , node
	    , &nodes[0]
	    );
    }

    AddHead (&list, node);

    if (node != GetHead(&list))
    {
	error ++;
	printf ("AddHead: Node 0 is wrong (Is: %p, Should: %p)\n"
	    , node
	    , &nodes[0]
	    );
    }

    node = RemTail (&list);

    if (node != &nodes[4])
    {
	error ++;
	printf ("RemTail: Node 4 is wrong (Is: %p, Should: %p)\n"
	    , node
	    , &nodes[4]
	    );
    }

    AddTail (&list, node);

    if (node != GetTail(&list))
    {
	error ++;
	printf ("AddTail: Node 4 is wrong (Is: %p, Should: %p)\n"
	    , node
	    , &nodes[4]
	    );
    }

    /* Remove */
    Remove (&nodes[0]);
    node = GetHead (&list);

    if (node != &nodes[1])
    {
	error ++;
	printf ("Remove &[0] is wrong (Is: %p, Should: %p)\n"
	    , node
	    , &nodes[1]
	    );
    }

    Remove (&nodes[4]);
    node = GetTail (&list);

    if (node != &nodes[3])
    {
	error ++;
	printf ("Remove &[4] is wrong (Is: %p, Should: %p)\n"
	    , node
	    , &nodes[3]
	    );
    }

    Remove (&nodes[2]);
    node = GetHead (&list);

    if (node != &nodes[1])
    {
	error ++;
	printf ("Remove &[2] (1) is wrong (Is: %p, Should: %p)\n"
	    , node
	    , &nodes[1]
	    );
    }

    node = GetTail (&list);

    if (node != &nodes[3])
    {
	error ++;
	printf ("Remove &[2] (3) is wrong (Is: %p, Should: %p)\n"
	    , node
	    , &nodes[3]
	    );
    }

    if (error)
	printf ("Tests yielded %d errors\n", error);
    else
	printf ("No errors\n");
}
